Різання відео в точних кадрах за допомогою фільтра вибору ffmpeg


16

Замість використання -ssта -toпошуку параметрів, які здаються не дуже точними, чи можу я вирізати відео для заданих номерів кадрів? Наприклад;

ffmpeg -i video.webm -startingframe 80 -endingframe 560 output.webm

[80-й кадр та 560-й кадр включені. Отже, загалом (560 - 80 +1) кадрів]

Після відповідей і невеликого пошуку я спробував кілька команд. Але поки що я не міг знайти прийнятний спосіб.

Якщо хтось хоче скоротити відеопотік між 250-м та 750-м кадрами, це шлях. Це дасть 501 кадр як вихід:

Примітка: movie.mp4 має 25 кадрів в секунду, швидкість вибірки звуку - 48 к

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm

Як і очікувалося, вихід точно триває 20 секунд.

Використовуючи той же метод для аудіо:

ffmpeg -i movie.mp4 -vn -af "aselect=between(n\,480\,1440),setpts=PTS-STARTPTS" a_stream.webm

Несподівано, цей має дуже низьку точність. Це повинно було дати мені 960001 (960k + 1) зразків, що дорівнює аудіо 20 секунд. Але натомість вихід був 20,505 секунди і налічував 984240 проб. Також, якщо я збільшую тривалість, збільшується і помилка.

Потім я спробував використовувати параметри -ss -to для вирізання аудіопотоку:

ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm

Старий класичний спосіб працює набагато краще. Вихід тривав 20.003 секунди і налічував 960144 зразків. Плюс збільшення тривалості помилки не збільшує, помилка постійна, завжди є 144 надлишків зразків із цим вхідним файлом.

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

Отже, щоб точно вирізати медіа-файл, я повинен зробити ці 3 кроки:

ffmpeg -i movie.mp4 -an -vf "select=between(n\,250\,750),setpts=PTS-STARTPTS" v_stream.webm 
ffmpeg -i movie.mp4 -vn -ss 10.000 -to 30.000 a_stream.webm 
ffmpeg -i v_stream.webm -i a_stream.webm -c:v copy -c:a copy  movie-between_10th_and 20th_seconds.webm

Це дає найбільш точні результати. Відео триває 20 000 секунд, а звуковий кадр - акустичний - 20,003 секунди та має зразок 960144. Не зовсім збігається з відеопотоком, але це нормально. Залишок лише 144 проби. Найбільшим недоліком є ​​те, що коли я хочу вирізати файл, я повинен надсилати 3 команди для простої роботи, і це створює два непотрібні файли: a_stream.webm та v_stream.webm. І selectфільтр не працює на деяких вхідних файлах, які я пробував. Він виконує цю роботу успішно (?), Але ніколи не зупиняє процес кодування, тому мені доведеться щоразу закривати командний рядок.


Я прочитав цю сторінку, перш ніж я опублікував це питання. Ця сторінка мені не допомогла. Якщо вхід має змінну fps, чи можемо ми просто обчислити, використовуючи це рівняння? Я не думаю, що так. Також я не думаю, що "-ss" дасть мені точну позицію. Я думаю, що кадр за кадром шукатиме краще.
дестор

Зверніть увагу, що -ssце рамка (див. Тут ). У вас насправді є вхід змінної кадрів в секунду? Моя відповідь посилається на потік списку розсилки, який згадує за допомогою selectфільтрів, де можна вказати номер кадру. Ви пробували це?
slhck

Я спробував використовувати selectі aselectфільтри для відео та аудіо потоків. Selectє точним для кадру для відео, але aselectне є зразком. Насправді це далеко не точне. Це дає набагато гірші результати, ніж використання простих параметрів -ss -to. Через це я зараз використовую комбінацію selectфільтра та -ss -toпараметрів, щоб досягти найбільш точного різання. Але це шорсткий спосіб зробити це. Подивіться, будь ласка, на моєму першому дописі, я додав декілька командних
рядків

версія ffmpeg?
пт

Чому ви все одно намагаєтеся скоротити номер кадру. Якщо вам потрібна така точність, то чому б не використовувати avidemux? Також, можливо, ваші початкові проблеми полягають у тому, що він вибирає найближчий кадр ключа?
пт

Відповіді:


3

Аудіо надходить із секунд, а не з кадрів, тому, якщо ви хочете вирізати відео, вам слід обчислити відео в секунду × 20 секунд так: 20 секунд від 23,97 кадрів в секунду = 479,4

Різка кадру не є точною, тому що ви не можете отримати повний кадр в секунду за останню секунду, тому звук отримає більше секунд або лише півтори секунди або трохи більше або менше! Можливо, вам слід використовувати секунди замість кадрів, щоб отримати точний зріз, ви скажете ffmpeg зробити це за вас. А якщо ви отримаєте 1 додатковий кадр, що робити із зміною 250-го та 750-го кадрів на 250-й та 749-й кадри ?! Використовуйте мінус 1, щоб завжди отримувати кількість кадрів, які ви просите!


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