Ho un video che è stato ruotato di 180 ° durante la registrazione. È possibile correggerlo con FFmpeg?
Ho un video che è stato ruotato di 180 ° durante la registrazione. È possibile correggerlo con FFmpeg?
Risposte:
ffmpeg
ruoterà automaticamente il video a meno che:
ffmpeg
troppo vecchioAlcuni 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 ffmpeg
all'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
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.
ffmpeg -i input.mp4 -c:a copy output.mp4
Per disabilitare questo comportamento utilizzare l' -noautorotate
opzione.
ffmpeg
è vecchioDovrai utilizzare un filtro per ruotare il video e se esiste qualche metadata di rotazione, dovrà essere rimosso come mostrato negli esempi seguenti:
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 rotate
filtro, l'interpolazione bilineare deve essere disattivata (utilizzando bilinear=0
) per angoli divisibili per 90, altrimenti potrebbe apparire sfocata.
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=yuv420p
poiché ffmpeg
tenterò di ridurre al minimo o evitare il sottocampionamento del chroma (a seconda dell'encoder, dell'input, della ffmpeg
versione, 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 copy
opzione 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.
In alternativa è possibile ruotare durante la riproduzione ed evitare la ricodifica. ffplay
ruoterà 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à.
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 .
-vf vflip
e ha funzionato come un fascino. Ma era una ricodifica. Non sono sicuro se ti sto leggendo bene. Stai dicendo -vf hflip,vflip
che non ricodificherà?
ffmpeg
richiede di ricodificare nuovamente quando si utilizzano filtri video e audio. Tuttavia, ffplay
può anche utilizzare molti dei filtri durante la riproduzione, come mostrato nel mio secondo esempio.
-codec:v libx264
? Puoi ffmpeg
semplicemente usare la stessa codifica senza che l'utente cerchi di capirla?
rotate
usa 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)"
.
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 -noautorotate
flag (questo è supportato nelle versioni precedenti che erano ancora gestite al momento).
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".
In alternativa, se desideri ricodificare il tuo video, dai un'occhiata a Rotazione dei video con FFmpeg su Stackoverflow.
transpose
filtro indicato in Rotazione dei video con FFmpeg non ruoterà di 180 ° per quanto ne so.
transpose
filtri per ottenere l'effetto.
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
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
Ecco i passaggi:
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.
Una volta aperto il video, fai clic su "Modifica" e troverai le opzioni di rotazione e rotazione direttamente sotto
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).