繁体   English   中英

使用gstreamer分割/分割视频流

[英]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)以获取具有正确标题的文件,该文件头要比可以单独播放的文件正确(取决于多路复用器)。

gnonlingnlfilesource而制作。 您必须将视频转码作为流程的一部分,因为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');
  }
);

FFMPEG具有内置的段解复用器。

检查文档中的-segment选项。

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

暂无
暂无

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

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