使用 gstreamer 分割/分段视频流

发布于 2024-10-15 01:08:51 字数 47 浏览 3 评论 0原文

有没有办法将视频分割成指定长度的片段?即 60 分钟的视频变成 12x5 分钟。

Is there a way to split a video into segments of specified length? Ie 60 minute video into 12x5 mins.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(5

好倦 2024-10-22 01:08:51

似乎在不重新编码且不丢失帧的情况下执行此操作的“官方”方法是使用 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< /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:

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. Because it cuts on keyframes, the real segment length will not be exactly 5 min but will vary by a few seconds.

疾风者 2024-10-22 01:08:51

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).

叫嚣ゝ 2024-10-22 01:08:51

gnonlingnlfilesource 就是为此而设计的。作为该过程的一部分,您必须对视频进行转码,因为 gstreamer 不支持在不转码的情况下分割某些格式。

请参阅如何使用 gstreamer 从较长源的片段制作音频剪辑? 有关如何从音频文件制作剪辑的示例。

gnonlin and gnlfilesource 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.

人事已非 2024-10-22 01:08:51

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

暗藏城府 2024-10-22 01:08:51

我能够使用 Perl 与 GStreamer 和 GLib 绑定​​来完成类似的事情。我的黑客滥用了 GStreamer Pipeline 状态来重置文件接收器的位置。我使用流媒体源,因此 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');
  }
);

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.

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