точне вирізання відео (+ аудіо) за допомогою ffmpeg


10

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

У мене є вихідний відеофайл, який я спершу хочу перетворити на щось, що підходить для веб-сайту:

Input #0, matroska,webm, from 'source.mkv': 
Duration: 00:28:18.57, start: 0.000000, bitrate: 10183 kb/s 
Stream #0:0: Video: h264 (Constrained Baseline), yuv420p, 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn, 48 tbc (default)
Stream #0:1: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s (default)

Я використовую ffmpeg, щоб перетворити його так:

ffmpeg -i source.mkv -c:v libx264 -c:a aac -strict experimental -vf scale="960:-1" source.mp4

Переглядаючи це відео назад, він достатньо якісний і достатньо невеликий розмір файлу для моїх потреб та завантаження / відтворення на моєму веб-сайті.

У мене є веб-сторінка, яка дозволяє користувачам вибрати стартову та кінцеву точку цього відео - і створити кліп. Ось приклад команди ffmpeg, яку я використовую для цього:

-ss 577.920 -i source.mp4 -t 011.980 -codec:v copy -codec:a copy -vf scale="960:-1" clip1.mp4

Проблема в тому, що кліп не завжди є достатньо точним за часом. Зазвичай звук досить точний, але відео зупиняється на півсекунди рано чи щось.

Чи є якийсь спосіб зробити це точним і синхронізованим, скажімо, 0,2 секунди?

EDIT: Додавання -force_key_frames 00:00:00.2не допомогло.

EDIT: Я змінив відсікання на використання -c:v libx264 -c:a aac -strict experimentalзамість -codec:v copy -codec:a copyхороших (ish) результатів.

Файл може відтворюватись без проблем, але коли я завантажую його у свій елемент html5-відео та відтворюю його - остання частина відео (звук прекрасна) застигає. Остання частина, яка замерзає, довша секунди.

Чи варто спробувати це з іншим відео кодером? Яка найкраща альтернатива libx264? Маючи на увазі, я, мабуть, хочу, щоб це було на загальнодоступному веб-сайті.

Але не витримуйте чи не факт, що він грає точно без проблем з таким програвачем, як MPC або Windows Media Player, чи припускає це проблема з Google Chrome або з елементами відео HTML? Або я використовую непідтримуване кодування чи щось таке?


Це може бути пов’язано з тимчасовими рамками ключових кадрів. У будь-якому випадку це потрібно перенести на SuperUser.com.
Бред

Привіт, ffmpeg не може вирізати відео в будь-якій точці, він може вирізати лише ключові кадри; З цієї причини звук майже точний, а відео - ні.

Чи можу я сам її перемістити? Я спробую додати ключові кадри до вихідного файлу за допомогою -force_key_frames 00: 00: 00.2
Pete

Відповіді:


9

Поведінка -ssзмінюється залежно від того, якщо вона використовується як параметр введення або виводу, і часто є повільнішою, але може бути більш точною, коли використовується як вихідний варіант. Дивіться відповідь на ffmpeg перетворює відео з визначеного періоду повільно для отримання детальної інформації та прикладів.

Для зміни якості виводу для source.mp4використання використовується -crfопція зі значенням між 18-28 (за замовчуванням 23). Див. Розділи CRF у Посібнику з кодування FFmpeg та x264 для прикладів.

Ваша команда обрізки може бути спрощена:

ffmpeg -ss 577.92 -i source.mp4 -ss 0 -t 11.98 -c copy -map 0 clip1.mp4

Я замінив -codec:v copy -codec:a copyна -c copy -map 0. Це скопіює всі потоки замість лише першого відео та аудіо потоку - хоча вхід має лише два потоки завдяки попередній команді. Оскільки ви не можете масштабувати без повторного кодування, тому виключаєте взаємовиключення -codec:v copy, і оскільки ваше введення вже масштабується до встановленого розміру, я видалив параметри фільтра.

Якщо вона все ще недостатньо точна, спробуйте:

ffmpeg -i source.mp4 -ss 577.92 -t 11.98 -c copy -map 0 clip1.mp4

Це буде повільніше, але, ймовірно, більш точно. Дивіться посилання у відповіді у першому посиланні, яке я надав для опису відмінностей цих двох прикладів.

І, нарешті, ви повинні запустити source.mp4через qt-faststart(знаходиться в каталозі інструментів в джерелі FFmpeg), або використовуйте -movflags faststartопцію. Це перемістить деякі дані на початок файлу, щоб вони могли розпочати відтворення до повного завантаження.


+1 для порад, але я спробував ffmpeg -i source.mp4 -ss 577.92 -t 011.980 -c копія -map 0 clip1.mp4, але перша частина (майже друга) і остання частина (можливо, чверть секунди) відео пропущено, проте аудіо чудово.
Піт Оукі

@PeteOakey Ви намагалися вирізати без бітової копії, але фактичного перекодування?
slhck

Спробував це без копії бітстрілу - результати додали до мого питання.
Піт Оакі

3
Використання -ssяк вихідного варіанту замість вхідного варіанту вирішило мою проблему: перший кадр відео був приблизно 1 с у вихідному відео, до цього був лише звук (також підтверджений ffprobe -show_frames). Переміщення -ssпісля цього -iдозволило вивести кадри аудіо та відео, починаючи з кадру 0.
CodeManX
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.