Как изменить частоту кадров видео без перекодирования


14

Я пытаюсь изменить частоту кадров видео MP4 (это видео GoPro 120 кадров в секунду, я хочу воспроизвести его со скоростью 30 кадров в секунду для эффекта замедленного воспроизведения).

Я использую avconv для этого:

avconv -i SourceMovie.mp4 -vf setpts=4.0*PTS -r 30 DestMovie.mp4

Это технически работает, но перекодирует фильм. В дополнение к медленной, это, очевидно, проблема качества. Технически должен быть способ установить fps в заголовке видео, как я могу это изменить? (Любой инструмент, кроме avconv тоже подойдет.)

Ответы:


15

MP4Box может это сделать.

Команда

MP4Box -add SourceMovie.mp4#video -raw 1 -new test

создает файлы testи test_track1.h264. Теперь вы можете создать файл mp4 с любой поддерживаемой частотой кадров (30 в этом примере):

MP4Box -add test_track1.h264:fps=30 -new DestMovie.mp4

MP4Box является частью gpacпакета, поэтому убедитесь, что он установлен.


6
Это действительно не так просто, но я понял - нужно сделать это в два этапа. Сначала извлеките видеопоток отдельно как raw ( MP4Box -add source.mp4#video -raw 1 -new test), а затем снова сохраните его как MP4 ( MP4Box -add test_track1.h264:fps=30 -new dest.mp4). Вы также можете добавить туда звуковую дорожку (через #audio).
EboMike

Лучше использовать -singleопцию для первой команды. MP4Box -single 1 -raw 1 SourceMovie.mp4создает только один файл SourceMovie_track1.h264вместо двух.
Диверсенок

6

Изменение частоты кадров в заголовке видео (контейнера) не влияет на сам видеопоток (или аудиопоток). Перекодирование является единственным вариантом.

Видеопотоки имеют временные метки, и в большинстве видео кадры взаимозависимы друг от друга из-за межкадрового сжатия. Некоторые плееры могут ускорять и замедлять видео, но не с помощью встроенных команд или чего-то еще. Ни один игрок не может изменить частоту кадров на лету, когда команда контейнера просит сделать это. Видеофайл будет не соответствовать спецификации (то есть не будет соответствовать стандартам), и 99,9% игроков откажутся соблюдать его. Совершенно невозможно сделать то, что вы хотите, без перекодирования. Конечно, вы можете подождать с перекодированием до последнего шага вашего редактирования.


1
Спасибо, том! Хотя глупый вопрос - почему? Есть ли у каждого кадра временная метка, которая заставляет игрока обеспечивать определенную скорость воспроизведения? Я хочу точно такие же кадры, я просто хочу, чтобы они воспроизводились с разной скоростью.
EboMike

2
Привет, Майк, нет, твой вопрос не глупый, честно говоря, способ, которым ты думаешь, довольно умен. Мне нравится твой образ мышления. Я добавил больше информации в свой ответ, потому что это было слишком долго, чтобы поместить это в поле для комментариев.
Thom

Благодарность! Это довольно информативно. Теперь что касается перекодирования - какой лучший способ сделать это с чем-то вроде avconv? Я использовал командную строку выше, но это привело к ужасному качеству - я мог видеть почти каждый макроблок.
EboMike

1
Временные метки в видеопотоках хранятся в контейнере, а не в самом битовом потоке h.264, я думаю. Пока вы просто хотите изменить время, но не порядок отображения фрейма, когда вам не нужно перекодировать, просто используйте ремукс. (И если вы делаете xcode, с более быстрым аппаратным обеспечением вы будете использовать -preset более медленный или veryslow, чтобы получить более высокое качество при одинаковом битрейте, вместо того, чтобы просто бросать больше битов при проблеме. И использовать -crf 18 или что-то, а не ABR)
Питер Кордес

1
Я не могу понять, как заставить ffmpeg выводить другую частоту кадров. Похоже, mkvmerge / mp4box необходимы, если только вы не можете получить ffmpeg для вывода необработанного потока битов .264, а затем использовать опцию fps для демультиплексора h.264 (который содержит полные документы, так как битовый поток не имеет времени) информация, только заказ.)
Питер Кордес

3

В случае, если ваша главная цель - воспроизвести его в замедленном режиме, а не сохранить файл в формате MP4, вы можете использовать инструмент MKVmerge GUI, чтобы смешать его в контейнере Matroska, который может легко изменить частоту кадров. Remuxing намного лучше, чем перекодирование, потому что он изменяет только метаданные, а не сам поток.

Сначала вы устанавливаете пакет

sudo apt-get install mkvtoolnix-gui

Затем вы запускаете MKVmerge GUI. Вы столкнетесь с таким окном

MKVMERGE GUI 1

Просто нажмите кнопку «Добавить» и выберите свой файл или просто перетащите файл в область «Входные файлы». На этом этапе вы сможете выбрать видеопоток в вашем видео. Вы также можете удалить другие потоки, так как они все равно будут мешать.

После того, как вы выбрали его, вы должны увидеть, как активируются нижние вкладки:

введите описание изображения здесь

Измените на «Форматировать определенные действия»

введите описание изображения здесь

Вы можете видеть, что есть поле «FPS», где вы можете ввести значение кадров в секунду. Выглядело так, как будто вы планируете замедлить работу четыре раза, поэтому вашей целью будет около 7 кадров в секунду. Вы также можете использовать опцию «Растянуть по».

После этого вы можете просто изменить имя выходного файла (если хотите) и нажать «Начать мультиплексирование».

Программа запустится, и вы должны иметь свой файл.


2

Я также хотел замедлить без потерь мои 120 кадров в секунду до 30 кадров в секунду. Я сделал скрипт, который делает это путем изменения темпа звука и изменения FPS непосредственно в контейнере MP4. Требуются следующие инструменты:

  1. avconv для конвертации аудио потоков
  2. sondstretch для замедления темпа звука
  3. gpac для получения MP4Box для изменения FPS

Скрипт, используемый для конвертации, находится здесь:

#!/bin/bash
#########################################
# Lossless slow down from 120 to 30 FPS #
#                                       #
# Use:                                  #
#                                       #
#   slow.bash <mp4_file>                #
#                                       #
#                           #-= OSi =-# #
#########################################


# Prepare basic variables
IN_FILE="$1"
NAME=$(echo "${IN_FILE}" | sed 's/\.[^.]*//')


# Clean up before start
rm -f "${NAME}.ac3" "${NAME}.wav" "${NAME}_.wav" "${NAME}" "${NAME}_track1.h264" "${NAME}_slow.mp4"


# Slow down sound
avconv -i "${IN_FILE}" -vn -acodec pcm_s16le "${NAME}_.wav"
soundstretch "${NAME}_.wav" "${NAME}.wav" -tempo=-75
avconv -i "${NAME}.wav" -vn -codec:a ac3_fixed -b:a 448k "${NAME}.ac3"


# Change video frame rate and multiplex with slowed sound
MP4Box -add "${IN_FILE}#video" -raw 1 -new "${NAME}"
MP4Box -add "${NAME}_track1.h264:fps=30" -add "${NAME}.ac3" -new "${NAME}_slow.mp4"


# Clean up when we are done
rm -f "${NAME}.ac3" "${NAME}.wav" "${NAME}_.wav" "${NAME}" "${NAME}_track1.h264"

Этот скрипт создает копию MP4 с постфиксом _slow.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.