Android 音頻採集——MediaRecord(編碼後錄影文件) 、AudioRecord(PCM原始數據)

http://blog.csdn.net/java_android_c/article/details/52619737html

Android 音頻簡介java

常見的音頻編解碼的類型:AAC  OPUS MP3  AMR  Ogg  PCM  android

AAC: 高級音頻編碼  對應  .m4a(audio/m4a)或者.3pg(audio/3gpp)文件   HEAAC:高級AAC,使用的比較多。網絡

OPUS:有損聲音編碼的格式,由互聯網工程任務組(IETF)進來開發,適用於網絡上的實時聲音傳輸,如:語音通話ide

MP3: 使用的最普遍的音頻編解碼器  對應 .mp3(audio/mp3) 各類音樂網站通常用這種。佈局

AMR:自適應多速率音頻編解碼器,通常用於語音呼叫程序。網站

Ogg:開發的無專利的音頻編解碼器,其質量可與商業的和手專利保護的MP3以及AAC編解碼相媲美。this

PCM :原始音頻,在android平臺上由audio record直接錄用下來的,未通過編碼的。編碼

視頻直播,語音通話中通常使用AAC或者OPUS ,若是對聲音要進行處理就須要使用PCM原始音頻加工處理,而後再進行編碼.url

 

Android音頻採集(捕獲)

android平臺上的音頻採集通常就三種:1.利用android內置的應用程序   2.使用MediaRecorder進行音頻捕獲   3.使用AudioRecord進行音頻捕獲。此3種方式的靈活性逐漸增大,相應的所須要作的工做也逐漸增多。

1、Android 內置的應用程序。

[java]  view plain  copy
 
  1. Intent intent=new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);  
  2. startActivityForResult(intent,0); //經過startActivityForResult獲取音頻錄製的結果的路徑  

這種方式靈活度最差,通常就是作着演示下,開發中基本不用這種方案。

 

2、使用MediaRecorder進行音頻的捕獲。  這個是 錄影視頻和音頻分別編碼後保存成一個文件,單獨音頻也能夠,不過是編碼後的數據

這種方案相較於調用系統內置的用用程序,靈活度要高不少,便於開發者在UI界面上佈局,並且系統封裝的很好,便於使用,惟一的缺點是使用它錄下來的音頻是通過編碼的,沒有辦法的獲得原始的音頻。同時MediaRecorder便可用於音頻的捕獲也能夠用於視頻的捕獲至關的強大。實際開發中沒有特殊需求的話,用的是比較多的!

使用步驟:

建立MediaRecorder對象,調用以下方法(Ps:調用順序順序對結果的影響是很是的大。)

MediaRecorder recorder=new MediaRecorder();//建立MediaRecoder對象

1.recorder.setAudioSource(MediaRecorder.AudioSource.MIC); //調用setAudioSource方法 (調用的第一個方法) 

   MediaRecorder.AudioSource.CAMCORDER和MediaRecorder.AudioSource.VOICE_RECOGNITION當設備具備。>=2個麥克風的時候就可使用它們。

   MediaRecorder.AudioSource.VOICE_CALL從電話中錄音
2.recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);//setOutputFormat方法(調用的第二個方法)
   MediaRecorder.OutputFormat.THREE_GPP 輸出文件將是一個擴展名爲(.3gp)的文件。它可能包含音頻和視頻。
   MediaRecorder.OutputFormat.MPEG_4 輸出一個MPEG_4文件,它可能包含音頻和視頻。
3.recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); //setAudioEncoder方法 (這是調用的第三個方法)
4.recorder.setOutputFile(url); //setOutputFile方法 url是目標文件路徑(這是調用的第四個方法)
以上四個方法一次調用完成以後,就能夠像MediaPlayer同樣控制錄製和暫停錄製了。

 

