Использование ffmpeg для разрезания видео

333

Я использую ffmpeg, чтобы вырезать раздел большого файла следующим образом:

ffmpeg -i input.wmv -ss 60 -t 60 -acodec copy -vcodec copy output.wmv

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

Есть ли способ использовать ffmpeg, чтобы обрезать конец видео без его перекодирования?

Нил
источник
1
этот синтаксис правильный.
Jiggunjer
1
stackoverflow.com/questions/18444194/…
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件

Ответы:

394

Вы можете использовать -ssопцию, чтобы указать начальную метку времени, и -tопцию, чтобы указать длительность кодирования. Метки времени должны быть в HH:MM:SS.xxxформате или в секундах ( s.msec).

Следующий код обрезает первые 30 секунд, а затем обрезает все, что происходит через 10 секунд:

ffmpeg -ss 00:00:30.0 -i input.wmv -c copy -t 00:00:10.0 output.wmv
ffmpeg -ss 30 -i input.wmv -c copy -t 10 output.wmv

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

Несколько советов:

  • Для более старых версий ffmpeg, если вы используете -ssпосле -i, вы получите более точный поиск за счет более медленного выполнения в целом. Смотрите также: Ищу с FFmpeg
  • Вы можете использовать -toвместо, -tчтобы указать временную метку, к которой вы хотите сократить. Таким образом, вместо -i <input> -ss 30 -t 10вас также можно сделать -i <input> -ss 30 -to 40то же самое.

  • Если ваш ffmpeg не поддерживает -cили -to, скорее всего, он сильно устарел. Соберите новую версию самостоятельно или загрузите статическую сборку с их домашней страницы. Это действительно не сложно.

slhck
источник
1
@Mondain На самом деле, вы получите больше точности, поставив -ss после. И slhck упоминает об этом здесь blog.superuser.com/2012/02/24/… также в документации ffmpeg для -ss, где упоминается разница между размещением до или после.
Барлоп
5
+1 Я пришел сюда, чтобы выяснить, как игнорировать все после первых 35 секунд, спасибо:ffmpeg -i input.wmv -c copy -t 35 output.wmv
karlphillip
2
Это не работает для меня (mp4). Он просто производит 5 секундный черный экран:frame= 150 fps=0.0 q=-1.0 Lsize= 264kB time=00:00:09.97 bitrate= 216.6kbits/s
часовщик
2
Это произвело 3-4 с черного экрана в начале моего видеоклипа. Модификация Криса с пропуском -c copyубрала начальный черный экран, подробности смотрите в его ответе.
Joelostblom
4
Вы пишете «Следующее обрезает первые 30 секунд, а затем обрезает все, что происходит через 10 секунд после этого:» <- Что это значит? Под клипом вы подразумеваете включение? потому что клип может означать клип. Предполагая, что вы имеете в виду включить. Вы имеете в виду начать с 30 секунд и включить всего 10 секунд? Если так, то я предлагаю вам написать, что это будет намного понятнее.
Барлоп
95

Как уже упоминалось, размещение -ssдо (гораздо быстрее) или после (более точно) -iимеет большое значение. В разделе «Быстрый и точный поиск» на странице поиска ffmpeg рассказывается, как получить оба, и я их использовал, и это имеет большое значение. В основном, вы ставите -ssдо и после -i, просто оставьте достаточно времени до того места, где вы хотите начать резку, чтобы получить еще один ключевой кадр. Пример: если вы хотите сделать 1-минутный клип, от 9 минут 0 секунд до 10 минут 0 секунд в Video.mp4, вы можете сделать это быстро и точно, используя:

ffmpeg -ss 00:08:00 -i Video.mp4 -ss 00:01:00 -t 00:01:00 -c copy VideoClip.mp4

Первый -ssищет быстро (приблизительно) 8 минут 0 секунд, а затем второй -ssищет точно 9 минут 0 секунд, а -t 00:01:00клип вынимает 1 минут 0 секунд.

Также обратите внимание на этот важный момент на этой странице: «Если вы используете -ssс -c:v copy, результирующий битовый поток может оказаться прерывистым, не воспроизводимым или не синхронизированным с аудиопотоком, поскольку ffmpeg вынужден использовать / разбивать только на i-кадры. "

Это означает, что вам нужно перекодировать видео, даже если вы хотите просто скопировать его или рискнуть быть нестабильным и не синхронизированным. Вы можете попробовать только -c copyсначала, но если видео отстой, вам нужно будет сделать это заново.

seriesoftubes
источник
то же самое предупреждение относится к -c:a copyэтому способу поиска.
Jiggunjer
1
Лучший ответ, этот способ работал лучше для меня.
Ондра Жижка
3
Кажется, что "-ss" теперь быстрый и точный в ffmpeg 2.1+ без указания его дважды. trac.ffmpeg.org/wiki/Seeking
Конрад Мейер
25

Я обнаружил, что в -ssсочетании с -c copyрезультатом получилось полсекундная отбивная на старте.

Чтобы избежать этого, вы должны удалить -c copy(который по общему признанию сделает транскод).

Крис
источник
4
Есть еще один ответ, который касается точности. Перекодирование с опцией по умолчанию часто НЕ то, что вы хотите сделать!
Томаш Гандор
Хороший вопрос @TomaszGandor
Крис
1
Я вообще не понял ответа @ TomaszGandor, но удаление -c copyисправило его.
Юлиан Онофрей
14

ВРУЧНУЮ

Откройте файл в медиаплеере, который будет перемещаться по кадрам, и воспроизведите файл AVISynth с такими данными, как:

DirectShowSource(("C:\Downloads\Video\Do you want him.flv"), Pixel_Type="yuy2").Crop(0,0,-0,-0)
Subtitle("C:\Downloads\Video\Do you want him.flv", font="Arial", size=24, text_color=$ff0000, align=3)
ShowFrameNumber(scroll=true, x=336, y=27, font="Arial", size=24, text_color=$ff0000)
ShowTime(x=398, y=44, font="Arial", size=24, text_color=$ff0000)

Затем вырезать с точным форматом времени:

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:05.240 -to 00:00:08.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him1.flv"

а также

ffmpeg -i "Path\do you want him.flv"        \
       -ss 00:00:10.240 -to 00:00:14.360    \
       -vcodec libx264 -acodec libvo_aacenc \
       "Path\Do you want him2.flv"

Теперь создайте текстовый файл с видеофайлами с таким содержимым, как:

file 'C:\Downloads\Video\Do you want him1.flv'
file 'C:\Downloads\Video\Do you want him2.flv'

Запустите ffmpeg:

ffmpeg -f concat -i FileList.txt -c copy "Path\NewName_joined.flv"
Budman1
источник
9

У меня -tвариант не работал, но -vframesработал. Я предпочитаю использовать #frames, так как я бы предпочел использовать I-Frames и узнал GOP для использования видео ffprobe.

Командная строка, которая работала для меня:

ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv

Между прочим, размещение -ssво фронте -iимеет большое значение во времени выполнения.

Бен
источник
1
На самом деле -vframes(или -frames:v) должно следовать после, -iпотому что это опция вывода.
Slhck
5

Как и в случае с user225366, опция -t не работает для коротких видео, но она подходит для более длинных видео. Для коротких видео кажется, что -frames: v лучше. Это то, что сработало для меня.

ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy output.mp4

Копия -acodec должна быть добавлена, если у видео есть аудио, как показывают другие ответы.

VectorVortec
источник
0

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

ffmpeg -to 60 -i input.mkv -map 0 -c copy output.mkv

С -map 0вас берут все потоки в файле, а с -c copyсобой копируют все их как есть.
Если -toпропустить начало через, -ssвы обрежете входное видео с начала до 60 секунд.

Работа с mapним полезна также в том случае, если вы хотите, чтобы в разрезе содержались только определенные потоки (возможно, вам не нужны все аудиоисточники в файле или только некоторые субтитры).

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

Gruber
источник