Jak obrócić wideo o 180 ° za pomocą FFmpeg?


69

Mam film, który został obrócony o 180 ° podczas nagrywania. Czy można to naprawić za pomocą FFmpeg?


Czy pytasz o odwrócenie go podczas odtwarzania lub ponownego kodowania w prawidłowej orientacji?
Mxx

@Mxx Myślałem o ponownym kodowaniu, ale co miałeś na myśli podczas odtwarzania?
Louis,

Odtwarzacze multimedialne, które używają ffmpeg jako zaplecza dekodującego, mogą również wykorzystywać wszystkie jego filtry. Zobacz ten zrzut ekranu ffdshow-tryout.sourceforge.net/images/front1.png Filtr „Przesunięcie i odwrócenie”. Zobacz także stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg
Mxx

No dobrze, spoko. To by działało dla mnie, ale ja też chcę się tym podzielić. Rzucę okiem na pytanie SO.
Louis,

5
Sformułowanie i tytuł tego pytania są bardzo mylące. Odwrócenie wideo w pionie to nie to samo, co obrócenie go o 180 stopni (co jest tym samym co odwrócenie pionowe i poziome). Na podstawie zaakceptowanej odpowiedzi edytuję, aby określić obrót. Obecnie zanieczyszcza to wyniki Google dla pionowych filmów z ffmpeg.
Jason C

Odpowiedzi:


102

oryginałobrócony


tl; dr

ffmpeg automatycznie obróci wideo, chyba że:

  • Twoje dane wejściowe nie zawierają obrotowych metadanych
  • twój ffmpegjest za stary

Metadane rotacji

Niektóre filmy, na przykład z iPhone'ów, nie są fizycznie odwracane, ale zawierają dane poboczne strumienia danych wideo lub obracają metadane. Niektórzy gracze ignorują te metadane, a inni nie. Sprawdź ffmpegdane wyjściowe konsoli, aby sprawdzić, czy dane wejściowe zawierają takie metadane:

$ ffmpeg -i input.mp4
...
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'input.mp4':
  Duration: 00:00:05.00, start: 0.000000, bitrate: 43 kb/s
    Stream #0:0(und): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 320x240 [SAR 1:1 DAR 4:3], 39 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default)
    Metadata:
      rotate          : 180
    Side data:
      displaymatrix: rotation of -180.00 degrees

Automatyczne obracanie

ffmpeg automatycznie fizycznie obróci wideo zgodnie z istniejącymi metadanymi obrotu strumienia wideo.

Aby móc korzystać z funkcji autorotacji, potrzebujesz kompilacji zawierającej zatwierdzenie 1630224 od 2 maja 2015 r.

Przykład

ffmpeg -i input.mp4 -c:a copy output.mp4

Aby wyłączyć to zachowanie, użyj -noautorotateopcji.


Jeśli dane wejściowe nie zawierają metadanych lub jeśli ffmpegsą stare

Będziesz musiał użyć filtra, aby obrócić wideo, a jeśli istnieją jakiekolwiek obracające metadane, trzeba je usunąć, jak pokazano w poniższych przykładach:

Przykłady

Używając ffmpegmasz do wyboru trzy metody używania filtrów wideo do obracania o 180 °.

hflip i vflip

ffmpeg -i input.mp4 -vf "hflip,vflip,format=yuv420p" -metadata:s:v rotate=0 \
-codec:v libx264 -codec:a copy output.mkv

transpose

ffmpeg -i input.mp4 -vf "transpose=2,transpose=2,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

rotate

Ten filtr może obracać się pod dowolnym dowolnym kątem i używa radianów jako jednostki zamiast stopni. Ten przykład obróci radian π / 1 lub o 180 °:

ffmpeg -i input.mp4 -vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

Zamiast tego możesz użyć stopni. Jeden stopień jest równy π / 180 radianom. Więc jeśli chcesz obrócić o 45 °:

ffmpeg -i input.mp4 -vf "rotate=45*(PI/180),format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 -codec:a copy output.mp4

