Вопрос или проблема
У меня есть следующая команда для записи mp4 файлов с веб-камеры:
ffmpeg -f video4linux2 -vcodec mjpeg -video_size 1280x720 -i /dev/video0 -f alsa -ac 1 -i hw:2 -g 64 -movflags frag_keyframe+empty_moov -pix_fmt yuv420p -profile:v baseline -vcodec libx264 -crf 35 out.mp4
Файл MP4 фрагментирован, потому что мне нужно делать снимки во время записи. Таким образом, я могу взять последний кадр из видео, которое сейчас записывается, с помощью следующей команды:
ffmpeg -sseof -3 -i out.mp4 -update 1 -q:v 1 out.jpeg
Все работает хорошо. Но теперь я хочу вместо записи одного длинного видео записывать сегменты по 30 минут, что можно легко сделать с помощью следующей команды:
ffmpeg -f video4linux2 -vcodec mjpeg -video_size 1280x720 -i /dev/video0 -f alsa -ac 1 -i hw:2 -g 64 -movflags frag_keyframe+empty_moov -pix_fmt yuv420p -profile:v baseline -vcodec libx264 -crf 35 -segment_time 30:00 -f segment -reset_timestamps 1 -strftime 1 out_%d%m%y_%H%M%S.mp4
Теперь, когда я запускаю команду для получения снимка из последнего видео, она не работает, выдает ошибку:
moov atom not found
Возможно ли записывать MP4 с сегментацией, чтобы я мог также фрагментировать ключевые кадры и делать последний кадр как снимок?
Ответ или решение
Конечно, давайте разберем вашу проблему с записью и сегментацией видео MP4 через ffmpeg, а также рассмотрим возможные пути решения.
Проблема
Вы записываете видео в формате MP4 с веб-камеры, используя команды ffmpeg. Сейчас цель — сегментировать запись на отрезки по 30 минут, сохраняя при этом возможность извлечения последнего кадра из текущего видео. Однако при попытке сделать снимок из видео вы сталкиваетесь с ошибкой «moov atom not found». Это происходит в основном из-за специфики работы с фрагментированными MP4-файлами, в которых структура MOOV атома (важная для индексирования содержания) не всегда находится в начале файла.
Решение
Для решения вашей проблемы я рекомендую несколько шагов и конфигураций:
-
Добивайтесь стабильности видеофайлов:
Используя флажок-movflags +faststart
, вы можете переместить moov-атом в начало файлов. Это полезно для быстрой потоковой передачи и более надежного воспроизведения. Однако это может замедлить процесс записи. -
Фрагментация и сегментация видео:
В вашей команде используется-movflags frag_keyframe+empty_moov
, что позволяет создавать фрагментированные MP4-файлы. Вместе с тем для сегментации вам следует использовать следующую команду:ffmpeg -f video4linux2 -vcodec mjpeg -video_size 1280x720 -i /dev/video0 -f alsa -ac 1 -i hw:2 -g 64 -movflags +faststart+frag_keyframe+empty_moov -pix_fmt yuv420p -profile:v baseline -vcodec libx264 -crf 35 -segment_time 1800 -f segment -reset_timestamps 1 -strftime 1 out_%d%m%y_%H%M%S.mp4
Замечание: Я изменил
segment_time
на значение в секундах (1800 секунд = 30 минут), так как ffmpeg принимает это время именно в секундах. -
Извлечение последнего кадра:
Для предотвращения ошибки при извлечении последнего кадра попробуйте обновить логику вашего скрипта, чтобы он выбирал последний доступный сегмент:latest_file=$(ls -t out_*.mp4 | head -n 1) ffmpeg -sseof -3 -i "$latest_file" -update 1 -q:v 1 out.jpeg
Это bash-скрипт, который извлекает последний сгенерированный файл и использует его для получения снимка.
Заключение
Следуя вышеперечисленным рекомендациям, вы сможете сегментировать ваше видео без потери возможности извлечения последнего кадра. Используйте указанные флаги и команды, чтобы оптимизировать процесс и устранить ошибки с moov-атомом. Это поможет обеспечить надежное воспроизведение и обработку ваших видеофайлов.
Если у вас появятся дополнительные вопросы или нужна будет помощь с настройками ffmpeg, пожалуйста, не стесняйтесь обращаться за профессиональной консультацией.