我在一家在线电视服务公司工作。其中一个目标是在没有任何额外的浏览器插件(除了Flash)的情况下播放视频。
我决定使用MP4,因为大多数HTML5浏览器和Flash都支持它(作为后备)。这些视频是通过FFMpeg在服务器上从ASF转码的。
然而,我发现MP4不能被实时流传输,因为它有一个moov原子用于必须指定长度的元数据。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,所以如果我必须同时支持这两种格式,我将不得不进行两次转码。
发布于 2012-12-11 03:42:56
这是我的想法,伙计们,其中一些可能是对的,而另一些可能是错的。我为自己的无知辩护,因为没有人真正完整地记录了这个过程,这都是一个有根据的猜测。
AvAssetWriter只对文件进行编码,似乎没有办法将编码后的视频存储到内存中。从后台线程读取正在写入的文件,比如说一个套接字,结果是一个基本流,这本质上是一个m4v,它是一个包含h264/acc mdata的容器,但没有moov原子。(换句话说,没有标题)苹果提供的播放器不能播放这个流,但是一个基于ffplay的修改后的播放器应该能够解码和播放这个流。这应该可以工作,因为ffplay使用libavformat可以解码基本流,一个警告,因为没有文件长度信息,一些事情必须由播放,DTS和PTS决定,也播放器不能在文件中查找。
可选地,可以使用来自m4v流的原始naul来构造rtmp流。
如果你想进一步讨论,你可以直接联系我。
你如何获取数据。
因为你无论如何都要在接收端重建文件,我想你可以对它进行分割,史蒂夫麦克法林写了一个小appleSegmentedEcorder,你可以在他的github页面上找到,这解决了moov原子的一些问题,因为你有所有的文件信息。
发布于 2013-01-28 16:37:19
您可以使用碎片MP4。构建一个零碎的MP4文件如下所示:
moov [moof mdat]+moov框则只包含有关轨迹的基本信息(数量、类型、编解码器初始化等),而不包含有关轨迹中采样的信息。有关样品位置和样品大小的信息在moof框中,每个moof框后面都有一个mdat,其中包含前面的moof框中描述的样品。通常,人们会选择(moof,mdat)-pair的长度在2,4或8秒左右(没有详细说明,但这些值对于大多数用例似乎都是合理的)。
这是一种构造永无止境的MP4流的方法。
发布于 2012-10-23 17:11:15
不,它不仅仅是很长的长度..您需要知道每个帧的确切大小才能在mp4中创建标头。这就是为什么它在最后由不同的编码器创建。
https://stackoverflow.com/questions/13010530
复制相似问题