[英]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.