2013-06-19 3 views
1

У меня есть рабочая программа, построенная сверху libav (альтернативно ffmpeg - экспертиза также полезна здесь).Remux и сегментные части видеофайла без разницы в выходе

Требуется видео mp4, закодированное с аудио/видео AAC h264, и переводит его в MPEG TS и сегментирует его на X вторых фрагментов. Она аналогична следующей FFmpeg команды:

ffmpeg -y -i video.mp4 -c:a copy -bsf:a aac_adtstoasc -c:v copy -bsf:v h264_mp4toannexb -flags -global_header -map 0 -f segment -segment_time 10 -segment_list playlist.m3u8 -segment_format mpegts chunk_%03d.ts 

Причина я не с помощью командной строки, является то, что я хочу, чтобы генерировать только часть сегментов. Поэтому, если видео приводит к 10 сегментам от 8 до 12 секунд (сегменты никогда не являются точно требуемой длиной из-за ключевых кадров), я могу захотеть генерировать сегменты 3-7 позднее.

Полный код программы можно найти here.

Я использую av_read_frame, чтобы читать каждый кадр из исходного файла, remux (включая процесс bitfilter) и записывать в выходной файл. Как только продолжительность с последнего выхода становится близкой/большей, чем желаемая длина сегмента, я очищаю выходной файл, закрываю его, открываю следующий сегмент и продолжаю.

Я попытался изменить код, чтобы сделать av_seek_frame до конца первого сегмента и начать с него (я также попытался начать в конце 2-го и 3-го сегментов). Новые сегменты имеют одинаковую длину (в секундах и очках), но имеют разный размер, чем сопоставимые сегменты от полного прогона (в пределах нескольких килобайт) - начальный сегмент (будь то второй, третий или другой) также отображается как с 2 пакетами МЕНЬШЕ, чем сопоставимый сегмент ранее.

Я предположил, что av_seek_frame дал бы мне точное совпадение, как если бы я вручную выполнил цикл с av_read_frame до этого кадра, но похоже, что это не тот случай.

Я желаю:

  • Пути к «быстрой перемотке вперед» в файл для специфического (не приблизительных) точек в файле.
  • Чтобы записать с этой точки вперед и иметь выход, полностью идентичный выходу, полный прогон обеспечивает (тот же размер, ту же длину, точные точные байты).

ответ

0

мне удалось заставить его работать, выполнив следующие действия:

  • обратиться к биту (1000 DTS) до фактического ключевого кадра находится.
  • Позвоните av_read_frame в цикле, пока мы не достигнем ключевого кадра.
  • Написать заголовок и трейлер для каждого сегмента (avformat_write_header, av_write_trailer)

Конечным результатом является то, что я могу начать в данной временной метки, где я знаю, что сегмент собирается начать и иметь те сегменты, созданные (и остановитесь на любом сегменте, который я желаю, но это тривиально). Полученные сегменты идентичны тем, которые созданы в полном прохождении.

1

Искание обычно неточно и приведет вас только к пунктам, указанным в индексе файла (как правило, ключевыми кадрами видео). Вы можете попробовать искать с флагом AVSEEK_FLAG_BACKWARD, искать до указанной точки, а затем читать + отбрасывать оттуда.

В качестве альтернативы вы можете посмотреть на FFMS2, который предположительно обеспечивает обертку более высокого уровня вокруг функций libav с поиском кадров.

+0

Я ищу ключевые фреймы, поэтому, хотя это было бы точно. FFMS2 звучит интересно, и, учитывая отсутствие документации для libav, это может быть моя спасительная грация. Благодаря! –

+0

FFMS2 действительно выглядит красиво, но кажется, что он читает только - нет записи/мультиплексирования. API гораздо приятнее работать, хотя :) –