Як вирізати точні рамки за допомогою ffmpeg?


22

Я намагаюся використовувати ffmpeg для вирізання відеофайлів у точний час. Довідка ffmpeg показує параметр -timecode_frame_start, щоб вказати початковий кадр, але я не в змозі змусити цю команду працювати. Отримане відео завжди починається на початку оригінального відео. Ось приклад команди, яку я виконую:

ffmpeg -i input.mpg -acodec copy -vcodec copy -timecode_frame_start 200 -vframes 210 -n ouput.mpg

Я перемістив параметр timecode_frame_start до та після інших варіантів, без зміни результатів. Чи потрібно вказати додатковий варіант? Я спробував різні формати файлів, mkv, avi, mp4, і, здається, проблема не пов'язана з кодеком. Ось один файл, який я спробував:

http://www.seaotter.com/marine/movies/hermit-long-01.mpg

Я щось пропускаю?


Здається, на це відповіли у списку розсилки (і зауважте, що з копією -vcodec ви не можете "реально" отримати конкретний кадр, оскільки він може повторно синхронізуватися лише на i-фреймах
rogerdpack

@ user39364 Я запитав у списку розсилки, і виявляється, що ця опція не робить те, що хоче ОП. Я також дізнався щось нове :)
slhck

Просто хотів зауважити, що я знайшов метод вирізання на точні кадри, використовуючи melt, див. Точне вирізання відеофайлів з командного рядка - Super User
sdaau

Відповіді:


46

Я щойно дізнався, що timecode_frame_startце не працює так. Єдиний спосіб почати з конкретних кадрів - це перетворити ряд кадрів у ss.msсинтаксис, або hh:mm:ss.ms. Отже, якщо ваше відео має 25 кадрів в секунду, а ви хочете розпочати на 133 кадрах, вам знадобиться

133/25 = 5,32

Отже, біжи

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac out.mp4

Зауважте, що різання на точні кадри з бітовою копією ( -c:v copy) неможливо, оскільки не всі кадри внутрішньо кодовані і можуть стояти самостійно.

-ss завжди буде точною рамкою.

Якщо ви хочете кодувати певну кількість кадрів, використовуйте -frames:v, наприклад:

ffmpeg -ss 5.32 -i input.mp4 -c:v libx264 -c:a aac -frames:v 60 out.mp4

Ви також можете використовувати відеофільтри , але підтримка аудіо може бути не точною. І, мабуть, пошук кадрів все ще не є особливістю. Ви можете слідкувати за цим рядком розсилки користувачів FFmpeg для отримання додаткової інформації:

ви можете використовувати -vf selectдля точного вибору кадру (щось на зразок -vf 'select=gte(n\,100)'пропустити 100 перших кадрів)


3
для відео з дроп-кадрами (наприклад, 29,97 кадрів в секунду), які перевищують 10 хвилин; як би ви вирішили точно обчислити час для конкретного кадру?
GFoley83

select=gte(n\,100)метод працює , але шукання з'їдає продуктивність. Якщо ви протестуєте, кодуючи всього 30 кадрів за один раз, Чим далі я починаю відео, тим довше ffmpeg потрібно виконати через пошуки.
Адам Грант

6

Варіант

-vf select = "між (n \, start_frame_num \, end_frame_num ), setpts = PTS-STARTPTS"
наприклад,

-vf select=“between(n\,200\,300),setpts=PTS-STARTPTS"

вирізає відео з (включає) 200-го до (включає) 300-го кадру, підрахунок послідовностей починається від 0.

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