[英]splitting / segmenting video stream with gstreamer
有没有一种方法可以将视频分成指定长度的片段? 即将60分钟的视频转换为12x5分钟。
似乎在不splitmuxsink
且不丢失帧的情况下使用“官方”方法是使用splitmuxsink
元素:
例如,对于MKV文件输入:
gst-launch-1.0 filesrc location=input.mkv ! matroskademux ! h264parse ! splitmuxsink location=file%02d.mkv max-size-time=300000000000 muxer=matroskamux
max-size-time
以纳秒(sic)为单位给出段长度,因此上述值为5分钟。 由于它会切入关键帧,因此实际片段的长度将不会精确到5分钟,而是会变化几秒钟。
Afaik,您将需要开发自己的“细分工具”。 这类似于创建HTTP Live流文件所需的内容。 可能有一个更简单的解决方案,但是这是我要做的:
您可以使用multifilesink next-file = buffer(或next-file标记,如果段无法容纳在内存中)来制作一个相对较小的程序(在python中)。
您需要对输入流进行编码或解复用,然后将流复用回去。 当达到所需的持续时间时,在关键帧上剪切多路复用流,然后推动聚合的缓冲区(或标记一个伪造的关键帧,例如,强制接收器创建新文件)。 重新初始化多路复用器(或追加多路复用器streamheader)以获取具有正确标题的文件,该文件头要比可以单独播放的文件正确(取决于多路复用器)。
gnonlin
和gnlfilesource
而制作。 您必须将视频转码作为流程的一部分,因为gstreamer并不支持不进行转码就分割某些格式的特殊支持。
请参阅如何使用gstreamer从较长源的片段中制作音频剪辑? 有关如何从音频文件制作剪辑的示例。
使用Perl和GStreamer和GLib绑定,我能够完成类似的工作。 我的黑客滥用GStreamer管道状态以重置文件接收器的位置。 我使用流媒体源,因此在set_state('null')之后可以将行为重置为零。 您将需要管理源元素中的搜索位置,以支持正确的细分。
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');
}
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.