сегмент ffmpeg по времени видео, а не по времени стены

сегмент ffmpeg по времени видео, а не по времени стены

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

У меня возникли проблемы с освоением ffmpeg.

Фон:

Видео захватывается непрерывно в одном потоке с URL-адреса rtsp://, предоставленного подключенной камерой, с помощью этой команды:

ffmpeg -i rtsp://192.168.0.10/h264 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -segment_atclocktime 1 -strftime 1 /tmp/capture-%s.mp4

Это работает и создает видеофайлы продолжительностью 15 минут, как и ожидалось.

Проблема:

В лаборатории у меня нет ни камеры, ни потока rtsp://. Вместо этого я скопировал один из захваченных MP4 из реальной системы и использую его в качестве входных данных для ffmpeg. Что-то вроде:

ffmpeg -stream_loop -1 -i capture-1469547000.mp4 -c copy -map 0 -f segment **-{NEED PARAM}** -segment_format mp4 -strftime 1 /tmp/captest-%s.mp4

Параметр -stream_loop -1делает то, что и ожидалось: он считывает данные из входного файла (длительностью 15 минут) и создает бесконечный выходной поток. Это разумное приближение чтения из потока rtsp://.

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

Попытка №1

Использование, -segment_time 900похоже, либо a) хочет использовать значение настенных часов в 15 минут, либо b) игнорируется. Поскольку копирование из существующего MP4 намного быстрее, чем копирование из потока rtsp://, полученный файл захвата представляет собой много-много копий оригинала.

Попытка №2

Я использовал эту команду

ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 capture-1469547000.mp4

чтобы определить, что входной файл содержит 13494 кадра.

Использование, -segment_frames 13494по-видимому, игнорируется, а вывод вообще не сегментируется.

Попытка №3

Я прочитал кучу документации по ffmpeg и либо не нашел то, что мне нужно, либо этого не существует.

Использование -ss *position* -t *duration*не обеспечивает непрерывную запись и сегментацию выходных данных.

Запрос о помощи

Какие параметры следует использовать, чтобы сегментация а) работала и б) продолжительность видео составляла 15 минут?

Возможные осложнения

Временные метки (DTS?) в примере MP4 не являются «хорошими», поскольку эта ошибка возникает постоянно:

[сегмент @ 0x2abc7c0] Немонотонный DTS в выходном потоке 0:0; предыдущее: 80990160, текущее: -74730276972; изменяется на 80990161. Это может привести к неправильным временным меткам в выходном файле.  
DTS 191648787, следующий:-830336344130 st:0 недопустимый сброс  
PTS 191648787, следующий:-830336344130 недействительный сброс st:0

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

Дополнительная информация

версия ffmpeg:

\# /usr/share/local/bin/ffmpeg -версия  
ffmpeg версия N-79587-g9f9c833 Авторские права (c) 2000-2016 разработчики FFmpeg  
собрано с помощью gcc 4.8 (Ubuntu/Linaro 4.8.2-16ubuntu4)  
конфигурация: --prefix=/home/t/dev/j/third-party/ffmpeg/../build --cross-prefix=/usr/bin/arm-linux-gnueabihf- --cpu=armv7-a --disable-shared --enable-static --enable-gpl --enable-pthreads --enable-nonfree --enable-libx264 --enable-filters --extra-libs=-static --extra-cflags=--static --enable-cross-compile --target-os=linux --disable-inline-asm --arch=armv7 --disable-debug --disable-altivec --disable-sse --disable-armv6 --disable-armv6t2 --disable-mmx --disable-neon --disable-amd3dnow --disable-thumb --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/../build/lib --extra-cflags=-I/home/t/dev/j/сторонний/ffmpeg/../build/include --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libavcodec --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libavdevice --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libavfilter --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libavformat --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libavresample --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libavutil --extra-ldflags=-L/home/t/dev/j/сторонний/ffmpeg/libswscale --extra-ldflags=-lx264 --extra-ldflags=-lm --extra-ldflags=-ldl --extra-cflags='-fpic -mthumb'  
libavutil 55. 22.101 / 55. 22.101  
libavcodec 57.38.100 / 57.38.100  
libavformat 57. 34.103 / 57. 34.103  
libavdevice 57. 0.101 / 57. 0.101  
libavfilter 6. 44.100 / 6. 44.100  
libswscale 4. 1.100 / 4. 1.100  
libswresample 2. 0.101 / 2. 0.101  
libpostproc 54. 0.100 / 54. 0.100

решение1

segment_timeдолжно работать. Это относится к длительности сегмента, а не к настенным часам.

Расположение ключевого кадра может мешать, поэтому попробуйте

ffmpeg -fflags +genpts -i capture-1469547000.mp4 -c copy -map 0 -f segment -segment_time 900 -segment_format mp4 -break_non_keyframes 1 -strftime 1 /tmp/capture-%s.mp4

I've removed the stream_loop option since there's currently a timestamp generation bug related to its use. That may be interfering here as well.

Если вам нужен действительно длинный поток для работы, используйте демультиплексор concat.

Создать текстовый файл

file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'
file 'capture-1469547000.mp4'

И затем используйте

ffmpeg -f concat -i list.txt -c copy ...

решение2

У меня есть работающее решение.

Основная причина

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

Решение

Я побежал

ffmpeg -i capture-1469547000.mp4 -c copy captemp.mp4

Используя captemp.mp4вместо этого я получаю хороший поток либо с помощью stream_loop, либо с помощью concat muxer.

Я не уверен, в чем разница между capture-1469547000.mp4 и captemp.mp4; AtomicParsley показывает, что captemp.mp4 на 12 байт короче в атоме «elst».

Еще раз взглянув на свою изначальную настройку, и добавив, segment_listя обнаружил: сегменты генерировались правильно, но очень-очень быстро. Они просто добавлялись к существующему файлу сегмента вместо создания нового. Это отчасти вина...

потенциальная ошибка strftime

Я использовал strftimeс %sформатом. strftime, как оказалось, использовал время часов хост-машины, а не время из видеосегмента. Это верно даже в «рабочем» случае; я переключился на использование %dформатирования сегментного мультиплексора.

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

Я почти уверен, что использование -reфлага обойдет эту проблему, замедлив обработку, но на самом деле я хочу ускоренную обработку. Поэтому я этого не пробовал.

Связанный контент