Android提供了兩個API用于實現錄音功能:AudioRecord、MediaRecorder。
AudioRecord
????AudioRecord與MediaRecorder一樣用來錄制音頻的。相對于MediaRecorder來說,AudioRecorder 錄音時直接操縱硬件實時獲取音頻流數據,可以對錄制的數據進行實時的處理,比如降噪,除雜,或者將音頻進行實時傳輸,比如IP電話,對講功能等操作。同時也可實現暫停功能。
????AudioRecord通過設置不同的采樣率,采樣位數,聲道數,"拉"取不同的音質流,我們可以查看Android官方的API來查看他的初始化方法。
????因為AudioRecord比MediaRecorder更接近底層,錄制的音頻是PCM格式的,最接近原始聲音的音頻數據。只能用AudioTraker進行播放,或者可以將PCM數據用算法進行壓縮編碼后,轉換成mp3等格式播放。
????AudioRecord的使用還算簡單,沒有太多復雜的方法,下面就是代碼樣例。
// 音頻獲取源
private int audioSource = MediaRecorder.AudioSource.MIC;
// 設置音頻采樣率,44100是目前的標準,但是某些設備仍然支持22050,16000,11025
private static int sampleRateInHz = 44100;
// 設置音頻的錄制的聲道CHANNEL_IN_STEREO為雙聲道,CHANNEL_CONFIGURATION_MONO為單聲道
private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
// 音頻數據格式:PCM 16位每個樣本。保證設備支持。PCM 8位每個樣本。不一定能得到設備支持。
private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
// 緩沖區字節大小
private int bufferSizeInBytes = 0;
private AudioRecord audioRecord;
// 設置正在錄制的狀態
private boolean isRecord = false;
//AudioName裸音頻數據文件
private static final String AudioName = "/sdcard/love.pcm";//不推薦這么寫,可以用Enviroment.
private void creatAudioRecord() {
// 獲得緩沖區字節大小
bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
channelConfig, audioFormat);
// 創建AudioRecord對象
audioRecord = new AudioRecord(audioSource, sampleRateInHz,
channelConfig, audioFormat, bufferSizeInBytes);
}
public void startRecord() {
if (!isRecord) {
// 讓錄制狀態為true
isRecord = true;
//開始錄制
audioRecord.startRecording();
// 開啟音頻文件寫入線程
new Thread(new AudioRecordThread()).start();
}
}
public void stopRecord() {
if (audioRecord != null) {
if (isRecord) {
//停止文件寫入
isRecord = false;
//停止錄制
audioRecord.stop();
//釋放資源
audioRecord.release();
}
}
}
private class AudioRecordThread implements Runnable {
@Override
public void run() {
//往文件中寫入裸數據
writeDateTOFile();
}
}
/**
* 這里將數據寫入文件,但是并不能播放,因為AudioRecord獲得的音頻是原始的裸音頻,
* 如果需要播放就必須加入一些格式或者編碼的頭信息。但是這樣的好處就是你可以對音頻的 裸數據進行處理,比如你要做一個愛說話的TOM
* 貓在這里就進行音頻的處理,然后重新封裝 所以說這樣得到的音頻比較容易做一些音頻的處理。
*/
private void writeDateTOFile() {
// new一個byte數組用來存一些字節數據,大小為緩沖區大小
byte[] audiodata = new byte[bufferSizeInBytes];
FileOutputStream fos = null;
int readsize = 0;
try {
File file = new File(AudioName);
if (file.exists()) {
file.delete();
}
fos = new FileOutputStream(file);// 建立一個可存取字節的文件
} catch (Exception e) {
e.printStackTrace();
}
while (isRecord) {
readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {
try {
fos.write(audiodata);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
fos.close();// 關閉寫入流
} catch (IOException e) {
e.printStackTrace();
}
}
下面是Android所支持的音頻源:
/**默認聲音**/
public static final int DEFAULT = 0;
/**麥克風聲音*/
public static final int MIC = 1;
/**通話上行聲音*/
public static final int VOICE_UPLINK = 2;
/**通話下行聲音*/
public static final int VOICE_DOWNLINK = 3;
/**通話上下行聲音*/
public static final int VOICE_CALL = 4;
/**根據攝像頭轉向選擇麥克風*/
public static final int CAMCORDER = 5;
/**對麥克風聲音進行聲音識別,然后進行錄制*/
public static final int VOICE_RECOGNITION = 6;
/**對麥克風中類似ip通話的交流聲音進行識別,默認會開啟回聲消除和自動增益*/
public static final int VOICE_COMMUNICATION = 7;
/**錄制系統內置聲音*/
public static final int REMOTE_SUBMIX = 8;
MediaRecorder
????MediaRecorder已經集成了錄音、編碼、壓縮等,支持少量的錄音音頻格式。大部分已經集成,直接調用相關接口即可,代碼量小。
????如下面代碼樣例,錄制的m4a文件可以直接播放,并且錄制一分鐘的音頻,只有100KB大小,相對于AudioRecord錄制的原始音頻,1分鐘需要10.34MB的大小,已經被壓縮很多了。
// 音頻獲取源
private int audioSource = MediaRecorder.AudioSource.MIC;
// 設置音頻采樣率,44100是目前的標準,但是某些設備仍然支持22050,16000,11025
private static int sampleRateInHz = 44100;
// 設置音頻的錄制的聲道CHANNEL_IN_STEREO為雙聲道,CHANNEL_CONFIGURATION_MONO為單聲道
private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
// 音頻數據格式:PCM 16位每個樣本。保證設備支持。PCM 8位每個樣本。不一定能得到設備支持。
private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private MediaRecorder mRecorder;
//AudioName裸音頻數據文件
private static final String AudioName = "/sdcard/MRecord.m4a";//不推薦這么寫,可以用Enviroment.
public void startRecord() {
try {
// 創建AudioRecord對象
mRecorder = new MediaRecorder();
// 設置錄音的聲音來源
mRecorder.setAudioSource(audioSource);
// 設置錄制的聲音的輸出格式(必須在設置聲音編碼格式之前設置)
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 設置聲音編碼格式
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
//所有android系統都支持的適中采樣的頻率
mRecorder.setAudioSamplingRate(sampleRateInHz);
File file = new File(AudioName);
if (file.exists()) {
file.delete();
}
mRecorder.setOutputFile(file.getAbsolutePath());
mRecorder.prepare();
// 開始錄音
mRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopRecord() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();//釋放資源
mRecorder = null;
}
}
權限申請
注意:由于該程序需要使用系統的麥克風進行錄音,因此還需要在清單文件AndroidManifest.xml文件中授權相應的權限:
<!-- 授予該程序向外部存儲器寫入數據的權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- 授予該程序錄制聲音的權限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
未完待更新...
上一篇:Android 音視頻之音頻編碼
有問題的地方請大家幫忙指出,謝謝。
持續更新中...