是否可以在编码器编码时播放输出视频文件?

发布于 2024-11-15 15:03:22 字数 265 浏览 3 评论 0原文

我有一个视频文件,我需要将其编码为 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

喜爱皱眉﹌ 2024-11-22 15:03:22

是的,这是可能的,但仅限于某些容器格式。 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.

绅士风度i 2024-11-22 15:03:22

也许当 @wombat57 写下他的答案时这是不可能的,但现在是可能的!

您需要 -movflags +frag_keyframe+empty_moov+faststart

正如这个答案中所述,

通常,MOV/MP4 文件将所有数据包的所有元数据存储在一个位置(写在文件末尾,可以通过在 movflags 中添加 faststart 或使用qt-faststart 工具)。分片文件由许多片段组成,其中数据包和有关这些数据包的元数据存储在一起。写入分段文件的优点是,即使写入中断,文件也可解码(而普通 MOV/MP4 如果未正确完成则无法解码),并且在写入很长的文件时需要较少的内存(因为写入普通 MOV /MP4 文件将有关内存中每个数据包的信息存储到文件关闭为止)。缺点是与其他应用程序的兼容性较差。

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,

Normally, a MOV/MP4 file has all the metadata about all packets stored in one location (written at the end of the file, it can be moved to the start for better playback by adding faststart to the movflags, or using the qt-faststart tool). A fragmented file consists of a number of fragments, where packets and metadata about these packets are stored together. Writing a fragmented file has the advantage that the file is decodable even if the writing is interrupted (while a normal MOV/MP4 is undecodable if it is not properly finished), and it requires less memory when writing very long files (since writing normal MOV/MP4 files stores info about every single packet in memory until the file is closed). The downside is that it is less compatible with other applications.

守护在此方 2024-11-22 15:03:22

您可以使用 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

预谋 2024-11-22 15:03:22

我之前也用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文