1

Используя FFMPEG, как вы можете разбить видео на сегменты равной длины, которые МОГУТ ИЛИ МОГУТ НЕ запускаться на ключевых кадрах?

Предполагая, что вы знакомы с форматом сегмента и опцией break_non_keyframes , FFMPEG, кажется, НЕ делает то, что я ожидал (из того, что я прочитал ... больше не могу найти ссылки).

ffmpeg -i ...  -f segment -break_non_keyframes 1 -segment_time 2 -c copy 2secs%03d.ts

А именно, создайте сегмент, который на самом деле может быть длиннее желаемого сегмента, включая всю GOP по мере необходимости.

Например, предположим, что 3-кадровая GOP с глупой частотой кадров 1 FPS со следующей глупой каденцией IBP:

 01 02 03 11 12 13 21 22 23 31 32 33
  I  B  P  I  B  P  I  B  P  I  B  P

Если я хочу разбить его на 2-секундные сегменты, можно ожидать, что будут генерироваться следующие сегменты (кадры в скобках не должны отображаться в этом сегменте):

01 02 03  (03 not displayed in this segment, only used for decoding)
01 02 03 11 (... 01 and 02)
11 12 13  (... 11 )
21 22 23  (... 23)
21 22 23 31 (...21 22)
31 32 33  (... 31)

Как вы можете видеть, в каждом сегменте будут дополнительные кадры, но с учетом начального PTS и, наконец, конечного PTS, вы ВСЕГДА можете воспроизводить / транскодировать только сегмент самостоятельно.

Это действительно расточительное пространство (сумма сегментов будет НАМНОГО больше, чем первоначальный актив), но здесь дело не в этом. Дело в том, чтобы иметь автономные сегменты без транскодирования.

2 ответа2

3

Сожалею, что это невозможно с текущим сегментным мультиплексором. Опция break_non_keyframes предназначена для таких случаев, как HLS, где многие проигрыватели рассматривают сегменты как непрерывный поток пакетов, поэтому разделение справочных данных по нескольким файлам не является проблемой.

Мне любопытно, каков ваш настоящий вариант использования здесь. Где вам нужны сегменты фиксированной длины, каждый из которых должен декодироваться как полностью независимый файл? Я сомневаюсь, что большинство игроков справятся с этим так, как вы хотите; при отсутствии ссылочной картинки игроки часто отображают зеленые или серые артефакты, а не опускают кадр.

Кроме того, ваш темп IBP немного вводит в заблуждение. Предполагая, что ваши номера кадров имеют порядок отображения, ваши кадры будут фактически упорядочены в потоке IPB/IPB/IPB/IPB.

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

Цитата: Я реализовал настройку break_non_keyframes .

0

Когда я бегу

ffmpeg -i input.mp4 -f segment -c copy -reset_timestamps 1 -segment_time 2 -break_non_keyframes 1 a%02d.mp4

а затем воспроизводить выходные сегменты MP4 с помощью ffplay, многие из них воспроизводятся нормально, несмотря на большое количество сообщений об ошибках. Играется только 2-секундная часть. Немного игры, но с артефактами, т.е. ключевой кадр не был декодирован. Однако, если я установлю время сегмента выше, скажем, 11, то все сегменты будут воспроизводиться так, как вы хотели бы, через ffplay. Это не относится к выходу TS. Кроме того, воспроизведение не работает в обычном плеере, как VLC.

В качестве альтернативы, если я создаю сегмент, используя шаблон ниже

ffmpeg -ss N -t 2 -i input.mp4 -c copy aN.ts

Потплеер сыграл это замечательно - всего 2 секунды, без ошибок. ffplay проиграл все мультиплексированные кадры, без ошибок. VLC сыграл только 2-й сегмент, но с глюками. В моем тесте 229 кадров видео с частотой 30 кадров в секунду были переданы на выход.

tl; dr Различные проигрыватели не ведут себя одинаково с файлами, содержащими кадры с отрицательным DTS/PTS. Какой у вас вариант использования?

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .