MediaSource 实现视频流分片快速加载

前言:直接加载视频资源会有视频资源泄露的风险,用视频流分片加载可以快速加载视频,并且避免视频资源泄露。视频资源是MP4格式。

1.对视频资源有要求

使用MediaSource加载视频资源,实现分片加载对视频编码格式有要求,
可以参考
MP4文件主要由ftyp,mdat,moov三部分组成。
三部分的主要职责:
(1)ftyp 记录了mp4格式,编码格式之类的一些基本信息
(2)mdat记录了视频媒体信息(mdat的体积往往非常的大,几乎等于MP4总大小)
(3)moov是如同检索表一样的存在,里面记录了每一帧对应的数据在哪里等等
而这三部分的在mp4视频中的顺序决定了该视频支不支持边下边播,具体主要是mdat和moov两个部分的顺序,需要moov在mdat前,也就是先加载类似视频的索引才能实现该效果。
可以下载两个文件
1.查看MP4编码格式 mp4info
2.转换编码格式 faststart

2.分片加载视频流

转换完格式的视频资源,默认加载就自动分片了,可以直接在player.src中插入请求地址,我这个是get请求直接返回流。这种要求后端代码做分片限制。

player.src = 'http://xxx'

但是分的片不是固定的。
想要固定分片可以通过限制请求头的Range,并迭代请求。

//获取视频
function getVideo(video_size) {
    //video_size 单位MB video_size*1024*1024 单位B 字节
    const totalSize = video_size * 1024 * 1024
    const chunkSize = Math.ceil(totalSize / 5)//浏览器同域名请求的最大限制,谷歌浏览器最多六路
    const numChunks = 5
    let index = 0
    var startByte,endByte
    //获取视频流对视频格式有要求 
    const mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
    if ("MediaSource" in window && MediaSource.isTypeSupported(mimeCodec)) {
        const mediaSource = new MediaSource();
        player.src = URL.createObjectURL(mediaSource);
        mediaSource.addEventListener("sourceopen", sourceOpen);
    } else {
        console.error("Unsupported MIME type or codec: ", mimeCodec);
    }

    function sourceOpen(_) {
        const mediaSource = this;
        const sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
        function send(){
            if (index >= numChunks) {
                sourceBuffer.addEventListener('updateend', function (_) {
                    mediaSource.endOfStream()
                })
            }else{
                startByte = index * chunkSize
                endByte = Math.min(startByte + chunkSize - 1, totalSize - 1)
                var xhr = new XMLHttpRequest();
                xhr.open("get", 'http://XXX')
                xhr.responseType = "arraybuffer";//可以分配一段可以存放数据的连续内存区域。
                xhr.setRequestHeader('Range', `bytes=${startByte}-${endByte}`);//限制range
                xhr.onload = function () {
                    index++
                    sourceBuffer.appendBuffer(xhr.response);//资源拼接
                    send()
                    player.play();
                };
                xhr.send();
            }
        }
        send()
    }

这样的前端分片对请求次数有限制,谷歌浏览器中第7次请求报错。解决办法参考

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值