2

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

У меня проблемы с приручением 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 может либо а) хотеть использовать значение настенных часов 15 минут, либо б) игнорироваться. Поскольку копирование из существующего 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* не делает непрерывной записи и сегментации выходных данных.

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

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

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

Отметки времени (DTS?) в примере MP4 не «хороши» тем, что эта ошибка постоянно возникает:

[segment @ 0x2abc7c0] Non-monotonous DTS in output stream 0:0; previous: 80990160, current: -74730276972; changing to 80990161. This may result in incorrect timestamps in the output file.  
DTS 191648787, next:-830336344130 st:0 invalid dropping  
PTS 191648787, next:-830336344130 invalid dropping st:0

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

Дальнейшая информация

версия ffmpeg:

\# /usr/share/local/bin/ffmpeg -version  
ffmpeg version N-79587-g9f9c833 Copyright (c) 2000-2016 the FFmpeg developers  
built with gcc 4.8 (Ubuntu/Linaro 4.8.2-16ubuntu4)  
configuration: --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/third-party/ffmpeg/../build/lib --extra-cflags=-I/home/t/dev/j/third-party/ffmpeg/../build/include --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavcodec --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavdevice --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavfilter --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavformat --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavresample --extra-ldflags=-L/home/t/dev/j/third-party/ffmpeg/libavutil --extra-ldflags=-L/home/t/dev/j/third-party/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

2 ответа2

0

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

Я удалил параметр stream_loop, так как в настоящее время существует ошибка генерации метки времени, связанная с его использованием. Это может мешать и здесь.

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

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

Коренная причина

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

Решение

Я побежал

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

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