本文介绍了MediaSource API - 将多个视频追加/连接到一个缓冲区中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:

因此我可以通过使用offsetTimestamp属性(在附加每个视频后递增它)来使其工作。

SO I was able to get this to work by using the offsetTimestamp property (incrementing it after appending each video).

我现在的问题:
1)为什么在将MediaSource.mode设置为序列时没有正确完成?

My questions now:1) Why isn't this done properly when setting the MediaSource.mode to sequence?

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

2) Why is my MediaSource.duration always "Infinity" and not the correct duration?

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

I'm trying to use the MediaSource API to append multiple video files and play them seamlessly as if it were 1 video.

我已经正确地对我的视频进行了转码spec(DASH-MPEG)并且当它们单独播放时,它们工作正常。

I've properly transcoded my videos according to the spec (DASH-MPEG) and when playing them individually, they work fine.

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

However, when I try to append multiple, I run into issues where the segments overwrite one another, incorrect duration, etc. Even though everything seems to be executing as expected.

我尝试过使用offsetTimestamp,但是根据文档设置MediaSource.mode 'sequence'应该自动处理这个。此外,出于某种原因,MediaSource.duration即使在追加一个片段后也总是看似无限。

I've tried playing around with the offsetTimestamp, but according to the documentation setting MediaSource.mode to 'sequence' should automatically handle this. Also, for some reason, MediaSource.duration always seems to be 'Infinity' even after appending a segment.

这是我的代码:

<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对象计算其 SourceBuffer 中段的实际持续时间。我看到你正在这样做,但看起来你在调用 endOfStream() MediaSource.duration C>。我建议您阅读。

You need to call MediaSource.endOfStream() in order for the MediaSource object to calculate the actual duration of segments in its SourceBuffer. I see that you are doing this, but it looks like you're trying to access MediaSource.duration before calling endOfStream(). I suggest you read up on the end of stream algorithm in the MSE Spec, you'll notice that it will lead to invoking the duration change algorithm.

如果您想要< video> 元素报告a在调用 MediaSource.endOfStream()之前的持续时间,您实际上可以使用基于您自己对附加段的估计。

If you want to have your <video> element report a duration before calling MediaSource.endOfStream(), you can actually set a value using MediaSource.duration based on your own estimate of segments appended.

据我所知,应该这样做。但是我自己更喜欢显式的 timestampOffset 方法,因为它在想要在缓冲区中远远追加段时提供了更大的灵活性(即,如果用户在当前缓冲区之前寻找方法)结束,你会想要开始加载+附加差距后追加)。虽然我很欣赏在你的用例中寻求我不是一个要求。

As far as I know, it should do. But I have preferred the explicit timestampOffset approach myself as it provides more flexibility when wanting to append segments far ahead in the buffer (ie. if the user seeks way ahead of the current buffer end, you'll want to start loading+appending after a gap). Although I appreciate that seeking my not be a requirement in your use-case.

这篇关于MediaSource API - 将多个视频追加/连接到一个缓冲区中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 21:00