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/[email protected]: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/[email protected]: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>

  

猜你喜欢

转载自www.cnblogs.com/wanggang123/p/12316895.html