Hybrid移動應用語音錄製及斷點上傳實現思路

前言

斷點上傳功能在移動應用中較爲常見,使用過程中,要求錄製較爲清晰切大小適中的語音文件,能夠控制斷點上傳會有較好的用戶體驗, 下面是我在這方面的一些實踐經驗,分享一下,不成熟的地方歡迎指正!

混合應用中的音頻錄製

首先創建一個Cordova項目:

cordova create Audio com.delaware.AudioDemo AudioDemo

cd Audio

cordova platform add ios

cordova platform add android

添加語音功能插件:

cordova plugin add cordova-media-with-compression

採用的音頻格式爲MPEG4, MPEG4是一個影音串流視訊壓縮技術及商業標準格式,MPEG4之優勢在於其壓縮比(最大可達4000:1),低位元速率,較少之核心程式空間,加強運算功能,及強大之通訊應用整合能力,己成爲影音數位視訊產業,最重要之功及標準格式, 後綴名字爲.m4a

利用插件可以合理進行圖片,比如可以設置壓縮碼率等等,具體方案我們看一實現代碼:

錄音:

// Record audio with compression
//
function recordCompressedAudio() {
    var src = "myrecording.m4a";
    var mediaRec = new Media(src,
        // success callback
        function() {
            console.log("recordCompressedAudio():Audio Success");
        },

        // error callback
        function(err) {
            console.log("recordCompressedAudio():Audio Error: "+ err.code);
        });

    // Record MPEG compressed audio, single channel at 16kHz
    var options = {
        SampleRate: 16000,
        NumberOfChannels: 1
    }

    mediaRec.startRecordWithCompression(options);
}

停止錄製:

media.pauseRecord();

播放:(想要播放一個文件,需要先把錄音release掉,否則無法播放)

// Play audio
//
function playAudio(url) {
    // Play the audio file at url
    var my_media = new Media(url,
        // success callback
        function() {
            console.log("playAudio():Audio Success");
        },
        // error callback
        function(err) {
            console.log("playAudio():Audio Error: "+err);
        }
    );

    // Play audio
    my_media.play();

    // Pause after 10 seconds
    setTimeout(function() {
        my_media.stop();
    }, 10000);
}

對於音頻文件錄製,需要建一個標準文件夾用於管理文件位置,方便。

這裏我們用到插件:

cordova plugin add cordova-plugin-file

定義一個文件夾:

fileSystem.root.getDirectory("MyApp", {create: true}, gotDir);

function gotDir(dirEntry) {
      dirEntry.getFile(escape(fileName).replace(/%/g, ''), {create: true, exclusive: false}, gotFileEntry, fail);
    }
function gotFileEntry(fileEntry) {
      $timeout(function(){
        fileEntry.getMetadata(function(data){
          if(data.size === 0){
            fileUrl = fileEntry.toURL();
          }else{
           fileUrl = fileEntry.toURL();
          }
        },function(){
          fileUrl = fileEntry.toURL();

        });
      },200);
    }

判斷文件是否存在,沒有的話,進行創建操作。

音頻文件斷點上傳

文件上傳操作

優點:

1.傳輸數據爲字節級,傳輸數據可自定義,數據量小。相應的移動端開發,手機費用低
2.傳輸數據時間短,性能高
3.適合C/S之間信息實時交互
4.可以加密,數據安全性高

缺點:

1.需要對傳輸的數據進行解析,轉化爲應用級的數據
2.對開發人員的開發水平要求高
3.相對於Http協議傳輸,增加了開發量

Http請求主要有http協議,基於http協議的soap協議,常見的http數據請求方式有get和post,web服務

優點:

1.基於應用級的接口使用方便
2.要求的開發水平不高,容錯性強

缺點:

1.傳輸速度慢,數據包大。
2.如實現實時交互,服務器性能壓力大
3.數據傳輸安全性差

Socket適用場景:大文件上傳,網絡遊戲,銀行交互,支付。

這裏有Android爲例:

try {  
                    uploadbar.setMax((int)uploadFile.length());  
                    String souceid = logService.getBindId(uploadFile);  
                    String head = "Content-Length="+ uploadFile.length() + ";filename="+ uploadFile.getName() + ";sourceid="+  
                        (souceid==null? "" : souceid)+"\r\n";  
                    Socket socket = new Socket("172.19.34.69",7878);
                    OutputStream outStream = socket.getOutputStream();  
                    outStream.write(head.getBytes());  

                    PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream());      
                    String response = StreamTool.readLine(inStream);  
                    String[] items = response.split(";");  
                    String responseid = items[0].substring(items[0].indexOf("=")+1);  
                    String position = items[1].substring(items[1].indexOf("=")+1);  
                    if(souceid==null){
                        logService.save(responseid, uploadFile);  
                    }  
                    RandomAccessFile fileOutStream = new RandomAccessFile(uploadFile, "r");  
                    fileOutStream.seek(Integer.valueOf(position));  
                    byte[] buffer = new byte[1024];  
                    int len = -1;  
                    int length = Integer.valueOf(position);  
                    while(start&&(len = fileOutStream.read(buffer)) != -1){  
                        outStream.write(buffer, 0, len);  
                        length += len;  
                        Message msg = new Message();  
                        msg.getData().putInt("size", length);  
                        handler.sendMessage(msg);  
                    }  
                    fileOutStream.close();  
                    outStream.close();  
                    inStream.close();  
                    socket.close();  
                    if(length==uploadFile.length()) logService.delete(uploadFile);  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  

在Android中除了通過http協議上傳小文件外,還可以通過Socket上傳較大的文件

案例具體思路:

這裏寫圖片描述

文件被第一次上傳時發送: “Content-Length=”+ uploadFile.length() + “;filename=”+ uploadFile.getName() + “;sourceid=”+null+”\r\n”;字段給服務器

服務器收到字段後,看到文件的sourceid字段值爲空,則表示該文件第一次上傳,服務器就會自動爲其創建id,並且在本地根據文件名建立相應文件用於接收文件數據,同時把該文件路徑和id保存在Map集合中,併發送:“sourceid=”+ id+ “;position=0\r\n”;內容給客戶端,客戶端收到服務器爲其創建的id和應該從上傳文件的什麼位置開始讀取信息後,在SQLite數據庫中記錄下本次上傳文件的id和文件路徑,然後上傳文件。

服務器端則開始接收從客戶端發來的數據並保存起來,並且時刻把該文件的上傳的數據大小保存在以該文件命名的.log文件中。

當在發送的的時候突然關機或網絡出現狀況,當再次上傳該文件時,客戶端就會從SQLite中根據文件路徑查找到已上傳文件的id,然後發送內容給服務器端,服務器從發來的sourceid字段中讀到了數據,就從map集合中找到該文件路徑,然後根據路徑和文件名找到.log文件,並從中讀取上次上傳文件的大小發送給客戶端,客戶端得到後遍選擇從文件的指定文件讀取上傳,服務器則再次接收並從文件指定位置保存。

Socket套接字原理分析

建立Socket連接至少需要一對套接字,其中一個運行於客戶端,稱爲ClientSocket ,另一個運行於服務器端,稱爲ServerSocket 。

套接字之間的連接過程分爲三個步驟:服務器監聽,客戶端請求,連接確認。

服務器監聽:

服務器端套接字並不定位具體的客戶端套接字,而是處於等待連接的狀態,實時監控網絡狀態,等待客戶端的連接請求。

客戶端請求:

指客戶端的套接字提出連接請求,要連接的目標是服務器端的套接字。爲此,客戶端的套接字必須首先描述它要連接的服務器的套接字,指出服務器端套接字的地址和端口號,然後就向服務器端套接字提出連接請求。

連接確認:

當服務器端套接字監聽到或者說接收到客戶端套接字的連接請求時,就響應客戶端套接字的請求,建立一個新的線程,把服務器端套接字的描述發給客戶端,一旦客戶端確認了此描述,雙方就正式建立連接。而服務器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連接請求。

參考文獻:http://blog.csdn.net/shimiso/article/details/8529633

http://blog.csdn.net/zl594389970/article/details/12500371

個人微信公衆號

這裏寫圖片描述

發佈了208 篇原創文章 · 獲贊 143 · 訪問量 79萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章