[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:background="#fff"  
  7.     android:gravity="center">  
  8.   
  9.     <Button   
  10.         android:text="開始錄音"   
  11.         android:id="@+id/StartRecording"   
  12.         android:layout_width="wrap_content"   
  13.         android:layout_height="wrap_content"/>  
  14.      
  15.     <Button   
  16.         android:text="中止錄音"   
  17.         android:id="@+id/StopRecording"   
  18.         android:layout_width="wrap_content"   
  19.         android:layout_height="wrap_content"/>  
  20.       
  21. </LinearLayout>  

 

[java]  view plain  copy
 
  1. public class MainActivity extends Activity implements OnClickListener{  
  2.      
  3.     Button startRecording, stopRecording;//開始錄音、中止錄音、釋放資源  
  4.     MediaRecorder recorder;  
  5.     File audioFile; //錄音保存的文件  
  6.     boolean isRecoding=false;// true 表示正在錄音  
  7.   
  8.     @Override  
  9.     public void onCreate(Bundle savedInstanceState) {  
  10.         super.onCreate(savedInstanceState);  
  11.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  12.         setContentView(R.layout.main);  
  13.         init();  
  14.         initListener();  
  15.     }  
  16.       
  17.     //初始化  
  18.     public void init(){  
  19.         stopRecording = (Button) this.findViewById(R.id.StopRecording);  
  20.         startRecording = (Button) this.findViewById(R.id.StartRecording);  
  21.           
  22.         recorder = new MediaRecorder();  
  23.         recorder.setAudioSource(MediaRecorder.AudioSource.MIC);//設置播放源 麥克風  
  24.         recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //設置輸入格式 3gp  
  25.         recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //設置編碼 AMR  
  26.     }  
  27.       
  28.     //設置監聽器  
  29.     public void initListener(){  
  30.         startRecording.setOnClickListener(this);  
  31.         stopRecording.setOnClickListener(this);  
  32.     }  
  33.          
  34.     //錄音      
  35.     public void recod(){      
  36.               
  37.             //此處還應該對手機進行下判斷,判斷下手機裏面有沒有內存卡  
  38.             //保存在SD卡下MediaRecorderTest文件夾中  
  39.             File path = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/MediaRecorderTest");   
  40.             if(!path.exists())  
  41.             {  
  42.                 path.mkdirs();  
  43.             }  
  44.               
  45.             try {  
  46.                 audioFile=new File(path,"test.3gp");  
  47.                 if(audioFile.exists())  
  48.                 {  
  49.                     audioFile.delete();  
  50.                 }  
  51.                 audioFile.createNewFile();//建立文件  
  52.                   
  53.                } catch (Exception e) {  
  54.                 throw new RuntimeException("Couldn't create recording audio file", e);  
  55.             }  
  56.   
  57.             recorder.setOutputFile(audioFile.getAbsolutePath()); //設置輸出文件  
  58.   
  59.             try {  
  60.                 recorder.prepare();  
  61.             } catch (IllegalStateException e) {  
  62.                 throw new RuntimeException("IllegalStateException on MediaRecorder.prepare", e);  
  63.             } catch (IOException e) {  
  64.                 throw new RuntimeException("IOException on MediaRecorder.prepare", e);  
  65.             }  
  66.             isRecoding=true;  
  67.             recorder.start();  
  68.     }  
  69.       
  70.       
  71.     public void onClick(View v) {  
  72.           
  73.         switch (v.getId())  
  74.         {     
  75.             //開始錄音  
  76.             case R.id.StartRecording:  
  77.             {    
  78.                 Toast.makeText(MainActivity.this,"開始錄音",Toast.LENGTH_SHORT).show();  
  79.                 recod();  
  80.                 break;  
  81.             }  
  82.               
  83.             //中止錄音  
  84.             case R.id.StopRecording:  
  85.             {     
  86.                 if(isRecoding)  
  87.                 {  
  88.                  Toast.makeText(MainActivity.this,"中止錄音",Toast.LENGTH_SHORT).show();  
  89.                  recorder.stop();  
  90.                  recorder.release();  
  91.                 }  
  92.                 break;  
  93.             }  
  94.               
  95.            default:  
  96.               break;  
  97.         }  
  98.     }  
  99.       
  100. }  
[java]  view plain  copy
 
  1. MediaRecoder的其餘API方法:  
  2. //設置錄製容許的最大時長 單位是毫秒。必須在setOutFormat方法以後,prepare方法以前使用。  
  3. setMaxDuration(int);  
  4. //設置文件錄製的存放文件的最大值,單位是字節 。必須在setOutFormat方法以後,prepare方法以前使用。   
  5. setMaxFileSize(long)  
  6. //容許錄製的音頻通道數,一般是一個通道(單聲道,2個通道雙聲道,立體聲)。必須在調用prepare方法以前調用。  
  7. setAudioChannels(int)  
  8. //容許制定捕獲和編碼音頻的採樣率。硬件和使用的編碼器將會決定合適的採樣率。必須在調用prepare方法以前調用。  
  9. setAudioSamplingRate(int)  
  10. //容許指定當壓縮音頻時編碼器所使用的每秒位數(位/秒)。必須在調用prepare方法以前調用。  
  11. setAudioEncodingBitRate在(int)  

 

 

3、使用AudioRecord 進行音頻捕獲。——從某個輸入,直接捕獲音頻數據:PCM格式

這種方法是3種之中最爲靈活的,能讓開發者最大限度的處理採集的音頻,同時它捕獲到的音頻是原始音頻PCM格式的!像作變聲處理的須要就必需要用它收集音頻。在實際開發中,它也是最經常使用來採集音頻的手段。也是本文介紹的重點。

 

[java]  view plain  copy
 
  1. //指定音頻源 這個和MediaRecorder是相同的   
  2. int audioSource=MediaRecorder.AudioSource.MIC;  
  3. //指定採樣率 (MediaRecoder 的採樣率一般是8000Hz CD的一般是44100Hz 不一樣的Android手機硬件將可以以不一樣的採樣率進行採樣。其中11025是一個常見的採樣率)  
  4. int sampleRateInHz=11025 ;  
  5. //指定捕獲音頻的通道數目。在AudioFormat類中指定用於此的常量    
  6. int channelConfig=AudioFormat.CHANNEL_CONFIGURATION_MONO;  
  7. //指定音頻量化位數 ,在AudioFormaat類中指定了如下各類可能的常量。一般咱們選擇ENCODING_PCM_16BIT和ENCODING_PCM_8BIT PCM表明的是脈衝編碼調製,它其實是原始音頻樣本。  
  8. //所以能夠設置每一個樣本的分辨率爲16位或者8位,16位將佔用更多的空間和處理能力,表示的音頻也更加接近真實。  
  9. int audioFormat=AudioFormat.ENCODING_PCM_16BIT;  
  10. 指定緩衝區大小。調用AudioRecord類的getMinBufferSize方法能夠得到。  
  11. //建立AudioRecord。AudioRecord類實際上不會保存捕獲的音頻,所以須要手動建立文件並保存下載。  
  12. AudioRecord record=new AudioRecord(audioSource,sampleRateInHz,channelConfig,audioFormat,bufferSizeInBytes);   

 

佈局xml文件和MediaRecorder Demo中同樣,2個按鈕而已!就不貼了,下面貼出AudioRecord的Demo的源代碼.

 

[java]  view plain  copy
 
  1. public class MainActivity extends Activity implements OnClickListener {  
  2.     Button startRecordingButton, stopRecordingButton;//開始錄音、中止錄音  
  3.     File recordingFile;//儲存AudioRecord錄下來的文件  
  4.     boolean isRecording = false; //true表示正在錄音  
  5.     AudioRecord audioRecord=null;  
  6.     File parent=null;//文件目錄  
  7.     int bufferSize=0;//最小緩衝區大小  
  8.     int sampleRateInHz = 11025;//採樣率  
  9.     int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; //單聲道  
  10.     int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //量化位數  
  11.     String TAG="AudioRecord";  
  12.   
  13.     @Override  
  14.     public void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  17.         setContentView(R.layout.main);  
  18.         init();  
  19.         initListener();  
  20.     }  
  21.       
  22.     //初始化  
  23.     public void init(){  
  24.         startRecordingButton = (Button)findViewById(R.id.StartRecordingButton);  
  25.         stopRecordingButton = (Button)findViewById(R.id.StopRecordingButton);  
  26.           
  27.         bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat);//計算最小緩衝區  
  28.         audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz,channelConfig, audioFormat, bufferSize);//建立AudioRecorder對象  
  29.           
  30.         parent = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+ "/AudiioRecordTest");  
  31.         if(!parent.exists())  
  32.             parent.mkdirs();//建立文件夾  
  33.     }  
  34.       
  35.     //初始化監聽器  
  36.     public void initListener(){  
  37.         startRecordingButton.setOnClickListener(this);  
  38.         stopRecordingButton.setOnClickListener(this);  
  39.     }  
  40.       
  41.     public void onClick(View v) {  
  42.         switch (v.getId()) {  
  43.         //開始錄音  
  44.         case R.id.StartRecordingButton:  
  45.         {  
  46.             record();  
  47.             break;  
  48.         }  
  49.           
  50.         //中止錄音  
  51.         case R.id.StopRecordingButton:  
  52.         {  
  53.             stopRecording();  
  54.             break;  
  55.         }  
  56.     }  
  57.           
  58.  }  
  59.   
  60.     //開始錄音  
  61.     public void record() {  
  62.         isRecording = true;  
  63.         new Thread(new Runnable() {  
  64.             @Override  
  65.             public void run() {  
  66.                 isRecording = true;  
  67.                   
  68.                 recordingFile = new File(parent,"audiotest.pcm");  
  69.                 if(recordingFile.exists()){  
  70.                     recordingFile.delete();  
  71.                 }  
  72.                   
  73.                 try {  
  74.                      recordingFile.createNewFile();  
  75.                     }   
  76.                 catch (IOException e) {  
  77.                      e.printStackTrace();  
  78.                      Log.e(TAG,"建立儲存音頻文件出錯");  
  79.                     }  
  80.                   
  81.                   
  82.                 try {  
  83.                 DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(recordingFile)));  
  84.                 byte[] buffer = new byte[bufferSize];  
  85.                 audioRecord.startRecording();//開始錄音  
  86.                     int r = 0;  
  87.                     while (isRecording) {  
  88.                         int bufferReadResult = audioRecord.read(buffer,0,bufferSize);  
  89.                         for (int i = 0; i < bufferReadResult; i++)   
  90.                         {  
  91.                             dos.write(buffer[i]);   
  92.                         }  
  93.                         r++;  
  94.                     }  
  95.                     audioRecord.stop();//中止錄音  
  96.                     dos.close();  
  97.                 } catch (Throwable t) {  
  98.                     Log.e(TAG, "Recording Failed");  
  99.                 }  
  100.                   
  101.             }  
  102.         }).start();  
  103.   
  104.     }  
  105.       
  106.     //中止錄音  
  107.     public void stopRecording()   
  108.     {  
  109.         isRecording = false;  
  110.     }  
  111.   
  112.       
  113. }  

 

注意這幾個Demo都要添加如下權限:

[html]  view plain  copy
 
  1. <uses-permission android:name="android.permission.RECORD_AUDIO"/>  
  2. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  

4、備註:

MediaRecorder採集音頻的Demo源碼

AudioRecord採集音頻的Demo源碼

原始音頻PCM播放器   使用方法 : 文件->導入->裸數據   而後根據你錄音時的配置填寫相應參數 就能夠播放了!

相關文章
相關標籤/搜索