是否可以在编码器编码时播放输出视频文件?
我有一个视频文件,我需要将其编码为 H264/AVC 并通过 HTTP 提供给客户端。我需要的是客户端的播放器可以在编码时播放视频。
AFAIK,为了使播放器能够在视频下载时播放,必须将“moovatom”放置在视频文件的开头。然而,编码器(例如:ffmpeg)在完成编码后总是在文件末尾写入“moovatom”。
有什么方法可以让编码器将“moovatom”放在编码输出的开头吗?或者在没有 moovatom 存在的情况下播放视频?
提前感谢
LR
I have a video file, and I need to encode it as H264/AVC and feed to client via HTTP. What i need is that i player at client side can play back the video as it is being encoded.
AFAIK, To enable player to play as the video is downloading, "moov atom" have to be placed at the begnning of the video file. However, encoders (ex: ffmpeg) always write "moov atom" at the end of file after it completes encoding.
Is there any way encoder can put "moov atom" at beginning of encode's output? Or play video without moov atom presence?
Thank in advances
LR
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,这是可能的,但仅限于某些容器格式。 QuickTime/MP4 容器不可能做到这一点。在这些格式中,moov 原子包含样本偏移量(样本在 mdat 原子中的位置)。这些直到视频编码后才知道。通过 VOD(视频点播),您可以获取完成的文件,并将 moov 原子移到前面,以使流媒体工作得更好。但如果您是即时编码,则无法做到这一点。为了实现这一点,您需要使用面向流的传输格式。 FLV 或 MPEG-TS 等格式都可以。如果您将视频传递到 ffmpeg 并告诉它在 FLV 容器中生成 H.264 视频,您就可以将该数据在编码后提供给播放器,并且它会正常工作。当然,如果您想通过 HTTP 提供服务,您可能必须编写自己的服务器(或现有服务器的模块)。据我所知,没有什么支持在写入文件时提供文件服务(问题是发送内容长度标头时不知道文件大小)。但是,如果您通过 RTMP 或 RTSP 提供视频,则可以使用现有软件来实现此操作。
Yes, this is possible, but only in some container formats. It is NOT possible with a QuickTime/MP4 container. In these formats, the moov atom contains sample offsets (the locations of the samples in the mdat atom). These are not known until after the video has been encoded. With VOD (video on demand) you can take the finished file, and move the moov atom to the front, to make streaming work better. But there is no way to do this if you are encoding on the fly. To make that work, you'll need to use a stream-oriented transport format. Something like FLV or MPEG-TS would work. If you pass video into ffmpeg and tell it to produce H.264 video in an FLV container, you can then serve that data to a player as it's encoded, and it will work. Of course, if you want to serve it over HTTP, you'll probably have to write your own server (or module for an existing server). Nothing that I know of supports serving a file as it is written (an issue is that the file size is not known when the content-length header is sent). If you serve the video over RTMP or RTSP, however, you can make this work with existing software.
也许当 @wombat57 写下他的答案时这是不可能的,但现在是可能的!
您需要
-movflags +frag_keyframe+empty_moov+faststart
正如这个答案中所述,
Perhaps it wasn't possible when @wombat57 wrote his answer, but it is possible now!
You want
-movflags +frag_keyframe+empty_moov+faststart
As explained in this answer,
您可以使用 ffmpeg 中名为 qt-faststart 的工具重写文件,将 MOOV Atom 移动到文件的开头。您需要自己从源代码编译它(但至少在 Linux / Mac OS 中相当容易)。只需下载libavcodec的源码即可,例如:
http://libav.org/releases/libav-0.8.tar.xz
解压它并进入工具目录,有一个名为 qt-faststart.c 的文件,只需使用以下命令构建它:
make qt-faststart
您现在可以通过这样调用它来重新分配 MOOV Atom: qt-faststart input.mp4输出.mp4
You can move the MOOV Atom to the beginning of a file by rewriting the file using a tool in ffmpeg called qt-faststart. You will need to compile it yourself from source code (but is quite easy at least in Linux / Mac OS). Just download the source of libavcodec, for example:
http://libav.org/releases/libav-0.8.tar.xz
Untar it and go the tools directory, there is a file called qt-faststart.c, just build it with:
make qt-faststart
you can now reallocate MOOV Atom by calling it like this: qt-faststart input.mp4 output.mp4
我之前也用 ffmpeg 尝试过同样的事情,但没有成功。但使用 vlc,我可以同时在 Android 上下载、转码和流式传输,尽管使用 rtsp。我没有尝试使用http渐进方法。我在vlc中使用了mpeg4视频编解码器、mpega音频编解码器。
I also tried this same thing earlier with ffmpeg, but could not succeed. But with vlc I was able to download, transcode and stream on Android simultaneously, though with rtsp. I did not try with http progressive method. I used mpeg4 video codec, mpega audio codec in vlc.