Html5 播放實時音頻流


     項目需求 Web端播放實時音頻流,折騰了兩天后問題得以解決。記錄下開發調試過程,方便后來者。

首次想到是利用Audio標簽,Audio標簽可以直接播放MP3格式,服務端將實時音頻流編碼成MP3格式

通過Http方式傳給Web端即可,前端代碼如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
    </script>
</head>
<body>
	<audio controls="controls" autoplay="autoplay">
	<source src="http://127.0.0.1:12345/cgmedia/28181/getaudio?id=34020000001310000001@192.168.1.108:5060&format=mp3&transporttype=udp&transportport=22000" type="audio/mpeg">
	</audio>
</body>
</html>

  通過Audio標簽 實現音頻流播放 代碼比較簡單,但有緩沖過大問題,粗略測試了下延時 20-30s左右,這顯然

不滿足實時播放實時播放需求。開始調試時懷疑是后台服務端傳輸過來的流有問題,於是將流保存成MP3文件進行

測試 ,結果正常未出現緩沖一段時間后開始播放。分析Audio標簽發出的Http報文,發現Http請求Head中有Range字段,

嘗試做了相應Response,結果未發生變化。猜想Audio標簽可能只適合於MP3文件(一次性將Audio數據加載完成再處

理)。如這個猜測不對,歡迎指正(本人主要從事后台媒體服務開發,前端經驗很少)。

      Audio標簽的方式不行,想到利用Web Audio API是實現,基本的思路是:通過WebSocket 接收服務端推送過來的音

頻流(MP3格式)調用decodeAudioData進行解碼,最后將解碼數據推送到AudioContext最后一個Node,代碼如下:

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
  
      function WebSocketTest()
         {
     var wsUrl = "ws://127.0.0.1:12345/cgmedia/28181/getaudio?id=34020000001310000001@192.168.1.108:5060&format=mp3&transporttype=udp&transportport=22000";
              ws = new WebSocket(wsUrl);
     ws.binaryType = 'arraybuffer'; //arraybuffer
     ws.onmessage = function(msg) {
     var data =  msg.data;
    var datalen = msg.data.size;
    var reader = new FileReader();
        var audioContext = new AudioContext({
        sampleRate:8000,
        });
     
     reader.onload = function(evt)
      {
       if(evt.target.readyState == FileReader.DONE)
       {
          audioContext.decodeAudioData(data, function(buffer) {
         console.log("decode success");
         var bufferSource = audioContext.createBufferSource();
         bufferSource.connect(audioContext.destination);
         bufferSource.buffer = buffer;
         bufferSource.start(0);
        }, function(e) {
         console.log("decode failed" + e);
        });
        
       }
      }
    reader.readAsArrayBuffer(new Blob([data]));
     
   };
   ws.onopen = function(evt) {
    if(self.verbose) {
     console.log("Connection open......");
    } 
   };
   ws.onclose = function(evt) {
    if(self.verbose) {
     console.log("Connection closed......");
    }
   };
         }
    </script>
</head>
<body>
 <button onclick="WebSocketTest()">發送請求</button>
</body>
</html>

   采用Audio Web API方式播放實時流會出現卡頓現象,以上方法一次性解碼的數據可以連續播放,每次解碼后要重新

創建BufferSource,顯而易見這種播放模式播放實時流效率很低,查閱了Audio Web API 文檔 播放網絡流似乎要利用

 基於AudioWorkletProcessor的自定義節點,文檔也給了一個簡單的例子,那個例子不符合我們的使用場景。沒有

更多的時間研究Audio Web API,這種方案只好作罷,單看Audio Web API接口有些無語, 這有可能跟Web端處理能力有關。

   可行的方法

     條條大路通羅馬,畢竟項目不是科研,可以實現需求就行。一種可行的方法是服務端輸出Rtmp音頻流 通過video.js播放

實際應該是用了flash。項目開始已經想到了這個方案可行只是覺得有些繞(需要將音頻流封裝后推送到rtmp server)。

另外一個可行的方案就是利用H5 MSE實現,這個方案也有開源的庫可以用,例如flv.js 這需要 服務端將音頻打包成flv格式

推送給Web前端,Web端接收到音頻數據后調用flv.js進行播放。video.js 及flv.js github都有下載 代碼就不貼出來了。

如需交流可加QQ群766718184,1038388075 或者QQ3501870

視頻下載地址:http://www.chungen90.com/?news_33/

 Demo下載地址: http://www.chungen90.com/?news_34


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM