1. 程式人生 > >Android音訊錄製、播放,這一篇就夠了

Android音訊錄製、播放,這一篇就夠了

github原始碼下載地址:https://github.com/geduo83/AudioRecorder

csdn原始碼下載地址:https://download.csdn.net/download/geduo_83/10841496

音訊錄製、播放

最近在專案要用到錄音的功能,研究了幾天,看了很多的資料,今天在這裡分享記錄一下以便回頭檢視。Android給我們提供了兩個錄音的API介面:MediaRecord、AudioRecoder

MediaRecord:

1. 優點:

  • 可以錄製音訊、視訊
  • 提供了錄製、壓縮、編碼等功能
  • 使用簡單方便,幾行程式碼就可實現

2. 缺點:

  • 可以錄製的視訊格式較少
  • 錄製的過程中不能暫停
  • 不能實時處理音訊資料(實時對講的話用它就不適合了)

3. 注意:

  • 模擬器不支援音訊、視訊錄製,只能在真機上測試
  • 錄製一定開啟錄製許可權 <uses-permission android:name="android.permission.RECORD_AUDIO" />
  • Android 9(API級別28)或更高,應用程式在後臺執行不能訪問麥克風

4.使用:

初始化

 public SuperMediaManager(Context context) {
        mMediaRecorder = new MediaRecorder();
        //設定音訊的來源
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        //設定音訊的輸出格式
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//設定輸出檔案的格式
        //設定音訊檔案的編碼
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//設定音訊檔案的編碼

        mMediaPlayer = new MediaPlayer();
    }

開始錄製

public void startRecord(String filepath) {
        Log.v(TAG, "startRecord startRecord");
        Log.v(TAG, "file path:" + filepath);
        //如果正在錄製,就返回了
        if(isRecording){
            return;
        }
        mMediaRecorder.setOutputFile(filepath);
        try {
            //錄製前準備工作
            mMediaRecorder.prepare();
            //開始錄製
            mMediaRecorder.start();

            isRecording = true;
            Log.v(TAG, "startRecord record succ...");
        } catch (Exception e) {
            Log.v(TAG, "startRecord record fail:" + e.toString());
        }
}

停止錄製

public void stopRecord() {
        if (mMediaRecorder != null && isRecording) {
            //停止錄製
            mMediaRecorder.stop();
            //重新開始
            mMediaRecorder.reset();//注意:可以通過返回setAudioSource()步驟來重用該物件
            //mMediaRecorder.release();注意:這個物件不能再次被使用,如果此次再次錄製,就會報錯
            isRecording = false;
        }
    }

錄製監聽

  • 錄製錯誤監聽:MediaRecorder.OnErrorListener
onError(MediaRecorder mr, int what, int extra)

MEDIA_RECORDER_ERROR_UNKNOWN:未知錯誤 MEDIA_ERROR_SERVER_DIED:媒體服務卡死,在這種情況下,應用程式必須釋放MediaRecorder物件並例項化一個新物件

  • 錄製警告資訊監聽:MediaRecorder.OnInfoListener
onInfo(MediaRecorder mr, int what, int extra)	

MediaRecorder.MEDIA_RECORDER_INFO_UNKNOWN:未知的錯誤
MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED:錄製超時了 MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:錄製檔案超過指定大小了,需要setNextOutputFile(File)指定一個新的檔案進行儲存

播放

public void play(String filepath) {
        try {
            //如果正在播放,然後在播放其他檔案就直接崩潰了
            if(mMediaPlayer.isPlaying()){
                return;
            }
            //設定資料來源
            mMediaPlayer.setDataSource(filepath);
            //這個準備工作必須要做
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    //播放完畢再重置一下狀態,下次播放可以再次使用
                    mp.reset();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

錄製狀態圖:

AudioRecoder:

優點:

  • 專業的音訊錄製API,支援實時錄製、支援暫停等,以流的形式進行錄製和播放的操作

缺點:

  • 錄製格式為pcm,在播放器不能直接播放,需要編碼和壓縮

使用

初始化

 public SuperMediaManager(Context context) {
        mMediaRecorder = new MediaRecorder();
        //設定音訊的來源
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        //設定音訊的輸出格式
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);//設定輸出檔案的格式
        //設定音訊檔案的編碼
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);//設定音訊檔案的編碼

        mMediaPlayer = new MediaPlayer();
    }

開始錄製

 public void startRecord(String filepath) {
        Log.v(TAG, "startRecord startRecord");
        Log.v(TAG, "file path:" + filepath);
        //如果正在錄製,就返回了
        if(isRecording){
            return;
        }
        mMediaRecorder.setOutputFile(filepath);
        try {
            //錄製前準備工作
            mMediaRecorder.prepare();
            //開始錄製
            mMediaRecorder.start();

            isRecording = true;
            Log.v(TAG, "startRecord record succ...");
        } catch (Exception e) {
            Log.v(TAG, "startRecord record fail:" + e.toString());
        }
    }

停止錄製

public void stopRecord() {
        if (mMediaRecorder != null && isRecording) {
            //停止錄製
            mMediaRecorder.stop();
            //重新開始
            mMediaRecorder.reset();//注意:可以通過返回setAudioSource()步驟來重用該物件
            //mMediaRecorder.release();注意:這個物件不能再次被使用,如果此次再次錄製,就會報錯
            isRecording = false;
        }
    }

播放

public void play(String filepath) {
        try {
            //如果正在播放,然後在播放其他檔案就直接崩潰了
            if(mMediaPlayer.isPlaying()){
                return;
            }
            //設定資料來源
            mMediaPlayer.setDataSource(filepath);
            //這個準備工作必須要做
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    //播放完畢再重置一下狀態,下次播放可以再次使用
                    mp.reset();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

問題反饋

在使用中有任何問題,歡迎反饋給我,可以用以下聯絡方式跟我交流

關於作者

  var geduo_83 = {
    nickName  : "geduo_83",
    site : "http://www.weibo.com/geduo83"
  }

歡迎打賞哦~~~