我正在构建一个基于媒体源扩展协议的自适应流媒体的html5视频播放器。我使用的是mp4。
我有两个版本的同一个视频(让我们说高质量和低质量),我希望能够在几乎没有延迟的版本之间切换。问题在于,在更改版本时,我需要一个以关键帧开头的片段,并且在视频中经常使用关键帧对带宽非常不利。
我正在寻找一种方法来发送一个以用户更改版本时以关键帧开头的片段,以及一个没有其他关键帧的片段(我意识到bug在Chromium中有关于没有关键帧的片段,但是现在让我们忽略它并且它将被修复)
我想过用一些关键帧复制视频中的每个流,而在另一个没有的情况下复制(显然除了第一帧)然后在切换视频版本时只使用带有关键帧的流。看起来像这样的东西:
// *
// * represents a key frame; * represents a normal frame; a fragment has 4 frames
*
Stream A.1 **** **** **** **** **** **** **** // version A with no key frames
* * * * * * *
Stream A.2 **** **** **** **** **** **** **** // version A with key frames
// at the beginning of each fragment
.
Stream B.1 .... .... .... .... .... .... ....
. . . . . . .
Stream B.2 .... .... .... .... .... .... ....
* .
A -> B **** **** .... .... .... .... ....
from A.1 A.2 B.1 B.2 B.2 B.2 B.2
因此每个帧都是一个关键帧,或者是其前身可以成功解码的普通帧。这会将通过线路发送的关键帧数限制到最小。
但是嘿!从A1
切换到A2
,浏览器会将其视为更改视频流,但由于A2
不以关键帧开头,因此无法正常工作。
有没有人聪明地知道如何实现这样的结果?我现在正在考虑重写客户端中的moov和moof原子,以欺骗玩家认为一切都如同它一样。但我对此并不了解......
我正在为360玩家工作。 360很难,因为视频的很大一部分是流式传输但未显示,这意味着在带宽受限的情况下,所显示的部分视频质量远低于人们习惯的质量。有一些工具和技术可以生成多个版本的视频,每个版本都以不同的视图方向为中心,然后播放器决定在运行时流式传输哪个版本。
由于用户可以随时改变视图方向,因此能够对这种变化做出快速反应非常重要,远远超过字节速率自适应。而且由于这个目标的目标是节省带宽,所以从添加大量关键帧开始会很糟糕!
此外,由于iOS Safari不支持内联视频,这对360播放器来说很关键,我很好地依赖iOS Safari不支持的MSE(严重的是,这些人在做什么?)
答案 0 :(得分:1)
每个片段都需要以关键帧开头,这样才能正确切换;为了使这项工作你的关键帧间隔应该均匀地划分片段持续时间,例如正确的组合是: