類似微信中說話功能的錄音處理C#代碼

n342 9年前發布 | 1K 次閱讀 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;
}

}

</pre>

 本文由用戶 n342 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!