使用 gstreamer 分割/分段视频流
有没有办法将视频分割成指定长度的片段?即 60 分钟的视频变成 12x5 分钟。
Is there a way to split a video into segments of specified length? Ie 60 minute video into 12x5 mins.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
似乎在不重新编码且不丢失帧的情况下执行此操作的“官方”方法是使用
splitmuxsink
元素:例如,对于 MKV 文件输入:
max-size-time< /code> 给出以纳秒 (sic) 为单位的段长度,因此上述值为 5 分钟。由于它会在关键帧上进行剪切,因此实际片段长度不会正好是 5 分钟,而是会有几秒钟的变化。
It seems the "official" way to do this without reencoding and without losing frames is using the
splitmuxsink
element:For example for a MKV file input:
The
max-size-time
gives the segment length in nanoseconds (sic), so the above value is 5 minutes. Because it cuts on keyframes, the real segment length will not be exactly 5 min but will vary by a few seconds.Afaik,您将需要开发自己的“分段器”。这与创建 HTTP Live 流文件所需的类似。可能有一个更简单的解决方案,但这就是我要做的:
您可以使用 multifilesink next-file=buffer (或下一个文件标记,如果段无法放入内存)制作一个相对较小的程序(在 python 中)。
您需要对输入流进行编码或解复用,然后将流复用回来。当达到所需的持续时间时,剪切关键帧上的混合流,并推送聚合缓冲区(或标记一个假关键帧,例如,以强制接收器创建新文件)。重新初始化复用器(或附加复用器流标头)以获取具有正确标头的文件,以便可以单独播放(取决于复用器)。
Afaik, you will need to develop your own "segmenter". This is similar to what you need to create HTTP Live streaming files. There might be a simpler solution, but here is what I would do:
You can make a relative small program (in python) using multifilesink next-file=buffer (or next-file marker, if segments can't fit in memory).
You'll need to encode or demux your input stream, and mux the stream back. Cut the muxed stream on key-frame when the desired duration is reached, and push the aggregated buffer (or mark a fake key frame, for example, to force sink to create a new file). Reinitialize the muxer (or append muxer streamheader) to get file with correct header than can be played seperately (depending on the muxer).
gnonlin
和gnlfilesource
就是为此而设计的。作为该过程的一部分,您必须对视频进行转码,因为 gstreamer 不支持在不转码的情况下分割某些格式。请参阅如何使用 gstreamer 从较长源的片段制作音频剪辑? 有关如何从音频文件制作剪辑的示例。
gnonlin
andgnlfilesource
are made for this. You will have to transcode the video as part of the process since gstreamer does not have special support for splitting certain formats without transcoding.See How do I use gstreamer to make an audio clip from a segment of a longer source? for an example of how to make clips from an audio file.
FFMPEG 有一个内置的分段解复用器。
检查文档中的 -segment 选项。
http://ffmpeg.org/ffmpeg.html#segment
FFMPEG has a built in segment demuxer.
check the -segment option n the documention.
http://ffmpeg.org/ffmpeg.html#segment
我能够使用 Perl 与 GStreamer 和 GLib 绑定来完成类似的事情。我的黑客滥用了 GStreamer Pipeline 状态来重置文件接收器的位置。我使用流媒体源,因此 set_state('null') 之后重置为零的行为是可以接受的。您将需要管理源元素中的搜索位置,以支持正确的分段。
I was able to accomplish something similar using Perl with the GStreamer and GLib bindings. My hack abuses the GStreamer Pipeline state in order to reset the filesink's location. I use a streaming source and hence the reset to zero behavior after set_state('null') is acceptable. You will need to manage the seek position in your source element in order to support proper segmentation.