通过 MP4 直播
Posted
技术标签:
【中文标题】通过 MP4 直播【英文标题】:Live streaming through MP4 【发布时间】:2012-10-12 05:01:51 【问题描述】:我正在开发在线电视服务。目标之一是在没有任何其他浏览器插件(Flash 除外)的情况下播放视频。
我决定使用 MP4,因为大多数 html5 浏览器和 Flash(作为备用)都支持它。这些视频由 FFMpeg 在服务器上从 ASF 转码。
但是,我发现 MP4 无法实时流式传输,因为它有一个 moov atom 用于必须指定长度的元数据。 FFMpeg 不能直接将 mp4 流式传输到标准输出,因为它将 moov 放在文件的末尾。 (Live transcoding and streaming of MP4 works in android but fails in Flash player with NetStream.Play.FileStructureInvalid error)
当然存在 MPEG-TS,但 HTML5 不支持<video>
。
我想到的是一种将流实时转码为 MP4 的方法,并且在每个新的 HTTP 请求上,首先发送一个 moov 指定一个非常长的视频长度数字,然后开始发送MP4 文件的其余部分。
是否可以通过这种方式使用 MP4 进行流式传输?
经过一些研究和av501的回答,我明白必须知道框架的大小才能工作。
可以将 mp4 文件分割成更小的部分以便进行流式传输吗?
当然,切换到另一种容器/格式是一种选择,但与 Flash 和 HTML5 兼容的唯一格式是 mp4/h264,所以如果我必须同时支持两者,我必须转码两次。
【问题讨论】:
【参考方案1】:您可以使用分段的 MP4。一个分段的 MP4 文件构建如下:
moov [moof mdat]+
然后,moov 框仅包含有关轨道的基本信息(有多少、它们的类型、编解码器初始化等),但不包含有关轨道中样本的信息。关于样本位置和样本大小的信息在 moof 框中,每个 moof 框后面都有一个 mdat,其中包含前面 moof 框中所述的样本。通常人们会选择 (moof, mdat)-pair 的长度为 2,4 或 8 秒左右(没有关于此的规范,但这些值对于大多数用例来说似乎是合理的)。
这是一种构建永无止境的 MP4 流的方法。
【讨论】:
看看这里:groups.google.com/forum/?fromgroups=#!topic/…这家伙似乎有一个非常相似的问题。 最终碎片化的 mp4 就像 Apple HTTP 直播一样,做得很好。一开始我忽略了这一点,因为我认为碎片化似乎是一种不必要的复杂性,但现在我认为这是唯一的选择。 @SebastianAnnies 这似乎可行,但是(至少)Safari 似乎使用单独的 Range GET 请求请求每个片段(从片段开始到 EOF,但过早终止),从而使整个处理流更令人讨厌。你有同样的经历吗?【参考方案2】:仅查看您问题的第二段(“视频是通过 ffmpeg 从服务器上的 ASF 转码的。”),您提到您正在使用 ffmpeg 对服务器上的视频进行转码。
使用 qt-faststart 或 MP4Box 将 MOOV atom 放在文件的开头。 (您还要确保使用 H264 视频和 AAC 音频编解码器以获得通用支持)
希望这对你有所帮助。
【讨论】:
它没有。经过无数次谷歌搜索,我发现 qt-faststart 被提到了很多 - 但它不适用于实时流,因为流是连续的 - 从一开始就无法知道帧/长度,因此无法创建 MOOV atom。如果我需要的是伪流(持续下载),qt-faststart 会有所帮助。【参考方案3】:这是我的想法,伙计们,其中一些可能在其他方面是正确的。我恳求无知,因为没有人真正完整地记录了这个过程,这都是有根据的猜测。
AvAssetWriter 仅编码为文件,似乎没有办法将编码的视频放入内存。在从后台线程写入文件时读取文件以说套接字会产生一个基本流,这本质上是一个 m4v,它是一个带有 h264/acc mdata 的容器,但没有 moov 原子。 (换句话说,没有标题) 没有苹果提供的播放器可以播放此流,但基于 ffplay 的修改后的播放器应该能够解码和播放流。这应该可行,因为 ffplay 使用可以解码基本流的 libavformat,一个警告,因为没有文件长度信息,有些事情必须由播放、DTS 和 PTS 确定,而且播放器也无法在文件中查找。
或者,m4v 流中的原始 naul 可用于构建 rtmp 流。
如果您想进一步讨论,可以直接与我联系。
您如何获取数据。
因为无论如何你都必须在接收端重建文件,我想你可以对它进行分段,Steve Mcfarin 写了一个小 appleSegmentedEcorder 你可以在他的 github 页面上找到,这解决了 moov 的一些问题原子,因为您拥有所有文件信息。
【讨论】:
这里有一个很好的解释,开始听起来像 rtmp 或一些自定义协议是要走的路fabiensanglard.net/mobile_progressive_playback/index.php 你的答案有警告,上面写着。时间是流媒体和播放的问题。所以 -1【参考方案4】:不,这不仅仅是很长的长度。您需要知道每一帧的确切大小才能在 mp4 中创建标题。 [这就是为什么它最终由各种编码器创建的原因]。
【讨论】:
不能把这些信息留空吗?经过一些调整,我设法创建了一个没有 moov atom 的 m4v 文件(基本上是一个 MP4),它在 Totem 中播放,没有显示任何有关视频长度的信息。 您的 m4v 是包含基本文件还是仅包含基本文件的 mp4(容器)?没有标头,它不再符合要求。所以玩不玩就看玩家的智商了。一些玩家可能会努力工作并尝试修复文件。但大多数人不会玩。 是的,m4v 似乎既可以是 mp4 文件,也可以是原始的 h264 流。在浏览器中运行的是 mp4,而 ffmpeg 生成的是原始流。所以看来终究是做不到了。以上是关于通过 MP4 直播的主要内容,如果未能解决你的问题,请参考以下文章
来自http直播m3u8文件的FFMPEG mp4? [关闭]