HTML5视频,MediaSource,appendBuffer,如何跳过一些块

时间:2018-01-16 10:19:28

标签: javascript html5-video mediarecorder media-source

如果跳过一些块,视频元素将无法播放。

HTML:

var vdo0 = document.getElementById('vdo0');
var vdo1 = document.getElementById('vdo1');
var ms = new MediaSource();
var sourceBuffer = null;
var chunks = [];

vdo1.src = URL.createObjectURL(ms);
var i = 0;
var recv = function(){
    var chunk = chunks.shift();
    if(chunk){
        i++;
        if(i < 5 || i > 10){ // HERE, skipped some chunks, vdo1 will cannot play
            sourceBuffer.appendBuffer(chunk);
        }
        recv();
    }else{
        setTimeout(recv, 20);
    }
};

ms.addEventListener('sourceopen', function () {
    sourceBuffer = ms.addSourceBuffer('video/webm;codecs=vp8');
    recv();
}, false);

document.getElementById('btnStart').addEventListener('click', function(){
    navigator.mediaDevices.getUserMedia({
        video: true,
        audio: true
    }).then(function (s) {
        vdo0.srcObject = s;
        vdo0.oncanplay = function(){
            var mediaRecorder = new MediaRecorder(s, 'video/webm;codecs=vp8');
            mediaRecorder.ondataavailable = function (e) {
                if (e.data && e.data.size > 0) {
                    var reader = new FileReader();
                    reader.addEventListener("loadend", function () {
                        var arr = new Uint8Array(reader.result);
                        chunks.push(arr);
                    });
                    reader.readAsArrayBuffer(e.data);
                }
            };
            mediaRecorder.start(20);
        };
    }).catch(function (err) {
        A.log('ERROR: ', err);
    });
}, false);

使用Javascript:

var queryRestateJob = _sut.CreateQueryJob(@"SELECT field1, '' as field2, field3  FROM your_dataset.your_table WHERE _PARTITIONTIME = TIMESTAMP('2018-01-14')",
            new List<BigQueryParameter>(), new QueryOptions
            {
                CreateDisposition = CreateDisposition.CreateIfNeeded,
                WriteDisposition = WriteDisposition.WriteTruncate,
                DestinationTable = new TableReference
                {
                    DatasetId = "your_dataset",
                    ProjectId = "your_project",
                    TableId = "your_table$20180114"
                },
                AllowLargeResults = true,
                FlattenResults = false,
                ProjectId = "your_project"
            })
            .PollUntilCompleted();

            queryRestateJob = queryRestateJob.ThrowOnAnyError();
我想做, 当跳过一些块时,vdo1仍然可以播放。 MediaSource怎么能收回任何blob?

如果没有将第一个记录器blob推送到块,则vdo1也无法播放。为什么?

怎么办?

感谢。

1 个答案:

答案 0 :(得分:0)

你不能随意跳过块。解复用器无法在随机点重新同步。

由于您使用的是WebM,因此可以跳到另一个群集。集群以0x1F43B675开头。 https://matroska.org/technical/specs/index.html#Cluster

请注意,要使其正常工作,您的视频应以每个群集以关键帧开头的方式进行编码。否则,您的视频将无法继续播放,因为编解码器不会满意。