При извлечении части видео с помощью ffmpeg без перекодирования вывод прерывается

Я извлекаю часть видео с 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 видео становится совершенно плавным. Как это исправить?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Когда вы используете -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) Мне приходит в голову третий вариант: вы могли бы:

  1. получить время первого ключевого кадра после вашей временной метки -ss
  2. перекодируйте часть от вашей временной метки до ключевого кадра как одно видео
  3. скопируйте часть ключевого кадра как другое видео
  4. объединить видео вместе
This would ensure that you use the minimum of CPU/GPU time and preserve as much quality as possible.

Интересный! Можете ли вы добавить несколько советов по решению (2)? Я могу написать сценарий Python, чтобы при извлечении ffmpeg-вызова использовались результаты ffmpeg-вызова по обнаружению ключевого кадра.

Basj 13.07.2024 16:52

Есть ли решение (3) с флагом в ffmpeg в дополнение к -ss 123.45, чтобы сохранить все данные с момента предыдущего ключевого кадра, но с флагом в видео, говорящим, что видео должно начинаться с 123.45. TL;DR: выходной MP4 может содержать данные с 118,28, но с флагом начала воспроизведения только с 123,45.

Basj 13.07.2024 16:55

Я обновил свой ответ. Я не видел вашего решения (3), хотя оно возможно. Я добавил свое собственное решение (3)

PANICresponse 13.07.2024 18:48

Для решения (3) взгляните на этот ответ

Alain1A45 13.07.2024 19:07

Другие вопросы по теме