разделение / сегментирование видеопотока с помощью gstreamer - PullRequest
2 голосов
/ 26 января 2011

Есть ли способ разбить видео на сегменты указанной длины?Т.е. 60-минутное видео в 12x5 минут.

Ответы [ 5 ]

1 голос
/ 05 мая 2018

Кажется, что "официальный" способ сделать это без перекодирования и без потери кадров - использовать элемент 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 минут, а будет меняться на несколько секунд.

1 голос
/ 22 февраля 2011

gnonlin и gnlfilesource созданы для этого.Вам придется перекодировать видео как часть процесса, поскольку gstreamer не имеет специальной поддержки для разделения определенных форматов без перекодирования.

См. Как использовать gstreamer для создания аудиоклипа из сегментаболее длинный источник? для примера того, как сделать клипы из аудиофайла.

1 голос
/ 10 февраля 2011

Афаик, тебе нужно будет разработать свой собственный "сегментатор". Это похоже на то, что вам нужно для создания потоковых файлов HTTP Live. Возможно, есть более простое решение, но вот что я бы сделал:

Вы можете создать относительно небольшую программу (в Python), используя multifilesink next-file = buffer (или маркер следующего файла, если сегменты не помещаются в памяти).

Вам нужно будет кодировать или демультиплексировать ваш входной поток и вернуть поток обратно. Отрежьте мультиплексированный поток по ключевому кадру, когда будет достигнута желаемая длительность, и нажмите объединенный буфер (или отметьте поддельный ключевой кадр, например, чтобы заставить приемник создать новый файл). Повторно инициализируйте мультиплексор (или добавьте потоковый заголовок мультиплексора), чтобы получить файл с правильным заголовком, который можно воспроизводить отдельно (в зависимости от мультиплексора).

0 голосов
/ 07 февраля 2012

FFMPEG имеет встроенный демультиплексор сегмента.

проверьте параметр -segment в документации.

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

0 голосов
/ 26 июля 2011

Мне удалось сделать нечто подобное, используя 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');
  }
);
...