更新:

因此,我能够通过使用offsetTimestamp属性(在附加每个视频后将其递增)来使其工作。

我现在的问题:
1)为什么在将MediaSource.mode设置为sequence时无法正确完成此操作?

2)为什么我的MediaSource.duration总是“Infinity”,而不是正确的持续时间?

我正在尝试使用MediaSource API附加多个视频文件,然后像播放1个视频一样无缝播放它们。

我已经按照规范(DASH-MPEG)对视频进行了正确的转码,当单独播放它们时,它们可以正常工作。

但是,当我尝试追加多个时,我遇到了这样的问题,即段之间相互覆盖,持续时间不正确等。即使一切似乎都按预期执行了。

我试过了offsetTimestamp,但是根据文档设置MediaSource.mode为'sequence'应该会自动处理这个问题。同样,由于某种原因,即使附加了段,MediaSource.duration似乎始终是“Infinity”。

这是我的代码:

<script>
 function downloadData(url, cb) {
    console.log("Downloading " + url);

    var xhr = new XMLHttpRequest;
    xhr.open('get', url);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function () {
        cb(new Uint8Array(xhr.response));
    };
    xhr.send();
}

if (MediaSource.isTypeSupported('video/mp4; codecs="avc1.64001E"')) {
    console.log("mp4 codec supported");
}

var videoSources = [
    "{% static 'mp4/ff_97.mp4' %}",
    "{% static 'mp4/ff_98.mp4' %}",
    "{% static 'mp4/ff_99.mp4' %}",
    "{% static 'mp4/ff_118.mp4' %}"
]

var mediaSource = new MediaSource();


mediaSource.addEventListener('sourceopen', function(e) {


    var sourceBuffer = mediaSource.addSourceBuffer('video/mp4; codecs="avc1.64001E"');
    sourceBuffer.mode = 'sequence';

    console.log('SourceBuffer mode set to ' + sourceBuffer.mode);

    sourceBuffer.addEventListener('updateend', function(e) {
        console.log('Finished updating buffer');
        console.log('New duration is ' + String(mediaSource.duration));

        if (videoSources.length == 0) {
            mediaSource.endOfStream();
            video.currentTime = 0;
            video.play();
            return;
        }

        downloadData(videoSources.pop(), function(arrayBuffer) {
            console.log('Finished downloading buffer of size ' + String(arrayBuffer.length));
            console.log('Updating buffer');
            sourceBuffer.appendBuffer(arrayBuffer);
        });

        console.log('New duration: ' + String(mediaSource.duration));

    });

    downloadData(videoSources.pop(), function(arrayBuffer) {
        console.log('Finished downloading buffer of size ' + String(arrayBuffer.length));
        console.log('Updating buffer');
        sourceBuffer.appendBuffer(arrayBuffer);
    });



}, false);

var video = document.querySelector('video');
video.src = window.URL.createObjectURL(mediaSource);

这是日志:
mp4 codec supported
(index):78 SourceBuffer mode set to sequence
(index):45 Downloading /static/mp4/ff_118.mp4
(index):103 Finished downloading buffer of size 89107
(index):104 Updating buffer
(index):81 Finished updating buffer
(index):82 New duration is Infinity
(index):45 Downloading /static/mp4/ff_99.mp4
(index):98 New duration: Infinity
(index):92 Finished downloading buffer of size 46651
(index):93 Updating buffer
(index):81 Finished updating buffer
(index):82 New duration is Infinity
(index):45 Downloading /static/mp4/ff_98.mp4
(index):98 New duration: Infinity
(index):92 Finished downloading buffer of size 79242
(index):93 Updating buffer
(index):81 Finished updating buffer
(index):82 New duration is Infinity
(index):45 Downloading /static/mp4/ff_97.mp4
(index):98 New duration: Infinity
(index):92 Finished downloading buffer of size 380070
(index):93 Updating buffer
(index):81 Finished updating buffer
(index):82 New duration is Infinity

最佳答案



您需要调用 MediaSource.endOfStream() ,以便MediaSource对象在其SourceBuffer中计算段的实际持续时间。我看到您正在执行此操作,但是您似乎在尝试调用MediaSource.duration之前尝试访问endOfStream()。我建议您阅读MSE规范中的end of stream algorithm,您会注意到它会导致调用duration change algorithm

如果要让<video>元素在调用MediaSource.endOfStream()之前报告持续时间,则实际上可以根据自己对附加段的估计,使用 MediaSource.duration 设置一个值。



据我所知,它应该做。但是我本人更喜欢显式timestampOffset方法,因为它在想要将段追加到缓冲区的最前面时提供了更大的灵活性(即,如果用户在当前缓冲区的末尾处寻找路径,那么您将希望在加载后添加+追加)。差距)。尽管我很欣赏在您的用例中寻求我不是必需的。

10-08 00:45