Використовуючи ffmpeg для вирізання відео


333

Я використовую ffmpeg, щоб вирізати розділ великого файлу на зразок цього:

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

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

Чи можна за допомогою ffmpeg відрізати кінець відео, не перекодуючи його?


1
цей синтаксис правильний.
jiggunjer

Відповіді:


393

Ви можете скористатися -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, ймовірно, дуже застарів. Складіть нову версію самостійно або завантажте статичну збірку зі своєї домашньої сторінки. Це справді не складно.


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 секунд після цього:" <- Що це означає? Під кліпом ви маєте на увазі включити? 'cos кліп може означати кліп. Припускаючи, що ви маєте на увазі включити. Ви маєте на увазі Почати з 30 секунд, і включити звідти всього 10 секунд? Якщо так, то я пропоную вам написати, що це було б набагато зрозуміліше.
барлоп

94

Як згадували інші люди, -ssвелике значення має те , що ставити перед (набагато швидше) або після (більш точним) -i. У розділі "Швидкий і точний пошук" на сторінці пошуку ffmpeg розповідається, як отримати обидва, і я використав це, і це має велику зміну. В основному ви ставите -ssперед І після -i, просто переконайтеся, що залиште достатньо часу до того, де ви хочете почати різати, щоб мати ще один ключовий кадр. Приклад: Якщо ви хочете зробити 1-хвилинний кліп, від 9min0sec до 10min 0sec у Video.mp4, ви можете зробити це швидко і точно, використовуючи:

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

Перший -ssшукає швидко (приблизно) 8min0sec, а потім другий -ssпрагне точно до 9min0sec, і -t 00:01:00знімає кліп 1min0sec.

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

Це означає, що вам потрібно перекодувати відео, навіть якщо ви хочете просто скопіювати його, або ризикуєте бути розбитим і синхронізованим. Ви можете спробувати лише -c copyспочатку, але якщо відео смокче, вам потрібно буде це зробити ще раз.


те саме попередження стосується -c:a copyцього способу пошуку.
jiggunjer

1
Найкраща відповідь, цей спосіб працював найкраще для мене.
Ondra Žižka

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"

Тепер зробіть txt-файл із відеофайлами із вмістом, як-от:

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"

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

Як і у користувачеві225366, опція -t не працює для коротких відео, але для довших відео. Для коротких відео схоже, що -frames: v краще. Це те, що працювало для мене.

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

-кодек-копію потрібно додати, якщо відео має аудіо, як показують інші відповіді.


0

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

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

З собою -map 0ви берете всі потоки у файл, а -c copyви копіюєте їх усі, як вони є.
Використання -toпропуску пуску через -ssперерізає вхідне відео від початку до другого 60.

Fiddling з mapкорисним також, якщо ви хочете, щоб у розрізі зберігалися лише певні потоки (можливо, вам не потрібні всі джерела звуку у файлі або лише деякі субтитри).

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.