1. 程式人生 > >Android音訊採集、壓縮、傳送

Android音訊採集、壓縮、傳送

基本的實現流程:

 1、從手機麥中採集音訊資料;2、將PCM音訊資料編碼壓縮;3、將壓縮好的音訊通過無線網路傳送出去;4、其他手機接收音訊資料並解碼;5、將音訊資料寫入到音軌中播放。專案雖然簡單,但其中的一些小問題也折騰了我不少時間。

  首先我們建立一個執行緒用來採集音訊資料,通過android提供的AudioRecord可以實時採集音訊流。AudioRecord類在Java應用程式中管理音訊資源,用來記錄從平臺音訊輸入裝置產生的資料。其實呼叫AudioRecord很簡單,首先建立AudioRecord物件,AudioRecord會初始化並連線音訊緩衝區,用來緩衝新的音訊資料。根據指定的緩衝區的大小來決定AudioRecord能夠記錄多長的資料。

呼叫getMinBufferSize(int,int,int)返回最小的緩衝區大小。然後根據得到的最小緩衝區大小來建立AudioRecord物件:

複製程式碼
inputMinSize = AudioRecord.getMinBufferSize(8000, 
        AudioFormat.CHANNEL_CONFIGURATION_MONO, 
        AudioFormat.ENCODING_PCM_16BIT);
audioRec = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000, 
        AudioFormat.CHANNEL_CONFIGURATION_MONO,
        AudioFormat.ENCODING_PCM_16BIT, inputMinSize);
複製程式碼
引數
  sampleRateInHz         預設取樣率,單位Hz。
  channelConfig          描述音訊通道設定。
  audioFormat              音訊資料保證支援此格式。

  AudioRecord初始化工作完畢後啟用錄製執行緒,並且呼叫startRecording ()開始進行音訊錄製。呼叫read(short,int,int)方法從音訊硬體錄製緩衝區讀取資料。拿到音訊資料後,直接通過網路傳送出去是不行的,我們在這裡還要做一項工作就是實現音訊壓縮。在網上提供了很多音訊的編碼庫,我們可以將原始碼匯入到專案中通過android ndk編譯成.so檔案,最後通過jni來呼叫。我這裡直接用sipdroid開源專案提供的SILK編解碼庫(

下載編碼庫)。

本地方法 encode(short[] lin,int offset,byte[] encoded,int size)
引數                  
  lin        源資料                  
  offset       源陣列的起始偏移量                  
  encoded     編碼後的資料      
  size          請求編碼的資料大小返回值   編碼後的資料大小

  呼叫encode(short[], int, byte[], int)壓縮已經採集完畢的音訊資料,我們就可以通過網路傳送出去了。 

  接下來,我們建立一個socket udp例項,為什麼這裡選擇udp而不是tcp呢?從我們本身的專案需求出發,我們做的這個專案的通訊方式是相互收發資料的,屬於手機與手機兩“客戶端“之間的通訊。並且,在這種音訊通訊過程中,我們要傳輸的資料量是比較龐大的,因此採用資源消耗少,處理速度快的UDP協議是合理的。指定傳送的埠號,我們將資料封裝成報文傳送出去,整個採集傳送的過程如下:

複製程式碼
class RecordSoundThread extends Thread {
        private boolean flag = true;
        private DatagramSocket mSocket;

        private int inputBufSize = 160;
        short[] inputBytes = new short[1024];
        byte[] encodeBytes = new byte[1024];

        RecordSoundThread() throws SocketException {
            // TODO Auto-generated constructor stub
            mSocket = new DatagramSocket();
        }

