Come ruotare un video di 180 ° con FFmpeg?


69

Ho un video che è stato ruotato di 180 ° durante la registrazione. È possibile correggerlo con FFmpeg?


Stai chiedendo di capovolgerlo durante una riproduzione o ricodificare con l'orientamento corretto?
Mxx,

@Mxx Stavo pensando di ricodificare, ma cosa volevi dire durante la riproduzione?
Louis,

I lettori multimediali che utilizzano ffmpeg come backend di decodifica possono anche utilizzare tutti i suoi filtri. Guarda questo screenshot ffdshow-tryout.sourceforge.net/images/front1.png Filtro "Offset e capovolgi". Vedere anche stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg
Mxx

Oh okay, fico. Funzionerebbe per me, ma voglio anche condividerlo. Darò un'occhiata alla domanda SO.
Louis,

5
La formulazione e il titolo di questa domanda sono davvero confusi. Capovolgere verticalmente un video non equivale a ruotarlo di 180 gradi (che equivale a una rotazione verticale e una rotazione orizzontale). In base alla risposta accettata, sto modificando per specificare la rotazione. Attualmente si stanno inquinando i risultati di google per capovolgere verticalmente i video con ffmpeg.
Jason C,

Risposte:


102

originaleruotato


tl; dr

ffmpeg ruoterà automaticamente il video a meno che:

  • l'input non contiene metadati ruotati
  • sei ffmpegtroppo vecchio

Metadati di rotazione

Alcuni video, ad esempio da iPhone, non vengono capovolti fisicamente, ma contengono dati lato matrice display stream video o ruotano metadati. Alcuni giocatori ignorano questi metadati e altri no. Fai riferimento ffmpegall'output della console per vedere se il tuo input ha tali metadati:

$ 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

Rotazione automatica

ffmpeg ruoterà automaticamente il video fisicamente in base a tutti i metadati di rotazione del flusso video esistenti.

È necessario un build che includa il commit 1630224, dal 2 maggio 2015, per poter utilizzare la funzione di autorotazione.

Esempio

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

Per disabilitare questo comportamento utilizzare l' -noautorotateopzione.


Se l'input non contiene metadati o se ffmpegè vecchio

Dovrai utilizzare un filtro per ruotare il video e se esiste qualche metadata di rotazione, dovrà essere rimosso come mostrato negli esempi seguenti:

Esempi

Utilizzando ffmpegè possibile scegliere tra tre metodi di utilizzo dei filtri video per ruotare di 180 °.

hflip e 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

Questo filtro può ruotare a qualsiasi angolo arbitrario e utilizza i radianti come unità anziché gradi. Questo esempio ruoterà π / 1 radianti 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

Puoi invece usare i gradi. Un grado è uguale a π / 180 radianti. Quindi se vuoi ruotare di 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

Quando si utilizza il rotatefiltro, l'interpolazione bilineare deve essere disattivata (utilizzando bilinear=0) per angoli divisibili per 90, altrimenti potrebbe apparire sfocata.


Appunti

  • Il filtro richiede la codifica. Questi esempi rendono le uscite video H.264. Consulta la Guida alla codifica video FFmpeg H.264 per indicazioni su come ottenere la qualità desiderata.

  • Sottocampionamento Chroma. Ho incluso format=yuv420ppoiché ffmpegtenterò di ridurre al minimo o evitare il sottocampionamento del chroma (a seconda dell'encoder, dell'input, della ffmpegversione, ecc.). Questo è un buon comportamento in senso puramente tecnico, ma la maggior parte dei giocatori è incompatibile con schemi di campionamento cromatico più "avanzati". Questo è lo stesso dell'uso -pix_fmt yuv420, ma si trova convenientemente nella filterchain .

  • Copia l'audio. L' -codec:a copyopzione eseguirà lo streaming della copia (re-mux) invece della codifica. Non c'è motivo di ricodificare l'audio se si desidera solo manipolare il video (a meno che non si desideri convertire in un formato audio diverso). Ciò farà risparmiare tempo poiché la codifica richiede molto tempo e preserverà la qualità dell'audio.


Ruota al momento della riproduzione

In alternativa è possibile ruotare durante la riproduzione ed evitare la ricodifica. ffplayruoterà automaticamente:

ffplay input.mp4

