语境:
我正在构建一个基于媒体源扩展协议的具有自适应流媒体的 html5 视频播放器。我正在使用 mp4。
问题:
我有同一个视频的两个版本(假设质量高和质量差),我希望能够在版本之间切换而几乎没有延迟。问题是在更改版本时,我需要有一个以关键帧开头的片段,并且视频中经常出现关键帧对带宽非常不利。
我正在寻找一种方法来发送一个在用户更改版本时以关键帧开头的片段,以及一个没有其他关键帧的片段(我知道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
所以每一帧要么是关键帧,要么是可以成功解码其前身的正常帧。这会将通过网络发送的关键帧的数量限制在最低限度。
但是,嘿!浏览器将切换 from A1
toA2
理解为更改视频流并且不起作用,因为A2
它不是从关键帧开始的。
有没有人知道如何实现这样的结果?我目前正在考虑重写客户端中的 moov 和 moof 原子,以欺骗玩家认为一切都与它不同。但是我对它了解不多...
动机:
我正在开发 360 播放器。360 很难,因为有很大一部分视频是流式传输但未显示的,这意味着在带宽有限的情况下,显示的视频部分质量比人们习惯的要低得多。有一些工具和技术可以生成多个版本的视频,每个版本都以不同的视图方向为中心,然后播放器决定在运行时播放哪个版本。
由于用户可以随时改变视图方向,因此能够对这种变化做出快速反应是非常重要的,这比对字节速率适应更重要。而且由于这个东西的目标是节省带宽,所以从添加大量关键帧开始会很糟糕!
此外,由于 iOS Safari 不支持内联视频,这是 360 播放器的关键,我可以依靠 iOS Safari 不支持的 MSE(说真的,那些人在做什么?)