У меня есть файл .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?
Для параметров 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, что он должен установить v
ideo b
itrate на заданное значение. В своем вводе вы установили его на copy
. Это недопустимое значение для этой опции. Параметры битрейта предполагают число и, возможно, порядок величины, например 320k
или 320000
.
Либо намерением было скопировать аудиокодек, и в этом случае это должно быть -c:a copy
, либо намерением было скопировать битрейт видео. Для последнего просто удалите параметр вообще; -c:v copy
создает точную копию (выбранной части) видеопотока, который включает в себя битрейт, количество кадров, частоту кадров и временные метки, а также все другие видеоданные.
Чтобы настроить вывод на тот же битрейт видео, что и вход без копирования, используйте ffprobe
, чтобы сначала проверить битрейт потоков.
@DanielKurniadi Извините, я не увидел комментарий раньше, так как ТАК может быть немного сложно уведомить меня о комментариях. Что касается -c:v
, это означает c
odec:v
ideo, поэтому copy
имеет допустимое значение и точно копирует указанное видео. Если вы используете параметры поиска, это не заставит его начинать с ключевого кадра, что сделает часть видео невоспроизводимой. Если у вас есть конкретные вопросы об определенных кодеках и параметрах, не стесняйтесь задавать новый вопрос.
Привет @RivenSkaye, если я новичок в
ffmpeg
и почти не знаю, как читать его документы. Что здесь означает опция кодека:-c:v [something]
? Из разных ответов я заметил, что значение[something]
может бытьcopy
,libvpx-vp9
,mpeg4
и т. д. Поправьте меня, если я ошибаюсь, но я действительно невежественен. Я мог бы опубликовать другой вопрос, если хотите, и скопировать ссылку, если ваш ответ длинный.