Podczas korzystania z rotatefiltra interpolacja dwuliniowa powinna być wyłączona (przy użyciu bilinear=0) dla kątów podzielnych przez 90, w przeciwnym razie może wyglądać na rozmazany.


Notatki

  • Filtrowanie wymaga kodowania. Te przykłady tworzą wyjścia wideo H.264. Zobacz Przewodnik po kodowaniu wideo FFmpeg H.264, aby uzyskać wskazówki, jak uzyskać żądaną jakość.

  • Podpróbkowanie barwy. Włączyłem, format=yuv420pponieważ ffmpegspróbuję zminimalizować lub uniknąć podpróbkowania barwy (w zależności od kodera, wejścia, ffmpegwersji itp.). Jest to dobre zachowanie w czysto technicznym sensie, ale większość graczy jest niezgodna z bardziej „zaawansowanymi” schematami podpróbkowania barwy. Jest to to samo, co używanie -pix_fmt yuv420, ale jest dogodnie zlokalizowany w łańcuchu filtrów .

  • Skopiuj audio. -codec:a copyOpcja stream copy (re-MUX) zamiast kodowania. Nie ma powodu, aby ponownie kodować dźwięk, jeśli chcesz manipulować tylko wideo (chyba że chcesz przekonwertować na inny format audio). Pozwoli to zaoszczędzić czas, ponieważ kodowanie jest czasochłonne i pozwoli zachować jakość dźwięku.


Obróć podczas odtwarzania

Alternatywnie możesz obracać podczas odtwarzania i unikać ponownego kodowania. ffplayautomatycznie obróci się:

ffplay input.mp4

Jeśli nie ma żadnych danych pobocznych ani rotacji metadanych, możesz użyć filtrów:

ffplay -vf "hflip,vflip" -i input.mp4

... lub skorzystaj ze swojego ulubionego odtwarzacza. Większość graczy, których warto używać, takich jak VLC, ma taką możliwość.


Dostawać ffmpeg

Starsze wersje ffmpeg nie zawierają możliwości filtrowania. Zobacz stronę pobierania FFmpeg , aby zapoznać się z kilkoma opcjami, w tym wygodnymi kompilacjami dla systemów Linux, OS X i Windows, lub zapoznaj się z Wiki FFmpeg, aby uzyskać szczegółowe instrukcje kompilacji ffmpeg .


Dzięki, właśnie skończyłem próbować -vf vflipi zadziałało to jak urok. Ale to było ponowne kodowanie. Nie jestem pewien, czy dobrze cię czytam. Czy mówisz, że -vf hflip,vflipnie będzie ponownie kodować?
Louis,

@Louis ffmpegwymaga ponownego kodowania podczas korzystania z filtrów wideo i audio. Jednak ffplaymoże również korzystać z wielu filtrów podczas odtwarzania, jak pokazano w moim drugim przykładzie.
llogan

Ach, nie zauważyłem, że to inny program.
Louis,

Zastanawiam się, czy istnieje sposób na zachowanie jakości wideo inny niż -codec:v libx264? Czy można ffmpegpo prostu użyć tego samego kodowania bez konieczności próbowania tego przez użytkownika?
Sadi

1
@Louis rotateużywa radianów jako jednostki zamiast stopni. Myślę, że ludzie są bardziej zaznajomieni ze stopniami, więc próbowałem pokazać, jak używać stopni w tym przykładzie. Jeden stopień jest równy π / 180 radianom. Więc jeśli chcesz obrócić o 45 °, po prostu użyj rotate="45*(PI/180)".
llogan

7

FFMPEG zmieniło domyślne zachowanie na automatyczne obracanie wejściowych źródeł wideo za pomocą metadanych „rotate” w wersji v2.7 w 2015 roku .

Jeśli wiesz, że twój skrypt lub polecenie nigdy nie będzie działać w wersjach ffmpeg starszych niż 2.7, najprostszym rozwiązaniem jest usunięcie dowolnej rotacji niestandardowej na podstawie metadanych.

