【问题标题】:Problem streaming video using media source extensions使用媒体源扩展的流式视频问题
【发布时间】:2018-12-19 03:21:38
【问题描述】:

我似乎有一个很奇怪的问题。我正在尝试播放正在使用网络浏览器直播的视频。为此,我正在查看 MediaSource 对象。我以某种方式得到它,以便将视频从服务器中以块的形式进行播放。问题是第一个块播放正确然后播放停止。

更奇怪的是,如果我在开始流式传输后让计算机进入睡眠状态,然后将其唤醒,视频就会按预期播放。

一些注意事项:

  1. 我目前正在使用 chrome。
  2. 我都试过了,无论是否调用 MediaSource 的 endOfStream。

    var VF = 'video/webm; codecs="vp8,opus"';
    var FC = 0;
    alert(MediaSource.isTypeSupported(VF));
    
    var url = window.URL || window.webkitURL;
    var VSRC = new MediaSource();
    var VURL = URL.createObjectURL(VSRC);
    var bgi, idx = 1;
    var str, rec, dat = [], datb, brl;
    var sbx;
    
    //connect the mediasource to the <video> elment first.
    vid2.src = VURL;
    
    VSRC.addEventListener("sourceopen", function () {
        // alert(VSRC.readyState);
        //Setup the source only once.
        if (VSRC.sourceBuffers.length == 0) {
            var sb = VSRC.addSourceBuffer(VF);
            sb.mode = 'sequence';
            sb.addEventListener("updateend", function () {
                VSRC.endOfStream();
            });
            sbx = sb;
        }
    });
    
    
    //This function will be called each time we get more chunks from the stream.
    dataavailable = function (e) {
                //video is appended to the sourcebuffer, but does not play in video element
                //Unless the computer is put to sleep then awaken!?
                sbx.appendBuffer(e.result);
                FC += 1;
                //These checks behave as expected.
                len.innerHTML = "" + sbx.buffered.length + "|" + VSRC.duration;
                CTS.innerHTML = FC;
    };
    

【问题讨论】:

    标签: javascript html media-player


    【解决方案1】:

    你犯了两个大错误:

    1. 只能在 sbx.updating 属性为 false 时调用 sbx.appendBuffer,否则 appendBuffer 会失败。所以现实中你需要做的是有一个chunk队列,如果sbx.updating为true,就向队列中添加一个chunk:

      if (sbx.updating || segmentsQueue.length > 0)
          segmentsQueue.push(e.result);
      else
          sbx.appendBuffer(e.result);
      
    2. 您的代码明确表示在第一个块之后停止播放:

      sb.addEventListener("updateend", function () {
          VSRC.endOfStream();
              });
      

      这是你真正需要做的:

      sb.addEventListener("updateend", function () {
          if (!sbx.updating && segmentsQueue.length > 0) {
              sbx.appendBuffer(segmentsQueue.shift());
          }
      });
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 2018-05-13
      • 1970-01-01
      • 2015-04-09
      • 2016-10-23
      • 1970-01-01
      相关资源
      最近更新 更多