我正在尝试将 H.264 视频源流式传输到网络浏览器。 Media Foundation 用于编码分段的 MPEG4 流(MFCreateFMPEG4MediaSink
with MFTranscodeContainerType_FMPEG4
, MF_LOW_LATENCY
and MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS
已启用)。然后,该流通过以下方式连接到 Web 服务器:IMFByteStream
.
当 H.264 视频被用户使用时,它的流式传输工作正常。<video src=".."/>
标签。然而,产生的延迟约为 2 秒,这对于相关应用程序来说太大了。我怀疑客户端缓冲导致了大部分延迟。因此,我正在尝试使用媒体源扩展 (MSE) 对浏览器内流进行编程控制。但是,当通过 MSE 使用相同的 MPEG4 流时,Chrome 会失败并出现以下错误:
解析 MP4 失败:MSE 不允许 TFHD 基本数据偏移。看https://www.w3.org/TR/mse-byte-stream-format-isobmff/#movie-fragment-relative-addressing https://www.w3.org/TR/mse-byte-stream-format-isobmff/#movie-fragment-relative-addressing
MPEG4 流中 moof/mdat 片段的 mp4dump。这清楚地表明TFHD包含“非法”内容base data offset
范围:
[moof] size=8+200
[mfhd] size=12+4
sequence number = 3
[traf] size=8+176
[tfhd] size=12+16, flags=1
track ID = 1
base data offset = 36690
[trun] size=12+136, version=1, flags=f01
sample count = 8
data offset = 0
[mdat] size=8+1624
我使用的是 Chrome 65.0.3325.181(官方版本)(32 位),在 Win10 版本 1709 (16299.309) 上运行。
有没有办法使用 Media Foundation 生成 MSE 兼容的 H.264/MPEG4 视频流?
状态更新:
基于roman-r https://stackoverflow.com/users/868014/roman-r建议,我设法通过拦截生成的 MPEG4 流并执行以下修改来自行解决问题:
- Modify Track Fragment Header Box (tfhd):
- remove
base_data_offset
参数(将流大小减少 8 个字节)
- set
default-base-is-moof
flag
- Add missing Track Fragment Decode Time (tfdt) (increases stream size by 20bytes)
- set
baseMediaDecodeTime
范围
- Modify Track fragment Run box (trun):
字段描述记录在https://www.iso.org/standard/68960.html https://www.iso.org/standard/68960.html(免费下载)。
切换到基于 MSE 的视频流将延迟从约 2.0 秒减少到 0.7 秒。通过调用,延迟进一步减少到 0-1 帧IMFSinkWriter::NotifyEndOfSegment
每次 IMFSinkWriter::WriteSample 调用之后。
有一个示例实现可用https://github.com/forderud/AppWebStream https://github.com/forderud/AppWebStream