        @Override
        public void run() {
            if (mSocket == null)
                return;

            while (flag) {
                if (isSpeakMode) {
                    try {
                        int length = audioRec.read(inputBytes, 0, inputBufSize);

//                        calc(inputBytes, 0, length);

                        length = silk8.encode(inputBytes, 0, encodeBytes,
                                length);

                        DatagramPacket writePacket;
                        if (inetAddress.length() > 0) {
                            InetAddress inet = InetAddress
                                    .getByName(inetAddress);
                            writePacket = new DatagramPacket(encodeBytes,
                                    length, inet, NETPORT);
                            writePacket.setLength(length);
                            mSocket.send(writePacket);
                        }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        
        public void close() {
            flag = false;
            if (mSocket != null) {
                mSocket.close();
            }        
        }
    }
複製程式碼

  接下來我們要接收目標機器傳送過來的音訊資料了。同樣,建立一個執行緒用來接收網路中的音訊資料,並且對音訊資料進行解碼。

本地方法 decode(byte[] encoded, short[] lin, int size)
引數
       encoded     源資料
       lin          解碼後的資料
       size        請求解碼的資料大小
返回值          解碼後的資料大小 

  得到解碼後的PCM音訊流,我們就可以使用AudioTrack將音訊播放出來了。

  AudioTrack類在java應用程式中管理和播放音訊資源,將PCM音訊資料寫入到緩衝區來播放音訊裝置。首先建立AudioTrack物件,AudioTrack會初始化並連線音訊緩衝區,根據指定的緩衝區大小來決定audioTrack能夠播放多長的資料。呼叫getMinBufferSize(int,int,int)返回最小的緩衝區大小。然後根據得到的最小緩衝區大小來建立audioTrack物件:

複製程式碼
outputMinSize = AudioTrack.getMinBufferSize(8000,
                AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT);
audioTrk = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
                AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT, outputMinSize,
                AudioTrack.MODE_STREAM);
複製程式碼

  AudioTrack初始化工作完畢後啟用接收執行緒,並且呼叫play()開始播放。呼叫write(short[],int,int)方法將PCM音訊資料寫入到音訊硬體中。

 View Code

   最後,退出應用後別忘了釋放資源。

複製程式碼
public void onDestroy() {
  silk8.close();
  recevThread.close();
  recordThread.close();
  audioRec.release();
  audioTrk.release();
}
複製程式碼

相關推薦

Android音訊採集壓縮傳送

基本的實現流程:  1、從手機麥中採集音訊資料;2、將PCM音訊資料編碼壓縮;3、將壓縮好的音訊通過無線網路傳送出去;4、其他手機接收音訊資料並解碼;5、將音訊資料寫入到音軌中播放。專案雖然簡單,但其中的一些小問題也折騰了我不少時間。   首先我們建立一個執行緒用來採

微信瀏覽器內相容android iOS調取手機攝像頭進行拍照打水印壓縮預覽

實現這些功能使用瞭如下外掛: html部分 //調起攝像頭按鈕 <input type="file" id="file" accept="image/*" capture="camera"> //預覽圖片 <div id="file

tar gz bz2 xz zip z歸檔壓縮壓縮

默認 不同 unxz arch 信息 zip壓縮 壓縮命令 完成後 調用 壓縮、解壓縮命令壓縮格式:gz, bz2, xz, zip, Z壓縮算法:算法不同,壓縮比也會不同;compress: FILENAME.Zuncompressgzip: .gz gzip /PATH

Nginx反向代理負載均衡動靜分離快取壓縮防盜鏈跨域訪問

一、反向代理 1、在192.168.189.130機器啟動tomcat服務,http://192.168.189.130:8080/ 訪問服務正常 2、在192.168.189.131機器配置nginx server { listen 80; serve

Nginx反向代理負載均衡動靜分離緩存壓縮防盜鏈跨域訪問

什麽 delete block fault 避免 user 源文件 event methods 一、反向代理 1、在192.168.189.130機器啟動tomcat服務,http://192.168.189.130:8080/ 訪問服務正常 2、在192.168.189.

JavaScript線上美化(格式化)壓縮加密解密混淆工具-toolfk程式設計師工具網

    本文要推薦的[ToolFk]是一款程式設計師經常使用的線上免費測試工具箱,ToolFk 特色是專注於程式設計師日常的開發工具,不用安裝任何軟體,只要把內容貼上按一個執行按鈕,就能獲取到想要的內容結果。ToolFk還支援  BarCode條形碼線上生成、&nb

HTML實現線上程式碼格式化美化加密解密壓縮一鍵轉JavaScript功能工具-toolfk程式設計師工具網

 本文要推薦的[ToolFk]是一款程式設計師經常使用的線上免費測試工具箱,ToolFk 特色是專注於程式設計師日常的開發工具,不用安裝任何軟體,只要把內容貼上按一個執行按鈕,就能獲取到想要的內容結果。ToolFk還支援  BarCode條形碼線上生成、 

linux的檔案同步壓縮歸檔

1.檔案同步 命令 含義 rsync -r /mnt/ [email protected]:/mnt 同步資料 rsync -rp /mnt/ [em

webpack4 css打包壓縮分離去重等優化配置詳解

Webpack 4 目前版本已經到了4.27 相較於前面的版本還是有一些改動的,具體可以參考升級指南 遷移到新版本 這裡只介紹 css 的 打包、壓縮、分離、去重 的方法; 不懂的或者有更優的方案,歡迎評論交流 用到的外掛及loader 外掛描述備註 mini-css-extract-plugin

MATLAB--圖形旋轉壓縮映象剪下

%% 旋轉 x=[0 1 1 0 0]; y=[0 0 1 1 0]; plot(x,y) h=patch(x,y,'b'); h.FaceAlpha=0.5; hold on axis([-2 2 -2 2]) axis equal for i=1:40   %旋轉40次

實現CSS線上美化(格式化)壓縮加密解密混淆工具-toolfk程式設計師工具網

程式碼教學 STEP 1 STEP 2 核心程式碼如下 beautify_start:function(options){     if (toolfk.beautify_default.beautify_in_progress) {       

JS XML線上格式化壓縮校驗XML轉JSON工具-toolfk程式設計師工具網

程式碼教學 STEP 1 STEP 2 核心程式碼如下 var xt = "", h3OK = 1; function checkXML(e) {     var t, o, i = e.nodeName;     if ("h3" == i) {

【unix學習】檔案處理1—檢視統計壓縮查詢檔案

檔案處理—檢視、統計、壓縮、查詢檔案 文字檔案檢視 一次性全部檢視 cat file 翻頁檢視 more cat file 按q退出 顯示行數的檢視 nl cat file 十六進位制檢視 od -h file 八進位制檢視 od

hive處理小檔案(進行mapreduce壓縮歸檔優化解決)

背景 Hive query將運算好的資料寫回hdfs(比如insert into語句),有時候會產生大量的小檔案,如果不採用CombineHiveInputFormat就對這些小檔案進行操作的話會產生大量的map task,耗費大量叢集資源,而且小檔案過多會對namenode造成很

常用模組(shutil copy壓縮解壓)

作用與功能 主要用於檔案的copy,壓縮,解壓 匯入shuitl模組: import shutil    copy方法 1 1、shutil.copyfileobj()  開啟file1,並copy寫入file2: 2 with

win7下,Ant 配合yuicompressor對js和css進行合併壓縮拷貝處理

更新:2015/8/13 【NAnt】 NAnt is a .NET-based build tool. In theory it is kind of like make without make's wrinkles. In practice it's a lot

bat批處理實現資料庫備份壓縮刪除

在專案運營的過程中,為保證資料庫能及時備份,我們一般啟動系統的定時任務來進行備份。以下bat指令碼實現刪除1天前的壓縮備份檔案,同時生成新的備份壓縮檔案 @echo off rem 刪除1天前的資料庫備份 forfiles /m *.rar /d -1 /c

Linux中分割槽配額的設定,LVM邏輯卷的建立擴充套件壓縮刪除

一、 配 額   超級使用者[[email protected] ~]# fdisk /dev/vdb #新建一個分割槽 [[email protected] ~]# mkfs.xfs /dev/vdb1 #格式化 [[email

CentOS7 複製刪除移動壓縮解壓等常用命令整理

壓縮、解壓 tar -cvf fille.tar file(可以多個檔案空格隔開)-c: 建立壓縮檔案;-v: 顯示所有過程;-f: 使用檔案名字,是必須的,是最後一個引數) tar -x

html5+exif.js+canvas實現手機端照片上傳預覽壓縮旋轉功能

html5+canvas進行移動端手機照片上傳時,發現ios手機上傳豎拍照片會逆時針旋轉90度,橫拍照片無此問題;Android手機沒這個問題。 因此解決這個問題的思路是:獲取到照片拍攝的方向角,對非橫拍的ios照片進行角度旋轉修正。 利用exif.js讀取照片的拍攝資訊