版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、直接給上個詳細的使用Android MediaRecorder進行手機錄音解說代碼:package .chenzheng_java.media;import java.io.IOException;import android.app.Activity;import android.media.MediaRecorder;import android.os.Bundle;public class MediaRecordActivity extends Activity MediaRecorder mediaRecorder ; Override public void onCreate(Bun
2、dle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); mediaRecorder = new MediaRecorder(); record(); /* * 開始錄制 */ private void record() /* * mediaRecorder.setAudioSource設置聲音來源。 * MediaRecorder.AudioSource這個內部類詳細的介紹了聲音來源。 */ mediaRecorder.setAudioSource(MediaRecor
3、der.AudioSource.MIC); /* * mediaRecorder.setOutputFormat代表輸出文件的格式。該語句必須在setAudioSource之后,在prepare之前。 * OutputFormat內部類,定義了音頻輸出的格式,主要包含MPEG_4、THREE_GPP、RAW_AMR等。 */ mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); /* * mediaRecorder.setAddioEncoder()方法可以設置音頻的編碼 * AudioEncoder內部類詳細
4、定義了兩種編碼:AudioEncoder.DEFAULT、AudioEncoder.AMR_NB */ mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); /* * 設置錄音之后,保存音頻文件的位置 */ mediaRecorder.setOutputFile(file:/sdcard/myvido/a.3pg); /* * 調用start開始錄音之前,一定要調用prepare方法。 */ try mediaRecorder.prepare(); mediaRecorder.start(); catch (Ill
5、egalStateException e) e.printStackTrace(); catch (IOException e) e.printStackTrace(); /* * 此外,還有和MediaRecorder有關的幾個參數與方法,我們一起來看一下: * sampleRateInHz :音頻的采樣頻率,每秒鐘能夠采樣的次數,采樣率越高,音質越高。 * 給出的實例是44100、22050、11025但不限于這幾個參數。例如要采集低質量的音頻就可以使用4000、8000等低采樣率 * * channelConfig :聲道設置:android支持雙聲道立體聲和單聲道。MONO單聲道,ST
6、EREO立體聲 * * recorder.stop();停止錄音 * recorder.reset(); 重置錄音 ,會重置到setAudioSource這一步 * recorder.release(); 解除對錄音資源的占用 */android中AudioRecord采集音頻的參數說明在android中采集音頻的api是android.media.AudioRecord類其中構造器的幾個參數就是標準的聲音采集參數以下是參數的含義解釋public AudioRecord (int audioSource, int sampleRateInHz, int channelConfig, int a
7、udioFormat, int bufferSizeInBytes)Since: API Level 3Class constructor.ParametersaudioSourcethe recording source. See MediaRecorder.AudioSource for recording source definitions.音頻源:指的是從哪里采集音頻。這里我們當然是從麥克風采集音頻,所以此參數的值為MICsampleRateInHzthe sample rate expressed in Hertz. Examples of rates are (but not l
8、imited to) 44100, 22050 and 11025.采樣率:音頻的采樣頻率,每秒鐘能夠采樣的次數,采樣率越高,音質越高。給出的實例是44100、22050、11025但不限于這幾個參數。例如要采集低質量的音頻就可以使用4000、8000等低采樣率。channelConfigdescribes the configuration of the audio channels. SeeCHANNEL_IN_MONO and CHANNEL_IN_STEREO聲道設置:android支持雙聲道立體聲和單聲道。MONO單聲道,STEREO立體聲audioFormatthe format
9、in which the audio data is represented. SeeENCODING_PCM_16BIT and ENCODING_PCM_8BIT編碼制式和采樣大?。翰杉瘉淼臄祿斎皇褂肞CM編碼(脈沖代碼調制編碼,即PCM編碼。PCM通過抽樣、量化、編碼三個步驟將連續(xù)變化的模擬信號轉換為數字編碼。) android支持的采樣大小16bit 或者8bit。當然采樣大小越大,那么信息量越多,音質也越高,現在主流的采樣大小都是16bit,在低質量的語音傳輸的時候8bit 足夠了。bufferSizeInBytesthe total size (in bytes) of the
10、buffer where audio data is written to during the recording. New audio data can be read from this buffer in smaller chunks than this size. See getMinBufferSize(int, int, int) to determine the minimum required buffer size for the successful creation of an AudioRecord instance. Using values smaller tha
11、n getMinBufferSize() will result in an initialization failure.采集數據需要的緩沖區(qū)的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。采集到的數據保存在一個byteBuffer中,可以使用流將其讀出。亦可保存成為文件的形式Android 使用AudioRecord錄音相關和音頻文件的封裝分類: Android流媒體學習在Android中錄音可以用MediaRecord錄音,操作比較簡單。但是不夠專業(yè),就是不能對音頻進行處理。如果要進行音頻的實時的處理或者音頻的一些封裝就可以用AudioRecord來進行錄
12、音了。這里給出一段代碼。實現了AudioRecord的錄音和WAV格式音頻的封裝。用AudioTrack和AudioTrack類可以進行邊錄邊播,可以參考:我們這里的代碼沒有播放。但是有封裝和詳解,如下:javaview plaincopy1 package com.ppmeet; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileNotFoundException; 5 import java.io.FileOutputStream; 6 import java.io.IOExcepti
13、on; 7 import android.app.Activity; 8 import android.graphics.PixelFormat; 9 import android.media.AudioFormat; 10 import android.media.AudioRecord; 11 import android.media.MediaRecorder; 12 import android.os.Bundle; 13 import android.view.View; 14 import android.view.View.OnClickListener; 15 import a
14、ndroid.view.Window; 16 import android.view.WindowManager; 17 import android.widget.Button; 18 /*19 * class name:TestAudioRecord20 * class description:用AudioRecord來進行錄音21 * PS: 22 * 23 * version 1.00 2011/09/2124 * author CODYY)peijiangping25 */26 publicclass TestAudioRecord extends Activity 27 / 音頻獲
15、取源28 privateint audioSource = MediaRecorder.AudioSource.MIC; 29 / 設置音頻采樣率,44100是目前的標準,但是某些設備仍然支持22050,16000,1102530 privatestaticint sampleRateInHz = 44100; 31 / 設置音頻的錄制的聲道CHANNEL_IN_STEREO為雙聲道,CHANNEL_CONFIGURATION_MONO為單聲道32 privatestaticint channelConfig = AudioFormat.CHANNEL_IN_STEREO; 33 / 音頻數據
16、格式:PCM 16位每個樣本。保證設備支持。PCM 8位每個樣本。不一定能得到設備支持。34 privatestaticint audioFormat = AudioFormat.ENCODING_PCM_16BIT; 35 / 緩沖區(qū)字節(jié)大小36 privateint bufferSizeInBytes = 0; 37 private Button Start; 38 private Button Stop; 39 private AudioRecord audioRecord; 40 privateboolean isRecord = false;/ 設置正在錄制的狀態(tài)41 /AudioN
17、ame裸音頻數據文件42 privatestaticfinal String AudioName = /sdcard/love.raw; 43 /NewAudioName可播放的音頻文件44 privatestaticfinal String NewAudioName = /sdcard/new.wav; 45 publicvoid onCreate(Bundle savedInstanceState) 46 super.onCreate(savedInstanceState); 47 getWindow().setFormat(PixelFormat.TRANSLUCENT);/ 讓界面橫屏
18、48 requestWindowFeature(Window.FEATURE_NO_TITLE);/ 去掉界面標題49 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 50 WindowManager.LayoutParams.FLAG_FULLSCREEN); 51 / 重新設置界面大小52 setContentView(R.layout.main); 53 init(); 54 55 privatevoid init() 56 Start = (Button) this.findViewById(R.id.s
19、tart); 57 Stop = (Button) this.findViewById(R.id.stop); 58 Start.setOnClickListener(new TestAudioListener(); 59 Stop.setOnClickListener(new TestAudioListener(); 60 creatAudioRecord(); 61 62 privatevoid creatAudioRecord() 63 / 獲得緩沖區(qū)字節(jié)大小64 bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInH
20、z, 65 channelConfig, audioFormat); 66 / 創(chuàng)建AudioRecord對象67 audioRecord = new AudioRecord(audioSource, sampleRateInHz, 68 channelConfig, audioFormat, bufferSizeInBytes); 69 70 class TestAudioListener implements OnClickListener 71 Override72 publicvoid onClick(View v) 73 if (v = Start) 74 startRecord()
21、; 75 76 if (v = Stop) 77 stopRecord(); 78 79 80 81 privatevoid startRecord() 82 audioRecord.startRecording(); 83 / 讓錄制狀態(tài)為true84 isRecord = true; 85 / 開啟音頻文件寫入線程86 new Thread(new AudioRecordThread().start(); 87 88 privatevoid stopRecord() 89 close(); 90 91 privatevoid close() 92 if (audioRecord != nu
22、ll) 93 System.out.println(stopRecord); 94 isRecord = false;/停止文件寫入95 audioRecord.stop(); 96 audioRecord.release();/釋放資源97 audioRecord = null; 98 99 100 class AudioRecordThread implements Runnable 101 Override102 publicvoid run() 103 writeDateTOFile();/往文件中寫入裸數據104 copyWaveFile(AudioName, NewAudioNam
23、e);/給裸數據加上頭文件105 106 107 /*108 * 這里將數據寫入文件,但是并不能播放,因為AudioRecord獲得的音頻是原始的裸音頻,109 * 如果需要播放就必須加入一些格式或者編碼的頭信息。但是這樣的好處就是你可以對音頻的 裸數據進行處理,比如你要做一個愛說話的TOM110 * 貓在這里就進行音頻的處理,然后重新封裝 所以說這樣得到的音頻比較容易做一些音頻的處理。111 */112 privatevoid writeDateTOFile() 113 / new一個byte數組用來存一些字節(jié)數據,大小為緩沖區(qū)大小114 byte audiodata = newbytebu
24、fferSizeInBytes; 115 FileOutputStream fos = null; 116 int readsize = 0; 117 try 118 File file = new File(AudioName); 119 if (file.exists() 120 file.delete(); 121 122 fos = new FileOutputStream(file);/ 建立一個可存取字節(jié)的文件123 catch (Exception e) 124 e.printStackTrace(); 125 126 while (isRecord = true) 127 re
25、adsize = audioRecord.read(audiodata, 0, bufferSizeInBytes); 128 if (AudioRecord.ERROR_INVALID_OPERATION != readsize) 129 try 130 fos.write(audiodata); 131 catch (IOException e) 132 e.printStackTrace(); 133 134 135 136 try 137 fos.close();/ 關閉寫入流138 catch (IOException e) 139 e.printStackTrace(); 140
26、141 142 / 這里得到可播放的音頻文件143 privatevoid copyWaveFile(String inFilename, String outFilename) 144 FileInputStream in = null; 145 FileOutputStream out = null; 146 long totalAudioLen = 0; 147 long totalDataLen = totalAudioLen + 36; 148 long longSampleRate = sampleRateInHz; 149 int channels = 2; 150 long b
27、yteRate = 16 * sampleRateInHz * channels / 8; 151 byte data = newbytebufferSizeInBytes; 152 try 153 in = new FileInputStream(inFilename); 154 out = new FileOutputStream(outFilename); 155 totalAudioLen = in.getChannel().size(); 156 totalDataLen = totalAudioLen + 36; 157 WriteWaveFileHeader(out, total
28、AudioLen, totalDataLen, 158 longSampleRate, channels, byteRate); 159 while (in.read(data) != -1) 160 out.write(data); 161 162 in.close(); 163 out.close(); 164 catch (FileNotFoundException e) 165 e.printStackTrace(); 166 catch (IOException e) 167 e.printStackTrace(); 168 169 170 /*171 * 這里提供一個頭信息。插入這
29、些信息就可以得到可以播放的文件。172 * 為我為啥插入這44個字節(jié),這個還真沒深入研究,不過你隨便打開一個wav173 * 音頻的文件,可以發(fā)現前面的頭文件可以說基本一樣哦。每種格式的文件都有174 * 自己特有的頭文件。175 */176 privatevoid WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, 177 long totalDataLen, long longSampleRate, int channels, long byteRate) 178 throws IOException 179 byte
30、 header = newbyte44; 180 header0 = R; / RIFF/WAVE header181 header1 = I; 182 header2 = F; 183 header3 = F; 184 header4 = (byte) (totalDataLen & 0xff); 185 header5 = (byte) (totalDataLen 8) & 0xff); 186 header6 = (byte) (totalDataLen 16) & 0xff); 187 header7 = (byte) (totalDataLen 24) & 0xff); 188 he
31、ader8 = W; 189 header9 = A; 190 header10 = V; 191 header11 = E; 192 header12 = f; / fmt chunk193 header13 = m; 194 header14 = t; 195 header15 = ; 196 header16 = 16; / 4 bytes: size of fmt chunk197 header17 = 0; 198 header18 = 0; 199 header19 = 0; 200 header20 = 1; / format = 1201 header21 = 0; 202 h
32、eader22 = (byte) channels; 203 header23 = 0; 204 header24 = (byte) (longSampleRate & 0xff); 205 header25 = (byte) (longSampleRate 8) & 0xff); 206 header26 = (byte) (longSampleRate 16) & 0xff); 207 header27 = (byte) (longSampleRate 24) & 0xff); 208 header28 = (byte) (byteRate & 0xff); 209 header29 =
33、(byte) (byteRate 8) & 0xff); 210 header30 = (byte) (byteRate 16) & 0xff); 211 header31 = (byte) (byteRate 24) & 0xff); 212 header32 = (byte) (2 * 16 / 8); / block align213 header33 = 0; 214 header34 = 16; / bits per sample215 header35 = 0; 216 header36 = d; 217 header37 = a; 218 header38 = t; 219 he
34、ader39 = a; 220 header40 = (byte) (totalAudioLen & 0xff); 221 header41 = (byte) (totalAudioLen 8) & 0xff); 222 header42 = (byte) (totalAudioLen 16) & 0xff); 223 header43 = (byte) (totalAudioLen 24) & 0xff); 224 out.write(header, 0, 44); 225 226 Override227 protectedvoid onDestroy() 228 close(); 229
35、super.onDestroy(); 230 231 +Android入門(9)AudioRecord和AudioTrack類的使用(2010-05-07 09:07:05 AudioRecord和AudioTrack類是Android獲取和播放音頻流的重要類,放置在android.media包中。與該包中的MediaRecorder和MediaPlayer類不同,AudioRecord和AudioTrack類在獲取和播放音頻數據流時無需通過文件保存和文件讀取,可以動態(tài)地直接獲取和播放音頻流,在實時處理音頻數據流時非常有用。 當然,如果用戶只想錄音后寫入文件或從文件中取得音頻流進行播放,那么直
36、接使用MediaRecorder和MediaPlayer類是首選方案,因為這兩個類使用非常方便,而且成功率很高。而AudioRecord和AudioTrack類的使用卻比較復雜,我們發(fā)現很多人都不能成功地使用這兩個類,甚至認為Android的這兩個類是不能工作的。 其實,AudioRecord和AudioTrack類的使用雖然比較復雜,但是可以工作,我們不僅可以很好地使用了這兩個類,而且還通過套接字(Socket)實現了音頻數據的網絡傳輸,做到了一端使用AudioRecord獲取音頻流然后通過套接字傳輸出去,而另一端通過套接字接收后使用AudioTrack類播放。 下面是我們對AudioRec
37、ord和AudioTrack類在使用方面的經驗總結: (1)創(chuàng)建AudioRecord和AudioTrack類對象:創(chuàng)建這兩個類的對象比較復雜,通過對文檔的反復和仔細理解,并通過多次失敗的嘗試,并在北理工的某個Android大牛的網上的文章啟發(fā)下,我們也最終成功地創(chuàng)建了這兩個類的對象。創(chuàng)建AudioRecord和AudioTrack類對象的代碼如下:AudioRecord類: m_in_buf_size =AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING
38、_PCM_16BIT); m_in_rec = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, m_in_buf_size) ;AudioTrack類: m_out_buf_size = android.media.AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCOD
39、ING_PCM_16BIT); m_out_trk = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, m_out_buf_size, AudioTrack.MODE_STREAM); (2)關于AudioRecord和AudioTrack類的監(jiān)聽函數,不用也行。 (3)調試方面,包括初始化后看logcat信息,以確定類的工作狀態(tài),初始化是否成功等。 編寫好代碼,沒有語法錯誤,調用模擬器運行、調試代碼時,
40、logcat發(fā)揮了很好的功用。剛調試時,經常會出現模擬器顯示出現異常,這時我們可以在代碼的一些關鍵語句后添加如Log.d(test1,OK);這樣的語句進行標識,出現異常時我們就可以在logcat窗口觀察代碼執(zhí)行到哪里出現異常,然后進行相應的修改、調試。模擬器不會出現異常時,又遇到了錄放音的問題。錄音方面,剛開始選擇將語音編碼數據存放在多個固定大小的文件中進行傳送,但是這種情況下會出現聲音斷續(xù)的現象,而且要反復的建立文件,比較麻煩,后來想到要進行網上傳輸,直接將語音編碼數據以數據流的形式傳送,經過驗證,這種方法可行并且使代碼更加簡潔。放音方面,將接收到的數據流存放在一個數組中,然后將數組中數據
41、寫到AudioTrack中。剛開始只是“嘟”幾聲,經過檢查發(fā)現只是把數據寫一次,加入循環(huán),讓數據反復寫到AudioTrack中,就可以聽到正常的語音了。接下來的工作主要是改善話音質量與話音延遲,在進行通話的過程中,觀察logcat窗口,發(fā)現向數組中寫數據時會出現Bufferflow的情況,于是把重心轉移到數組大小的影響上,經過試驗,發(fā)現 AudioRecord一次會讀640個數據,然后就對錄音和放音中有數組的地方進行實驗修改。AudioRecord和AudioTrack進行實例化時,參數中各有一個數組大小,經過試驗這個數組大小和AudioRecord和AudioTrack能正常實例化所需的最小
42、Buffer大?。瓷厦鎸嵗瘯r的m_in_buf_size和m_out_buf_size參數)相等且服務器方進行緩存數據的數組尺寸是上述數值的2倍時,語音質量最好。由于錄音和放音的速度不一致,受到北理工大牛的啟發(fā),在錄音方面,將存放錄音數據的數組放到LinkedList中,當LinkedList中數組個數達到2(這個也是經過試驗驗證話音質量最好時的數據)時,將先錄好的數組中數據傳送出去。經過上述反復試驗和修改,最終使雙方通話質量較好,且延時較短(大概有2秒鐘)。 (4)通過套接字傳輸和接收數據 數據傳送部分,使用的是套接字。通信雙方,通過不同的端口向服務器發(fā)送請求,與服務器連接上后,開始通話
43、向服務器發(fā)送數據,服務器通過一個套接字接收到一方的數據后,先存在一個數組中,然后將該數組中數據以數據流的形式再通過另一個套接字傳送到另一方。這樣就實現了雙方數據的傳送。 (5)代碼架構 為避免反復錄入和讀取數據占用較多資源,使程序在進行錄放音時不能執(zhí)行其他命令,故將錄音和放音各寫成一個線程類,然后在主程序中,通過MENU控制通話的開始、停止、結束。 最后說明,AudioRecord和AudioTrack類可以用,只是稍微復雜些。以下貼出雙方通信的源碼,希望對大家有所幫助:主程序Daudioclient:package cn.Daudioclient;import android.app.Act
44、ivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;public class Daudioclient extends Activity public static final int MENU_START_ID = Menu.FIRST ; public static final int MENU_STOP_ID = Menu.FIRST + 1 ; public static final int MENU_EXIT_ID = Menu.FIRST + 2 ; protect
45、ed Saudioserver m_player ; protected Saudioclient m_recorder ; Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); public boolean onCreateOptionsMenu(Menu aMenu) boolean res = super.onCreateOptionsMenu(aMenu) ; aMenu.add(0, MENU
46、_START_ID, 0, START) ; aMenu.add(0, MENU_STOP_ID, 0, STOP) ; aMenu.add(0, MENU_EXIT_ID, 0, EXIT) ; return res ; public boolean onOptionsItemSelected(MenuItem aMenuItem) switch (aMenuItem.getItemId() case MENU_START_ID: m_player = new Saudioserver() ; m_recorder = new Saudioclient() ; m_player.init() ; m_recorder.init() ; m_recorder.start() ; m_player.start(
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 項化課程設計
- 二零二五版二零二五年度便利店連鎖經營合同范本4篇
- 二零二五年度園林苗木種植與技術研發(fā)合同4篇
- 二零二五年房屋無證買賣及配套設施移交合同3篇
- 礦山井下爆破施工方案
- 2025年度智慧社區(qū)運營承包協議4篇
- 2025年項目合作商業(yè)機密保密協議范本3篇
- 2025年度綠色生態(tài)大棚蔬菜種植與技術服務全面合作協議3篇
- 2025年度個人財產保險合同范本下載包含意外傷害4篇
- 二零二五年度車輛抵押借款合同(含車輛交易監(jiān)管)4篇
- GB/T 12914-2008紙和紙板抗張強度的測定
- GB/T 1185-2006光學零件表面疵病
- ps6000自動化系統(tǒng)用戶操作及問題處理培訓
- 家庭教養(yǎng)方式問卷(含評分標準)
- 城市軌道交通安全管理課件(完整版)
- 線纜包覆擠塑模設計和原理
- TSG ZF001-2006 安全閥安全技術監(jiān)察規(guī)程
- 部編版二年級語文下冊《蜘蛛開店》
- 鍋爐升降平臺管理
- 200m3╱h凈化水處理站設計方案
- 個體化健康教育記錄表格模板1
評論
0/150
提交評論