返回顶部

收藏

类似微信中说话功能的录音处理C#代码

更多
package com.example.testaudio;

import java.io.File;

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity {

    private MediaRecorder recoder = null;
    private MediaPlayer player = null;
    private String theMediaPath;

    TextView tv = null;
    TextView tvRecord = null;
    Button testBtn = null;
    Button testBtn2 = null;
    Button stopBtn = null;
    Button playBtn = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.textView1);
        tvRecord = (TextView)findViewById(R.id.tvRecord);
        testBtn = (Button)findViewById(R.id.button1);
        testBtn2 = (Button)findViewById(R.id.button2);
        stopBtn = (Button)findViewById(R.id.buttonStop);
        playBtn = (Button)findViewById(R.id.buttonPlay);

        testBtn2.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.i("testactivity", "setOnTouchListener:"+event.getAction());
                switch(event.getAction()) {
                    case MotionEvent.ACTION_UP: {
                        Log.i("testactivity", "停止录音");
                        stopRecording();
                        break;
                    }
                    case MotionEvent.ACTION_DOWN: {
                        Log.i("testactivity", "开始录音");
                        startRecording();
                        break;
                    }
                    default: break;
                }
                return false;
            }
        });

        testBtn.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                startRecording();
                testBtn.setEnabled(false);
                stopBtn.setEnabled(true);
            }
        });

        stopBtn.setEnabled(false);

        stopBtn.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                stopRecording();
                testBtn.setEnabled(true);
                playBtn.setEnabled(true);
                stopBtn.setEnabled(false);
            }
        });

        playBtn.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                playRecordFile(theMediaPath);
                stopBtn.setEnabled(true);
            }
        });
    }

    protected void playRecordFile(String _file) {
        try {
            File f = new File(_file);
            if(!f.exists()) {
                tv.setText("文件不存在:" + _file);
                return;
            }
        } catch(Exception e) {
            Log.i("testactivity", e.getMessage());
        }
        try {
            player = new MediaPlayer();
            player.setDataSource(_file);
            player.prepare();
            player.setOnCompletionListener(new OnCompletionListener() {
                public void onCompletion(MediaPlayer arg0) {
                    tv.setText("播放完毕");
                    stopBtn.setEnabled(false);
                }
            });

            player.start();
        } catch(Exception e) {
            Log.e("testactivity", "play failed:" + e.getMessage());
        }
    }

    /**
     * 停止录音处理
     */
    protected void stopRecording() {

        if(recoder != null) {
            Log.i("testactivity", "停止录音");
            recoder.stop();
            recoder.release();
            recoder = null;
            endtime = System.currentTimeMillis();
            _handleRecordComplete();
        }
        if(player != null) {
            Log.i("testactivity", "停止播放");
            player.stop();
            player.release();
            player = null;
        }
    }

    /**
     * 开始录音处理
     */
    protected void startRecording() {

        theMediaPath = Environment.getExternalStorageDirectory().getAbsolutePath();
        theMediaPath += "/audiotest.3gp";

        recoder = new MediaRecorder();
        recoder.setAudioSource(MediaRecorder.AudioSource.MIC);
        recoder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        recoder.setOutputFile(theMediaPath);
        recoder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

        starttime = System.currentTimeMillis();
        updateMicStatus();

        try {
            recoder.prepare();
            recoder.start();
            _handleRecordStart();
        } catch (Exception e) {
            Log.e("testactivity", "prepared failed:" + e.getMessage());
            _handleRecordStartError(e);
        }

    }

    //定时器
    private static long maxtime = 30*1000; //30秒
    private long starttime = 0l;
    private long endtime = 0l;
    private final Handler mHandler = new Handler();  
    private Runnable mUpdateMicStatusTimer = new Runnable() {  
        public void run() {  
            //判断是否超时
            if(starttime > 0 && System.currentTimeMillis() - starttime > maxtime) {
                Log.e("testactivity", "超时的录音时间,直接停止");
                stopRecording();
                return;
            }

            //更新分贝状态
            updateMicStatus();  
        }  
    };  

    /** 
     * 更新话筒状态 分贝是也就是相对响度 分贝的计算公式K=20lg(Vo/Vi) Vo当前振幅值 Vi基准值为600:我是怎么制定基准值的呢? 当20 
     * * Math.log10(mMediaRecorder.getMaxAmplitude() / Vi)==0的时候vi就是我所需要的基准值 
     * 当我不对着麦克风说任何话的时候,测试获得的mMediaRecorder.getMaxAmplitude()值即为基准值。 
     * Log.i("mic_", "麦克风的基准值:" + mMediaRecorder.getMaxAmplitude());前提时不对麦克风说任何话 
     */
    private int BASE = 600;  
    private int SPACE = 300;// 间隔取样时间 

    private void updateMicStatus() {  
        if (recoder != null) {  
            // int vuSize = 10 * mMediaRecorder.getMaxAmplitude() / 32768;  
            int ratio = recoder.getMaxAmplitude() / BASE;  
            int db = 0;// 分贝  
            if (ratio > 1)  
                db = (int) (20 * Math.log10(ratio));  

            _handleRecordVoice(db);

            mHandler.postDelayed(mUpdateMicStatusTimer, SPACE);  
            /* 
             * if (db > 1) { vuSize = (int) (20 * Math.log10(db)); Log.i("mic_", 
             * "麦克风的音量的大小:" + vuSize); } else Log.i("mic_", "麦克风的音量的大小:" + 0); 
             */
        }  
    } 

    private void _handleRecordStart() {
        //开始录音的接收函数
        tv.setText("开始录音...");
        //starttime 开始时间
    }

    private void _handleRecordStartError(Exception e) {
        //开始录音的接收函数失败
        tv.setText("开始录音失败:" + e.getMessage());
    }

    private void _handleRecordComplete() {
        //结束录音
        tv.setText("停止录音:" + theMediaPath);
    }

    private void _handleRecordVoice(int _db) {
        //声音事件侦听,转换成分贝
        tvRecord.setText(""+_db);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

标签:c#

收藏

0人收藏

支持

0

反对

0

发表评论