Ffmpeg конвертирует переменную частоту кадров .webm в видео с постоянной частотой кадров

У меня есть файл .webm с записью игры со скоростью 16 кадров в секунду. Однако при попытке обработать видео с помощью OpenCV кажется, что видео записывается с переменной частотой кадров, поэтому, когда я пытаюсь использовать OpenCV для получения кадра каждую секунду, получая каждый 16-й кадр, это не будет работать, так как видео поток завершится преждевременно.

Поэтому я пытаюсь преобразовать видео .webm с переменным кадром, в котором утверждается, что оно имеет частоту кадров 16 кадров в секунду, в видео с постоянным кадром, чтобы я мог извлекать один кадр в секунду. Я пробовал следующую команду ffmpeg из https://ffmpeg.zeranoe.com/forum/viewtopic.php?t=5518:

ffmpeg -i input.webm -c:v copy -b:v copy -r 16 output.webm

Однако произойдет следующая ошибка:

[NULL @ 00000272ccbc0c40] [Eval @ 000000bc11bfe2f0] Undefined constant or missing '(' in 'copy'
[NULL @ 00000272ccbc0c40] Unable to parse option value "copy"
[NULL @ 00000272ccbc0c40] Error setting option b to value copy.

Error setting up codec context options.

Вот код, который я пытаюсь использовать для обработки кадра каждую секунду:

video = cv2.VideoCapture(test_mp4_vod_path)
print("Opened ", test_mp4_vod_path)
print("Processing MP4 frame by frame")

# forward over to the frames you want to start reading from.
# manually set this, fps * time in seconds you wanna start from
video.set(1, 0)
success, frame = video.read()
#fps = int(video.get(cv2.CAP_PROP_FPS))  # this will return 0!
fps = 16  # hardcode fps
total_frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
print("Loading video %d seconds long with FPS %d and total frame count %d " % (total_frame_count/fps, fps, total_frame_count))

count = 1
while video.isOpened():
    success, frame = video.read()
    if not success:
        break

    if count % fps == 0:
        print("%dth frame is %d seconds on video"%(count, count/fps))
    count += 1

Код завершится до того, как приблизится к концу видео, поскольку видео не имеет постоянной частоты кадров. Как преобразовать видео с переменным FPS в видео с постоянным FPS?

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
3 836
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий
  • Для параметров webM в FFmpeg прочитайте: https://trac.ffmpeg.org/wiki/Encode/VP9.

  • Не используйте опцию codec copy при преобразовании частоты кадров.

Возможное решение (2M — тестовое значение, отрегулируйте для своего видео):

ffmpeg -i input.we -c:v libvpx-vp9 -minrate 2M -maxrate 2M -b:v 2M -pix_fmt yuv420p -r 16 output.webm

Во-первых, другой ответ от VC.One очень похож на ваш ответ нужно. Однако это не точный ответ на ваш вопрос.

В вашей команде есть небольшая ошибка, поэтому выдается ошибка. -b:v сообщает ffmpeg, что он должен установить video bitrate на заданное значение. В своем вводе вы установили его на copy. Это недопустимое значение для этой опции. Параметры битрейта предполагают число и, возможно, порядок величины, например 320k или 320000.

Либо намерением было скопировать аудиокодек, и в этом случае это должно быть -c:a copy, либо намерением было скопировать битрейт видео. Для последнего просто удалите параметр вообще; -c:v copyсоздает точную копию (выбранной части) видеопотока, который включает в себя битрейт, количество кадров, частоту кадров и временные метки, а также все другие видеоданные.

Чтобы настроить вывод на тот же битрейт видео, что и вход без копирования, используйте ffprobe, чтобы сначала проверить битрейт потоков.

Привет @RivenSkaye, если я новичок в ffmpeg и почти не знаю, как читать его документы. Что здесь означает опция кодека: -c:v [something]? Из разных ответов я заметил, что значение [something] может быть copy, libvpx-vp9, mpeg4 и т. д. Поправьте меня, если я ошибаюсь, но я действительно невежественен. Я мог бы опубликовать другой вопрос, если хотите, и скопировать ссылку, если ваш ответ длинный.

Daniel Kurniadi 10.01.2020 10:51

@DanielKurniadi Извините, я не увидел комментарий раньше, так как ТАК может быть немного сложно уведомить меня о комментариях. Что касается -c:v, это означает codec:video, поэтому copy имеет допустимое значение и точно копирует указанное видео. Если вы используете параметры поиска, это не заставит его начинать с ключевого кадра, что сделает часть видео невоспроизводимой. Если у вас есть конкретные вопросы об определенных кодеках и параметрах, не стесняйтесь задавать новый вопрос.

RivenSkaye 15.05.2020 15:58

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