Se non ci sono dati lato displaymatrix o ruota metadati, puoi usare i filtri:

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

... o fai riferimento al tuo giocatore preferito. La maggior parte dei giocatori che vale la pena usare, come VLC, ha questa capacità.


ottenere ffmpeg

Le build precedenti di ffmpeg non includono funzionalità di filtro. Consulta la pagina di download di FFmpeg per diverse opzioni, tra cui comode build per Linux, OS X e Windows, oppure fai riferimento al Wiki FFmpeg per le guide dettagliate alla compilazione di ffmpeg .


Grazie, ho appena finito di provare -vf vflipe ha funzionato come un fascino. Ma era una ricodifica. Non sono sicuro se ti sto leggendo bene. Stai dicendo -vf hflip,vflipche non ricodificherà?
Louis,

@Louis ffmpegrichiede di ricodificare nuovamente quando si utilizzano filtri video e audio. Tuttavia, ffplaypuò anche utilizzare molti dei filtri durante la riproduzione, come mostrato nel mio secondo esempio.
Llogan,

Ah, non ho notato che era un programma diverso.
Louis,

Mi chiedo se esiste un modo per preservare la qualità del video oltre a -codec:v libx264? Puoi ffmpegsemplicemente usare la stessa codifica senza che l'utente cerchi di capirla?
Sadi,

1
@Louis rotateusa i radianti come unità anziché gradi. Penso che le persone abbiano più familiarità con i gradi, quindi ho provato a mostrare come usare i gradi nell'esempio. Un grado è uguale a π / 180 radianti. Quindi, se si desidera ruotare di 45 °, utilizzare semplicemente rotate="45*(PI/180)".
Llogan il

7

FFMPEG ha modificato il comportamento predefinito per ruotare automaticamente le sorgenti video di input con "ruota" i metadati nella versione v2.7 nel 2015 .

Se sai che il tuo script o comando non verrà mai eseguito su versioni di ffmpeg precedenti alla 2.7, la soluzione più semplice è rimuovere qualsiasi rotazione personalizzata basata sui metadati.

Per altri casi, è possibile eseguire le prove future conservando il proprio codice di rotazione personalizzato e aggiungendo il -noautorotateflag (questo è supportato nelle versioni precedenti che erano ancora gestite al momento).


2

I lettori multimediali che utilizzano ffmpeg come backend di decodifica possono anche utilizzare tutti i suoi filtri. Guarda questa schermata con il filtro "Offset e capovolgi".inserisci qui la descrizione dell'immagine

In alternativa, se desideri ricodificare il tuo video, dai un'occhiata a Rotazione dei video con FFmpeg su Stackoverflow.


1
Sfortunatamente il transposefiltro indicato in Rotazione dei video con FFmpeg non ruoterà di 180 ° per quanto ne so.
Llogan,

1
@LordNeckbeard non direttamente, ma è possibile concatenare due transposefiltri per ottenere l'effetto.
evilsoup,

1
@evilsoup Ah, sì, non ci ho pensato. Il ragionamento spaziale è difficile; andiamo a fare shopping. Sentiti libero di aggiornare la mia risposta con un esempio.
llogan

1

Di seguito è riportato uno script bash che produrrà i file con la struttura di directory in "fixedFiles". Trasforma e ruota video iOS e transcodifica AVI. Lo script si basa sull'aver installato sia exiftool che 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

Mi è stato chiesto di modificarlo, di prefigurare il testo, indicando che la soluzione che ho trovato alla fine era alla fine del testo. Quindi, alla fine, troverai i due comandi consecutivi di ffmpeg che hanno ruotato con successo il mio video con l'orientamento corretto. Il testo precedente che aveva lo scopo di fornire quante più informazioni possibili, come avevo visto altri messaggi che erano stati respinti a causa della mancanza di informazioni. Spero comunque che questo aiuti gli altri a usare ffmpeg. Mi sembra che lo scopo di hflip e vflip in ffmpeg sia, almeno, confuso e contrario a quanto mi aspettassi.

Il file merlin.mov è una copia di un video che ho fatto sul mio iPhone, prima caricato su Dropbox, quindi scaricato sul mio laptop, con 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

So che avrei dovuto essere in grado di montare il mio iPhone via USB e di aver copiato i file direttamente, ma non ha funzionato; il mio laptop avrebbe riconosciuto che l'iPhone era collegato, ma non montava il suo filesystem e non ho ricevuto alcuna richiesta sul mio iPhone di "fidarmi" del laptop.

