Jak zmienić liczbę klatek na sekundę wideo bez ponownego kodowania

14

Próbuję zmienić liczbę klatek na sekundę filmu MP4 (jest to film GoPro 120 kl./s, chcę go odtworzyć przy 30 kl./s, aby uzyskać efekt zwolnionego tempa).

Używam do tego avconv:

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

To technicznie działa, ale ponownie koduje film. Oprócz tego, że jest powolny, jest to oczywiście kwestia jakości. Technicznie powinien istnieć sposób, aby ustawić fps w nagłówku wideo, jak mogę to zmienić? (Każde narzędzie inne niż avconv też by działało).

EboMike
źródło

Odpowiedzi:

15

MP4Box może to zrobić.

Komenda

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

tworzy pliki testi test_track1.h264. Możesz teraz utworzyć plik mp4 z dowolną obsługiwaną liczbą klatek na sekundę (30 w tym przykładzie):

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

MP4Box jest częścią gpacpakietu, więc upewnij się, że jest zainstalowany.

Mitch
źródło
6
To naprawdę nie jest proste, ale rozumiem - musisz to zrobić w dwóch krokach. Najpierw wyodrębnij strumień wideo osobno jako raw ( MP4Box -add source.mp4#video -raw 1 -new test), a następnie zapisz go ponownie jako MP4 ( MP4Box -add test_track1.h264:fps=30 -new dest.mp4). Możesz tam również dodać ścieżkę audio (przez #audio).
EboMike,
Lepiej jest użyć -singleopcji dla pierwszego polecenia. MP4Box -single 1 -raw 1 SourceMovie.mp4tworzy tylko jeden plik SourceMovie_track1.h264zamiast dwóch.
diversenok
6

Zmiana liczby klatek na sekundę w nagłówku wideo (kontenera) nie ma wpływu na sam strumień wideo (lub audiostream). Ponowne kodowanie jest jedyną opcją.

Strumienie wideo mają znaczniki czasu, aw większości filmów klatki są od siebie zależne ze względu na kompresję między ramkami. Niektórzy gracze mogą przyspieszyć i spowolnić wideo, ale nie przez wbudowane polecenia lub coś w tym rodzaju. Żaden gracz nie może zmieniać prędkości klatek w locie, gdy komenda kontenera o to poprosi. Plik wideo skończy się ze specyfikacją (tj. Niezgodną ze standardami), a 99,9% graczy odmówi przestrzegania go. Nie jest możliwe robienie tego, co chcesz bez ponownego kodowania. Oczywiście możesz poczekać z przekodowaniem do ostatniego kroku edycji.

thom
źródło
1
Dzięki thom! Głupie pytanie - dlaczego? Czy każda klatka ma znacznik czasu, który zmusza odtwarzacz do wymuszenia określonej prędkości odtwarzania? Chcę dokładnie tych samych klatek, chcę tylko, aby były odtwarzane w innym tempie.
EboMike,
2
Cześć Mike, twoje pytanie nie jest głupie, szczerze mówiąc, sposób, w jaki myślisz, jest dość sprytny. podoba mi się twój sposób myślenia. Dodałem więcej informacji do mojej odpowiedzi, ponieważ było zbyt długo, aby umieścić to w polu komentarza.
thom
Dzięki! To dość pouczające. Jeśli chodzi o przekodowywanie - jaki jest najlepszy sposób, aby to zrobić za pomocą czegoś takiego jak avconv? Użyłem powyższego wiersza poleceń, ale spowodowało to okropną jakość - prawie widziałem każdy makroblok.
EboMike,
1
Znaczniki czasu w strumieniach wideo są przechowywane w kontenerze, a nie w samym surowym strumieniu bitów h.264, tak myślę. Tak długo, jak chcesz zmienić czas, ale nie kolejność, w jakiej ramce jest wyświetlana, kiedy nie powinieneś potrzebować transkodować, po prostu remux. (A jeśli robisz xcode, z szybszym sprzętem użyłbyś -preset wolniej lub bardzo wolno, aby uzyskać lepszą jakość przy SAME bitrate, zamiast po prostu rzucać więcej bitów na problem. I użyj -crf 18 lub coś, nie ABR)
Peter Cordes
1
Nie mogę jednak wymyślić, w jaki sposób zmusić ffmpeg do wyjścia z inną liczbą klatek na sekundę. Wygląda na to, że mkvmerge / mp4box są konieczne, chyba że można uzyskać od ffmpeg wyprowadzenie surowego strumienia bitów .264, a następnie użyć opcji fps do demuxera h.264 (który - pełne dokumenty to, ponieważ ma strumień bitów nie ma timingu informacje, tylko zamawianie.)
Peter Cordes
3

Jeśli twoim głównym celem jest odtwarzanie go w zwolnionym tempie, a nie zachowanie pliku jako MP4, możesz użyć narzędzia GUI MKVmerge, aby przełożyć go ponownie na pojemnik Matroska, który z łatwością może zmienić ilość klatek na sekundę. Remuxowanie jest znacznie lepsze niż ponowne kodowanie, ponieważ zmienia tylko metadane, a nie sam strumień.

Najpierw zainstaluj pakiet

sudo apt-get install mkvtoolnix-gui

Następnie uruchamiasz MKVmerge GUI. Pojawi się takie okno

mkvmerge gui 1

Wystarczy nacisnąć przycisk Dodaj i wybrać plik lub nawet przeciągnąć i upuścić plik w obszarze „Pliki wejściowe”. W tym momencie powinieneś być w stanie wybrać strumień wideo w swoim filmie. Możesz także usuwać inne strumienie, ponieważ one i tak przeszkadzają.

Po wybraniu powinieneś zobaczyć dolne zakładki, które stają się aktywne:

wprowadź opis zdjęcia tutaj

Zmień na „Formatuj określone działania”

wprowadź opis zdjęcia tutaj

Widoczne jest pole „FPS”, w którym można wprowadzić wartość klatek na sekundę. Wyglądało na to, że planujesz cztery razy zwolnić, więc Twoim celem będzie około 7 klatek na sekundę. Możesz także użyć opcji „Rozciągnij o”.

Następnie możesz po prostu zmienić nazwę pliku wyjściowego (jeśli chcesz) i nacisnąć „Rozpocznij multipleksowanie”.

Program uruchomi się i powinieneś mieć swój plik.

v010dya
źródło
2

Chciałem też bezstratnie zwolnić moje 120 filmów FPS do 30 FPS. Stworzyłem skrypt, który robi to, zmieniając tempo dźwięku i modyfikując FPS bezpośrednio w kontenerze MP4. Wymagane są następujące narzędzia:

  1. avconv do konwersji strumieni audio
  2. sondstretch, aby spowolnić tempo dźwięku
  3. gpac, aby MP4Box zmienił FPS

Skrypt używany do konwersji znajduje się tutaj:

#!/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"

Ten skrypt tworzy kopię MP4 z _slow postfix.

OSi
źródło