通过MediaSource分段播放demo

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
  </head>
  <body>
    <video controls id='video'></video>
    <input type='file' id='file'/>
    <script>
        /**
         *
         *
         *格式为 fragmented Mp4 https://blog.csdn.net/nonmarking/article/details/53439481
         *
         *
         */
        //help:
        //https://zhuanlan.zhihu.com/p/26374202
        //http://www.ptbird.cn/mediadource-readyState-is-not-open.html
        //https://stackoverflow.com/questions/28815529/mediasource-uncaught-invalidstateerror-failed-to-execute-appendbuffer-on-so
        //https://blog.csdn.net/nonmarking/article/details/53439481
        //转码工具Bento4 下载链接 https://www.bento4.com/downloads/
        //shell .\mp4fragment.exe .\v0.mp4 v0-new.mp4
        let file = null;
        let video = document.getElementById('video');
        let mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
        let i = 0;
        document.getElementById('file').onchange = function(){
          file = this.files[0];
          //一个视频分成3段 首先这个视频要大于30*1024*1024,结尾是file.size
          let blob = file.slice(0,10*1024*1024);
          let blob2 = file.slice(10*1024*1024,20*1024*1024);
          let blob3 = file.slice(20*1024*1024,30*1024*1024);
          //创建MediaSource
          let mediaSource = new MediaSource();
          //video.src 通过 URL.createObjectURL 链接 mediaSource
          video.src = URL.createObjectURL(mediaSource);
          //mediaSource设置监听打开链接
          mediaSource.addEventListener('sourceopen', sourceOpen);
          function sourceOpen(){
           
            let mediaSource = this;
            //创建sourceBuffer
            let sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
            //sourceBuffer监听数据更新updateend
            sourceBuffer.addEventListener('updateend', function (_) {
                //分了三段 so 0 1 2 ,当i==2时表示3段已经全部加入sourceBuffer
                if(i==2){
                  mediaSource.endOfStream();
                  URL.revokeObjectURL(video.src);
                }else{
                  //回调中读取字节流触发updateend
                  let cb = function (buf) {
                    console.log(sourceBuffer.appendBuffer);
                    sourceBuffer.appendBuffer(buf);
                  }
                  //i==0 表示第一段加载完毕,开始加载第二段
                  if(i==0)
                    fetchAB(blob2, cb);
                  //i==0 表示第二段加载完毕,开始加载第三段
                  else if(i==1)
                    fetchAB(blob3, cb);
                }
                //第一段加载完毕就开始播放
                if(i==0){
                  video.play();
                }
                i++;
               
              });

            //调用读取数据的方法,在回调中加入字节流,触发updateend
            fetchAB(blob, function (buf) {
              console.log(sourceBuffer.appendBuffer);
              sourceBuffer.appendBuffer(buf);
            });
           
          }
          function fetchAB (file, cb) {
            let reader = new FileReader();
            reader.onload = function(e){
              console.log(e.target.result);
              cb(e.target.result);
            }
            reader.readAsArrayBuffer(file);
           
          }
          //fetchAB(file);
        }
    </script>
  </body>
</html>

 

  • 1
    点赞
  • 2
    评论
  • 4
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页

打赏作者

喵脚三

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值