国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現語音數據實時采集、播放

2019-12-12 04:23:31
字體:
來源:轉載
供稿:網友

最近做的項目是和語音實時采集并發送,對方實時接收并播放相關,下面記錄下實現的核心代碼。
很多Android開發者應該知道android有個MediaRecorder對象和MediaPlayer對象,用于錄制和播放音頻。這個弊端在于他們不能實時采集并發送出去,所以,我們只能使用AudioRecord和AudioTrack來實現。
記得申明權限:

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><uses-permission android:name="android.permission.RECORD_AUDIO" >

一、AudioRecord實現核心代碼介紹如下:

1、先申明相關錄制配置參數

private AudioRecord audioRecord;// 錄音對象private int frequence = 8000;// 采樣率 8000private int channelInConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// 定義采樣通道private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;// 定義音頻編碼(16位)private byte[] buffer = null;// 錄制的緩沖數組

2、在開始錄制前,我們需要初始化AudioRecord類。

// 根據定義好的幾個配置,來獲取合適的緩沖大小// int bufferSize = 800;int bufferSize = AudioRecord.getMinBufferSize(frequence,    channelInConfig, audioEncoding);// 實例化AudioRecordaudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,    frequence, channelInConfig, audioEncoding, bufferSize);// 定義緩沖數組buffer = new byte[bufferSize];

3、準備開始錄制,使用循環不斷讀取數據。

audioRecord.startRecording();// 開始錄制isRecording = true;// 設置錄制標記為true// 開始錄制while (isRecording) {// 錄制的內容放置到了buffer中,result代表存儲長度int result = audioRecord.read(buffer, 0, buffer.length);/*.....result為buffer中錄制數據的長度(貌似基本上都是640)。剩下就是處理buffer了,是發送出去還是直接播放,這個隨便你。*/}//錄制循環結束后,記得關閉錄制!!if (audioRecord != null) {  audioRecord.stop();}

二、AudioTrack代碼實現介紹如下:

1、聲明播放相關配置。

private AudioTrack track = null;// 錄音文件播放對象private int frequence = 8000;// 采樣率 8000private int channelInConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;// 定義采樣通道private int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;// 定義音頻編碼(16位)private int bufferSize = -1;// 播放緩沖大小

2、初始化AudioTrack對象(初始化一次,該對象可重復使用)

// 獲取緩沖 大小bufferSize = AudioTrack.getMinBufferSize(frequence, channelInConfig,    audioEncoding);// 實例AudioTracktrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequence,    channelInConfig, audioEncoding, bufferSize,    AudioTrack.MODE_STREAM);

3、使用AudioTrack播放語音數據。

//將語音數據寫入即可。track.write(dataArray, buffer, len);

問題一:

由于目前的項目是實時采集,實時發送,所以需要考慮到包的大小,經測試,我們使用160個byte作為一個包傳遞可以做到比較良好的播放效果(也就是將一份buffer拆分成四個發送)。處理代碼如下:

// 將數據通過監聽接口回調出去if (audioRecordingCallback != null) {  int offset = result % MAX_DATA_LENGTH > 0 ? 1 : 0;  //將一個buffer拆分成幾份小數據包 MAX_DATA_LENGTH 為包的最大byte數  for (int i = 0; i < result / MAX_DATA_LENGTH + offset; i++) {    int length = MAX_DATA_LENGTH;    if ((i + 1) * MAX_DATA_LENGTH > result) {      length = result - i * MAX_DATA_LENGTH;    }  //寫到回調接口  audioRecordingCallback.onRecording(buffer, i      * MAX_DATA_LENGTH, length);  }}

問題二:

有時候傳輸的過來播放聲音會一卡一卡的,為了解決這樣的問題,暫時使用了語音雙緩沖機制來解決,問題優化很明顯。代碼和示意圖如下:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 麻栗坡县| 昌平区| 肥乡县| 龙泉市| 亚东县| 那坡县| 墨竹工卡县| 东丰县| 河源市| 高安市| 昌都县| 元朗区| 禄劝| 克拉玛依市| 尚志市| 都匀市| 惠水县| 湖州市| 富裕县| 武宣县| 抚宁县| 榕江县| 清苑县| 哈巴河县| 灵台县| 阳新县| 宜宾县| 玉树县| 定西市| 阿荣旗| 平顺县| 铁岭县| 宝山区| 巴南区| 宜丰县| 芒康县| 玉屏| 扬州市| 梅州市| 巴林右旗| 凤台县|