Il comando che ho usato per copiare da Dropbox sul mio laptop era questo:

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

Il file originale è Video 1920 x 1080 Codec HEVC / H.265 Framerate 30 / sec, Bitrate 8140 kbps, Codec audio MPEG-4 AAC canali audio Stereo, Frequenza di campionamento 44100 Hz, Bitrate 85 kbps. Quando lo suono sul mio iPhone è orientato correttamente e il suono è sincronizzato. Quando lo riproduco in Video sul mio laptop è sia capovolto che capovolto orizzontalmente e il suono non è sincronizzato. Ecco un output parziale di "ffmpeg -i merlin.mov":

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

Ecco la prima riga di output da "ffmpeg -version":

ffmpeg versione 3.3.3 Copyright (c) 2000-2017 per gli sviluppatori FFmpeg

Quanto segue ha lasciato la riproduzione invertita sia in verticale che in orizzontale, sebbene sia stata convertita in video MPEG-4 (video / mp4) e ha sincronizzato il suono:

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

Il seguente invertito verticalmente in modo che la riproduzione sia verticale, sincronizzato il suono e convertito in MPEG-4, ma lasciato l'estremità capovolta in modo errato per l'estremità (questo non è un errore di battitura, ho specificato 'hflip'):

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

Quanto segue ha capovolto l'orizzontale con l'orientamento corretto, ma ha lasciato la riproduzione sottosopra:

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

Quanto segue sembrava non avere alcun effetto:

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

Ho anche provato questo, sulla base di un comando che ho trovato su superuser.com. Ha sincronizzato correttamente il suono e convertito in MPEG-4, ma l'orientamento orizzontale e verticale è rimasto errato:

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

Ho anche provato questo, che non ha funzionato neanche in termini di correzione dell'orientamento:

    ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4

Il seguente processo in 2 passaggi ha finalmente ottenuto quello che volevo; verticale e orizzontale entrambi capovolti, suono sincronizzato e formato convertito in MPEG-4 (Ancora una volta, questo non è un errore di battitura; ho usato hflip in entrambi i comandi):

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

Per quanto tempo - questa mi sembra una risposta - ha semplicemente seguito il suo processo di risoluzione dei problemi.
Journeyman Geek

@JourneymanGeek In effetti hai ragione. Ora vedo nel suo paragrafo finale Il seguente processo in 2 passaggi ha finalmente ottenuto quello che volevo . Buon occhio. (Ho davvero letto l'intero post, ma probabilmente i miei occhi erano già finiti quando sono arrivato).
Dico Reintegrare Monica il

Ottimo lavoro nel migliorare la tua risposta. Hai fatto bene a includere dettagli sufficienti per la tua risposta. Mentre dai un'occhiata al sito, prova ad osservare come altre buone risposte bilanciano la chiarezza con i dettagli.
Dico Reintegrare Monica il

0

Ecco i passaggi:

  1. Per prima cosa apri il tuo file video in QuickTime. Puoi prima avviare QuickTime, andare su "File" e poi su "Apri file". Oppure puoi fare clic con il pulsante destro del mouse sul file stesso, scegliere "Apri con" e quindi scegliere QuickTime.

  2. Una volta aperto il video, fai clic su "Modifica" e troverai le opzioni di rotazione e rotazione direttamente sotto

  3. Dopo aver bloccato l'orientamento desiderato, devi esportare il video con le nuove modifiche che hai aggiunto. Troverai l'opzione "Esporta" nel menu "File" in QuickTime.

Scegliere le impostazioni del file che si desidera esportare come e fare clic su "OK", per dare il via all'esportazione.

Al termine dell'operazione di esportazione, troverai il tuo nuovo file ovunque tu abbia scelto di salvarlo con l'orientamento corretto!

L'intera correzione mi ha richiesto meno di 5 minuti per completare, ma a seconda della lunghezza del video, potrebbe richiedere molto più tempo (o più breve, di nuovo, varia).

fonte del blog


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

Ha fatto il trucco per me. Non so perché il filtro di trasposizione non offra la possibilità di ruotare di 180 gradi contemporaneamente, ma comunque. Controlla i documenti per ulteriori informazioni.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.