W innych przypadkach możesz zabezpieczyć się na przyszłość, zachowując swój niestandardowy kod obrotu i dodając -noautorotateflagę (jest to obsługiwane w starszych wersjach, które nadal były w tym czasie obsługiwane).


2

Odtwarzacze multimedialne, które używają ffmpeg jako zaplecza dekodującego, mogą również wykorzystywać wszystkie jego filtry. Zobacz ten zrzut ekranu z filtrem „Przesunięcie i odwrócenie”.wprowadź opis zdjęcia tutaj

Alternatywnie, jeśli chcesz ponownie zakodować wideo, sprawdź Obracanie filmów za pomocą FFmpeg na Stackoverflow.


1
Niestety transposefiltr wymieniony w Obracanie filmów z FFmpeg nie obróci się o 180 °, o ile wiem.
llogan

1
@ LordNeckbeard nie bezpośrednio, ale możesz transposepołączyć dwa filtry razem, aby osiągnąć efekt.
evilsoup

1
@evilsoup Ah, tak, nie myślałem o tym. Rozumowanie przestrzenne jest trudne; chodźmy na zakupy. Zaktualizuj moją odpowiedź za pomocą przykładu.
llogan,

1

Poniżej znajduje się skrypt bash, który wyświetli pliki ze strukturą katalogów pod „fixedFiles”. Przekształca i obraca filmy na iOS oraz transkoduje AVI. Skrypt polega na zainstalowaniu zarówno exiftool, jak i ffmpeg .

#!/bin/bash

# rotation of 90 degrees. Will have to concatenate.
#ffmpeg -i <originalfile> -metadata:s:v:0 rotate=0 -vf "transpose=1" <destinationfile>
#/VLC -I dummy -vvv <originalfile> --sout='#transcode{width=1280,vcodec=mp4v,vb=16384,vfilter={canvas{width=1280,height=1280}:rotate{angle=-90}}}:std{access=file,mux=mp4,dst=<outputfile>}\' vlc://quit

#Allowing blanks in file names
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

#Bit Rate
BR=16384

#where to store fixed files
FIXED_FILES_DIR="fixedFiles"
#rm -rf $FIXED_FILES_DIR
mkdir $FIXED_FILES_DIR

# VLC
VLC_START="/Applications/VLC.app/Contents/MacOS/VLC -I dummy -vvv"
VLC_END="vlc://quit"


#############################################
# Processing of MOV in the wrong orientation
for f in `find . -regex '\./.*\.MOV'` 
do
  ROTATION=`exiftool "$f" |grep Rotation|cut -c 35-38`
  SHORT_DIMENSION=`exiftool "$f" |grep "Image Size"|cut -c 39-43|sed 's/x//'`
  BITRATE_INT=`exiftool "$f" |grep "Avg Bitrate"|cut -c 35-38|sed 's/\..*//'`
  echo Short dimension [$SHORT_DIMENSION] $BITRATE_INT

  if test "$ROTATION" != ""; then
    DEST=$(dirname ${f})
    echo "Processing $f with rotation $ROTATION in directory $DEST"
    mkdir -p $FIXED_FILES_DIR/"$DEST"

    if test "$ROTATION" == "0"; then
      cp "$f" "$FIXED_FILES_DIR/$f"

    elif test "$ROTATION" == "180"; then
