简体   繁体   English

使用gstreamer分割/分割视频流

[英]splitting / segmenting video stream with gstreamer

Is there a way to split a video into segments of specified length? 有没有一种方法可以将视频分成指定长度的片段? Ie 60 minute video into 12x5 mins. 即将60分钟的视频转换为12x5分钟。

It seems the "official" way to do this without reencoding and without losing frames is using the splitmuxsink element: 似乎在不splitmuxsink且不丢失帧的情况下使用“官方”方法是使用splitmuxsink元素:

For example for a MKV file input: 例如,对于MKV文件输入:

gst-launch-1.0 filesrc location=input.mkv ! matroskademux ! h264parse ! splitmuxsink location=file%02d.mkv max-size-time=300000000000 muxer=matroskamux

The max-size-time gives the segment length in nanoseconds (sic), so the above value is 5 minutes. max-size-time以纳秒(sic)为单位给出段长度,因此上述值为5分钟。 Because it cuts on keyframes, the real segment length will not be exactly 5 min but will vary by a few seconds. 由于它会切入关键帧,因此实际片段的长度将不会精确到5分钟,而是会变化几秒钟。

Afaik, you will need to develop your own "segmenter". Afaik,您将需要开发自己的“细分工具”。 This is similar to what you need to create HTTP Live streaming files. 这类似于创建HTTP Live流文件所需的内容。 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). 您可以使用multifilesink next-file = buffer(或next-file标记,如果段无法容纳在内存中)来制作一个相对较小的程序(在python中)。

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). 重新初始化多路复用器(或追加多路复用器streamheader)以获取具有正确标题的文件,该文件头要比可以单独播放的文件正确(取决于多路复用器)。

gnonlin and gnlfilesource are made for this. gnonlingnlfilesource而制作。 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. 您必须将视频转码作为流程的一部分,因为gstreamer并不支持不进行转码就分割某些格式的特殊支持。

See How do I use gstreamer to make an audio clip from a segment of a longer source? 请参阅如何使用gstreamer从较长源的片段中制作音频剪辑? for an example of how to make clips from an audio file. 有关如何从音频文件制作剪辑的示例。

I was able to accomplish something similar using Perl with the GStreamer and GLib bindings. 使用Perl和GStreamer和GLib绑定,我能够完成类似的工作。 My hack abuses the GStreamer Pipeline state in order to reset the filesink's location. 我的黑客滥用GStreamer管道状态以重置文件接收器的位置。 I use a streaming source and hence the reset to zero behavior after set_state('null') is acceptable. 我使用流媒体源,因此在set_state('null')之后可以将行为重置为零。 You will need to manage the seek position in your source element in order to support proper segmentation. 您将需要管理源元素中的搜索位置,以支持正确的细分。

my $g_pipeline = GStreamer::Pipeline->new('pipeline');
....
my $g_filesink  = GStreamer::ElementFactory->make(filesink  =>  "filesink");
$g_filesink->set(location => $file_name);
...
$g_pipeline->add(..., $g_filesink);

my $delay = 5000; # switch output file at this interval
my $timer = Glib::Timeout->add( $delay, 
  sub {
    $g_pipeline->set_state('null');
    ...
    $g_filesink->set(location=> $next_file_name);
    $g_pipeline->set_state('playing');
  }
);

FFMPEG has a built in segment demuxer. FFMPEG具有内置的段解复用器。

check the -segment option n the documention. 检查文档中的-segment选项。

http://ffmpeg.org/ffmpeg.html#segment http://ffmpeg.org/ffmpeg.html#segment

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM