Я извлекаю часть видео с 00:02:00.000 по 00:03:30.000 с помощью ffmpeg
:
ffmpeg -i input.mp4 -ss 120 -t 90 -vcodec copy -acodec copy output.mp4
Это работает, но выходное видео получается прерывистым, то есть не совсем плавным. Почему?
Единственный журнал, который у меня есть:
[mp4 @ 000000000041c700] track 1: codec frame size is not set
[mp4 @ 000000000041c700] Timestamps are unset in a packet for stream 0. This is deprecated and will stop working in the future. Fix your code to set the timestamps properly
[mp4 @ 000000000041c700] pts has no value
Last message repeated 7894 times
Но при просмотре исходного видео и переходе к 00:02:00.000
видео становится совершенно плавным. Как это исправить?
Видеопоток состоит из фрагментов видео по несколько секунд или нескольких кадров за раз. В начале каждого фрагмента находится ключевой кадр, который содержит весь кадр, а затем данные последующего кадра состоят из изменений предыдущего изображения. Всякий раз, когда сцена меняется или данные между кадрами меняются слишком сильно, генерируется новый ключевой кадр, а затем последующие кадры снова представляют собой просто изменения данных.
Когда вы используете -c:v copy -ss 123.45, скорее всего, указанная вами временная метка не совпадает с ключевым кадром, и поэтому в результирующем видео будет черный ключевой кадр, и последующие изменения кадров не будут иметь особого смысла, следовательно дает прерывистый результат.
Исправление этого заключается в следующем:
(1) перекодировать или перекодировать вместо копирования
(2) определите, где находятся ключевые кадры, и совместите временную метку начала с ключевым кадром. Вы можете написать сценарий для обнаружения ключевых кадров и установки оттуда временных меток, но, на самом деле, это невозможно сделать с помощью одной команды.
например, вы можете использовать что-то вроде: ffprobe -i INPUT.mp4 -select_streams v -show_entries frame=pts_time -of csv=p=0 -skip_frame nokey > frames.txt
(3) Мне приходит в голову третий вариант: вы могли бы:
Есть ли решение (3) с флагом в ffmpeg в дополнение к -ss 123.45
, чтобы сохранить все данные с момента предыдущего ключевого кадра, но с флагом в видео, говорящим, что видео должно начинаться с 123.45. TL;DR: выходной MP4 может содержать данные с 118,28, но с флагом начала воспроизведения только с 123,45.
Я обновил свой ответ. Я не видел вашего решения (3), хотя оно возможно. Я добавил свое собственное решение (3)
Для решения (3) взгляните на этот ответ
Интересный! Можете ли вы добавить несколько советов по решению (2)? Я могу написать сценарий Python, чтобы при извлечении ffmpeg-вызова использовались результаты ffmpeg-вызова по обнаружению ключевого кадра.