#      $(eval $VLC_START \"$f\" "--sout="\'"#transcode{vfilter={rotate{angle=-"$ROTATION"}},vcodec=mp4v,vb=$BR}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
      $(eval ffmpeg -i \"$f\" -vf hflip,vflip -r 30 -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\")

    elif test "$ROTATION" == "270"; then
      $(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=2,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )

    else
#      $(eval $VLC_START \"$f\" "--sout="\'"#transcode{scale=1,width=$SHORT_DIMENSION,vcodec=mp4v,vb=$BR,vfilter={canvas{width=$SHORT_DIMENSION,height=$SHORT_DIMENSION}:rotate{angle=-"$ROTATION"}}}:std{access=file,mux=mp4,dst=\""$FIXED_FILES_DIR/$f"\"}'" $VLC_END )
      echo ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" 
      $(eval ffmpeg -i \"$f\" -vf "scale=$SHORT_DIMENSION:-1,transpose=1,pad=$SHORT_DIMENSION:$SHORT_DIMENSION:\(ow-iw\)/2:0" -r 30 -s "$SHORT_DIMENSION"x"$SHORT_DIMENSION" -metadata:s:v:0 rotate=0 -b:v "$BITRATE_INT"M -vcodec libx264 -acodec copy \"$FIXED_FILES_DIR/$f\" )

    fi

  fi

echo 
echo ==================================================================
sleep 1
done

#############################################
# Processing of AVI files for my Panasonic TV
# Use ffmpegX + QuickBatch. Bitrate at 16384. Camera res 640x424
for f in `find . -regex '\./.*\.AVI'` 
do
  DEST=$(dirname ${f})
  DEST_FILE=`echo "$f" | sed 's/.AVI/.MOV/'`
  mkdir -p $FIXED_FILES_DIR/"$DEST"
  echo "Processing $f in directory $DEST"
  $(eval ffmpeg -i \"$f\" -r 20 -acodec libvo_aacenc -b:a 128k -vcodec mpeg4 -b:v 8M -flags +aic+mv4 \"$FIXED_FILES_DIR/$DEST_FILE\" )
echo 
echo ==================================================================

done

IFS=$SAVEIFS

1

Zostałem poproszony o edycję tego, przedmowę tekstu, wskazując, że rozwiązanie, które ostatecznie znalazłem, znajdowało się na końcu tekstu. Na koniec znajdziesz dwa kolejne polecenia ffmpeg, które pomyślnie obróciły moje wideo do właściwej orientacji. Tekst poprzedzający miał dać jak najwięcej informacji, jak mogłem, ponieważ widziałem inne wiadomości, które zostały odrzucone z powodu braku informacji. W każdym razie mam nadzieję, że pomoże to innym użytkownikom ffmpeg. Wydaje mi się, że hflip i vflip w ffmpeg są co najmniej mylące i sprzeczne z oczekiwaniami.

Plik merlin.mov jest kopią wideo, które nagrałem na iPhonie, najpierw przesłałem do Dropbox, a następnie pobrałem na laptopa z systemem Ubuntu:

    $ uname -a
    Linux gazelle 3.13.0-135-generic #184-Ubuntu SMP
    Wed Oct 18 11:55:51 UTC 2017 x86_64 x86_64 x86_64
    GNU/Linux

Wiem, że powinienem móc podłączyć iPhone'a przez USB i bezpośrednio skopiować pliki, ale to nie działało; mój laptop rozpoznałby, że iPhone jest podłączony, ale nie zamontowałby systemu plików, a na moim iPhonie nie pojawił się monit o „zaufanie” laptopowi.

Polecenie, którego użyłem do skopiowania z Dropbox na mój laptop to:

    cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
            merlin.mov

Oryginalny plik to wideo 1920 x 1080 Codec HEVC / H.265 Framerate 30 / sec, Bitrate 8140 kbps, Audio Codec MPEG-4 AAC Audio Channels Stereo, Częstotliwość próbkowania 44100 Hz, Bitrate 85 kbps. Kiedy gram na iPhonie, jest odpowiednio zorientowany, a dźwięk jest zsynchronizowany. Kiedy odtwarzam go w filmach na moim laptopie, jest on odwrócony do góry nogami i odwrócony w poziomie, a dźwięk nie jest zsynchronizowany. Oto częściowe dane wyjściowe z „ffmpeg -i merlin.mov”:

    Metadata:
    rotate          : 180
    creation_time   : 2017-11-02T14:41:55.000000Z
    handler_name    : Core Media Data Handler
    encoder         : HEVC

Oto pierwszy wiersz wyniku z „ffmpeg -version”:

ffmpeg wersja 3.3.3 Copyright (c) 2000-2017 deweloperzy FFmpeg

Następujące polecenie pozostawiło odtwarzanie odwrócone zarówno w pionie, jak iw poziomie, chociaż zostało ono przekonwertowane na wideo MPEG-4 (wideo / mp4) i zsynchronizowało dźwięk:

    ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4

Następujące elementy są odwrócone w pionie, aby odtwarzanie odbywało się w pozycji pionowej, zsynchronizowało dźwięk i zostało przekonwertowane do formatu MPEG-4, ale pozostawiło niepoprawnie odwrócony koniec dla końca (nie jest to literówka, określiłem „hflip”):

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4

Poniższe odwróciło poziomą pozycję do prawidłowej orientacji, ale pozostawiło odtwarzanie do góry nogami:

    ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4

Wydaje się, że następujące działania nie mają żadnego wpływu:

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
    ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4

Próbowałem również tego, na podstawie polecenia znalezionego w superuser.com. Pomyślnie zsynchronizował dźwięk i przekonwertował go na MPEG-4, ale orientacja pozioma i pionowa pozostała niepoprawna:

    ffmpeg -i merlin.mov \
            -vf "rotate=PI:bilinear=0,format=yuv420p" \
            -metadata:s:v rotate=0 -codec:v libx264 \
            -codec:a copy merlinrotate.mp4

Próbowałem też tego, co również nie działało w zakresie korekty orientacji:

    ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4

Następujący 2-etapowy proces w końcu uzyskał to, czego chciałem; pionowy i poziomy zarówno odwrócony, zsynchronizowany z dźwiękiem, jak i format przekonwertowany na MPEG-4 (Ponownie, to nie jest literówka; w obu poleceniach użyłem hflip):

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
    ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4

Chociaż długo - to dla mnie wygląda na odpowiedź - po prostu przeszedł przez proces rozwiązywania problemów.
Journeyman Geek

@JourneymanGeek Rzeczywiście masz rację. Widzę teraz w jego ostatnim akapicie Następujący dwuetapowy proces w końcu uzyskał to, czego chciałem . Dobre oko. (Naprawdę przeczytałem cały post, ale moje oczy prawdopodobnie przeszły się szybą, zanim tam dotarłem).
Mówię: Przywróć Monikę

Dobra robota poprawiająca twoją odpowiedź. Zrobiłeś dobrze, aby podać wystarczającą ilość szczegółów dla swojej odpowiedzi. Rozglądając się po witrynie, spróbuj zaobserwować, jak inne dobre odpowiedzi równoważą jasność ze szczegółami.
Mówię: Przywróć Monikę

0

Oto kroki:

  1. Najpierw otwórz plik wideo w QuickTime. Możesz najpierw uruchomić QuickTime, przejść do „Plik”, a następnie do „Otwórz plik”. Możesz też kliknąć plik prawym przyciskiem myszy, wybrać „Otwórz za pomocą”, a następnie QuickTime.

  2. Po otwarciu filmu kliknij „Edytuj”, a poniżej znajdziesz opcje obracania i odwracania

  3. Po zablokowaniu pożądanej orientacji musisz wyeksportować wideo z nowymi dodanymi zmianami. Opcja „Eksportuj” znajduje się w menu „Plik” w QuickTime.

Wybierz ustawienia pliku, które chcesz wyeksportować, i kliknij „OK”, aby rozpocząć eksport.

Po zakończeniu operacji eksportowania znajdziesz nowy plik w dowolnym miejscu, w którym chcesz go zapisać w odpowiedniej orientacji!

Cała ta poprawka zajęła mi mniej niż 5 minut, ale w zależności od długości filmu może to potrwać znacznie dłużej (lub krócej, znowu się różni).

źródło bloga


0
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4

Wykonał dla mnie lewę. Nie jestem pewien, dlaczego filtr transpozycji nie zapewnia możliwości obrotu o 180 stopni na raz, ale cokolwiek. Sprawdź Dokumenty, aby uzyskać więcej informacji.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.