У меня проблемы с поиском клиентского приложения, которое может взять видеофайл (желательно avi, mkv и mp4) и вырезать очень короткие клипы (2-6 секунд) с точностью до времени. Я пробовал ffmpeg, mencoder, avidemux и mp4box, но все они вырезаны на ключевых кадрах, которые создают более 6 секундных клипов. Есть ли инструмент, который перекодирует входной файл и сокращает точное время или неточно, повторно кодирует, а затем точно вырезает?
3 ответа
Нарезка видео с помощью ffmpeg
Вы можете точно вырезать видео с помощью FFmpeg. С версии 2.5 это очень просто. Это, например, сократит 10 секунд, начиная с 0 минут, 3 секунд и 123 миллисекунд.
ffmpeg -ss 00:00:03.123 -i input.mp4 -t 10 -c:v libx264 -c:a aac -strict experimental out.mp4
Положение и время могут быть в секундах или в hh:mm:ss[.xxx]
.
Обратите внимание, что в этих примерах видео и аудио будут перекодированы с использованием кодеров x264 и aac .
Вы также можете использовать -to
вместо -t
чтобы указать конечную точку вместо продолжительности. В этом случае, однако, -to
эквивалентно -t
, так как, поместив -ss
перед -i
, ffmpeg сначала будет искать эту точку, а затем начнет выводить.
Смотрите также статью в поиске вики.
Точная резка для старых версий ffmpeg
Если у вас более старая версия ffmpeg, то для точного поиска вам нужно поместить -ss
после -i
, что делает процесс кодирования немного медленнее, потому что сначала нужно декодировать все видео:
ffmpeg -i input.mp4 -ss 00:00:03.123 -t 10 -c:v libx264 -c:a aac -strict experimental out.mp4
Здесь -to
и -t
ведут себя по-разному. -t 10
создаст клип длиной десять секунд, а -to 10
создаст клип длиной семь секунд.
Потоковое копирование или перекодирование
Вы можете попробовать скопировать аудиопоток с помощью -c:a copy
. Копирование видеопотока может быть выполнено с помощью -c:v copy
. Однако он может работать неправильно, потому что вы можете вырезать только ключевые кадры видео, что происходит не так часто. В любом случае это может привести к неточной обрезке при копировании видеопотока.
Как сказал Baodad в комментариях (я публикую пост, потому что его нелегко найти, если вы читаете быстро), лучший способ - автоматически определять аудио / видео кодеры с помощью ffmpeg, поэтому:
ffmpeg -ss 00:05:17.18 -i in.mp4 -t 00:06:29.10 -acodec copy -vcodec copy out.mp4
- начало @ 00:05:17.18
- input = in.mp4
- остановка @ 00:06:29.10
- выход = out.mp4
Единственный инструмент командной строки Linux, который я нашел до сих пор, который может вырезать с точным кадром (или, с точностью до кадра), это melt
(sudo apt-get install melt
).
Скажем, у вас есть inputvid.mp4
- сначала проверьте его настройки кодирования с помощью, скажем, ffmpeg
(здесь я просто говорю, что хочу снова закодировать его в -f mp4
, но как файл /dev/null
поэтому вывод отбрасывается; я перенаправляю stderr так что я могу просмотреть его - обратите внимание на середину, командную строку, и вы должны ответить y
с помощью ENTER, чтобы процесс продолжился и вывел полезную информацию (это с ffmpeg 3.3.3 в Ubuntu 14):
ffmpeg -i inputvid.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder'
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x360 [SAR 1:1 DAR 16:9], 389 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 95 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
encoder : Lavf57.71.100
Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p(progressive), 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
encoder : Lavc57.89.100 libx264
Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s (default)
encoder : Lavc57.89.100 aac
Итак, мы можем видеть, что ffmpeg
выбирает libx264
и aac
для этого видео; тогда мы можем ввести это для melt
:
melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac vcodec=libx264
.... и melt
разрезает кусок между кадрами 7235 и 7349 в новый файл, cut.mp4
. Затем, чтобы проверить правильность циклов cut.mp4
, снова используйте melt
чтобы воспроизвести его дважды - и воспроизведите в окне SDL:
melt cut.mp4 cut.mp4 -consumer sdl
... и вот что ffmpeg
видит для этого файла:
ffmpeg -i cut.mp4 -f mp4 /dev/null 2>&1 | grep 'Stream\|encoder' encoder : Lavf54.20.4
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x360 [SAR 1:1 DAR 16:9], 526 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default)
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 182 kb/s (default)
y
File '/dev/null' already exists. Overwrite ? [y/N] Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
encoder : Lavf57.71.100
Stream #0:0(und): Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=-1--1, 23.98 fps, 24k tbn, 23.98 tbc (default)
encoder : Lavc57.89.100 libx264
Stream #0:1(und): Audio: aac (LC) ([64][0][0][0] / 0x0040), 48000 Hz, stereo, fltp, 128 kb/s (default)
encoder : Lavc57.89.100 aac
Настройки кодирования видео для cut.mp4
похоже, идентичны inputvid.mp4
за исключением того, что битрейт видео изменен с 389 кбит / с до 526 кбит / с, а также настройки кодирования аудио практически одинаковы, за исключением того, что частота дискретизации изменилась с 44100 до 48000 Гц; хотя это можно регулировать с помощью:
melt inputvid.mp4 in=7235 out=7349 -consumer avformat:cut.mp4 acodec=aac ar=44100 ab=95k vcodec=libx264 vb=389k
... однако, даже с этим, окончательный битрейт видео для меня заканчивается 337 кбит / с. Тем не менее, цикл обрезки прекрасно (и включает в себя аудио) при воспроизведении в цикле, так что я думаю, что это действительно с точностью до кадра ...