Eu tenho um vídeo que foi girado 180 ° quando gravado. É possível corrigir isso com o FFmpeg?
Eu tenho um vídeo que foi girado 180 ° quando gravado. É possível corrigir isso com o FFmpeg?
Respostas:
ffmpeg
girará o vídeo automaticamente, a menos que:
ffmpeg
é muito velhoAlguns vídeos, como os de iPhones, não são fisicamente invertidos, mas contêm dados laterais da matriz de exibição de fluxo de vídeo ou alternam metadados. Alguns jogadores ignoram esses metadados e outros não. Consulte a ffmpeg
saída do console para ver se sua entrada possui esses metadados:
$ 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
girará fisicamente o vídeo automaticamente, de acordo com os metadados de rotação do fluxo de vídeo existentes.
Você precisa de uma compilação que inclua a confirmação 1630224, de 2 de maio de 2015, para poder usar o recurso de autorotação.
ffmpeg -i input.mp4 -c:a copy output.mp4
Para desativar esse comportamento, use a -noautorotate
opção
ffmpeg
for antigoVocê precisará usar um filtro para girar o vídeo e, se houver algum metadado de rotação, ele deverá ser removido, conforme mostrado nos exemplos abaixo:
Usando ffmpeg
você pode escolher entre três métodos de uso de filtros de vídeo para girar 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
Este filtro pode girar para qualquer ângulo arbitrário e usa radianos como uma unidade em vez de graus. Este exemplo girará π / 1 radianos ou 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
Você pode usar graus. Um grau é igual a π / 180 radianos. Então, se você deseja girar 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
Ao usar o rotate
filtro, a interpolação bilinear deve ser desativada (usando bilinear=0
) para ângulos divisíveis por 90, caso contrário, pode parecer tremida.
A filtragem requer codificação. Estes exemplos produzem saídas de vídeo H.264. Consulte o Guia de codificação de vídeo FFmpeg H.264 para obter orientação sobre como obter a qualidade desejada.
Subamostragem de croma. Incluí format=yuv420p
desde ffmpeg
que tentarei minimizar ou evitar a subamostragem de croma (dependendo do codificador, entrada, ffmpeg
versão etc.). Esse é um bom comportamento em um sentido puramente técnico, mas a maioria dos players é incompatível com esquemas de subamostragem de croma mais "avançados". É o mesmo que usar -pix_fmt yuv420
, mas está convenientemente localizado na cadeia de filtros .
Copie o áudio. A -codec:a copy
opção transmitirá a cópia (re-mux) em vez da codificação. Não há motivo para recodificar o áudio se você quiser apenas manipular o vídeo (a menos que queira converter para um formato de áudio diferente). Isso economizará tempo, pois a codificação é demorada e preserva a qualidade do áudio.
Como alternativa, você pode girar durante a reprodução e evitar a recodificação. ffplay
girará automaticamente:
ffplay input.mp4
Se não houver dados do lado da matriz de exibição ou girar metadados, você poderá usar filtros:
ffplay -vf "hflip,vflip" -i input.mp4
... ou consulte o seu jogador favorito. A maioria dos jogadores que vale a pena usar, como o VLC, tem esse recurso.
ffmpeg
As versões mais antigas do ffmpeg não incluem recursos de filtragem. Consulte a página de download do FFmpeg para obter várias opções, incluindo compilações convenientes para Linux, OS X e Windows, ou consulte o FFmpeg Wiki para obter os guias passo a passo de compilação do ffmpeg .
-vf vflip
e funcionou como um encanto. Mas foi uma recodificação. Não tenho certeza se estou lendo você direito. Você está dizendo -vf hflip,vflip
que não vai recodificar?
ffmpeg
exige que você recodifique ao usar filtros de vídeo e áudio. No entanto, ffplay
também pode utilizar muitos dos filtros durante a reprodução, como mostrado no meu segundo exemplo.
-codec:v libx264
. Pode ffmpeg
apenas usar a mesma codificação sem que o usuário tente descobrir?
O FFMPEG alterou o comportamento padrão para girar automaticamente as fontes de vídeo de entrada com metadados "rotate" na versão v2.7 em 2015 .
Se você sabe que seu script ou comando nunca será executado em versões do ffmpeg anteriores a 2.7, a solução mais simples é remover qualquer rotação personalizada com base nos metadados.
Para outros casos, você pode fazer a prova do futuro mantendo seu código de rotação personalizado e adicionando o -noautorotate
sinalizador (isso é suportado em versões mais antigas que ainda eram mantidas no momento).
Os players de mídia que usam o ffmpeg como um back-end de decodificação também podem utilizar todos os seus filtros. Veja esta captura de tela com o filtro "Offset & flip".
Como alternativa, se você quiser recodificar o vídeo, confira Girando vídeos com FFmpeg no Stackoverflow.
transpose
filtro mencionado em Girando vídeos com FFmpeg não gira 180 ° até onde eu sei.
transpose
filtros para obter o efeito.
A seguir, um script bash que produzirá os arquivos com a estrutura de diretórios em "FixedFiles". Ele transforma e gira vídeos do iOS e transcodifica AVIs. O script depende de ter instalado o exiftool e o 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
Me pediram para editar isso, prefaciar o texto, indicando que a solução que encontrei finalmente estava no final do texto. Portanto, no final, você encontrará os dois comandos ffmpeg consecutivos que rotacionaram meu vídeo com sucesso para a orientação correta. O texto anterior a ele deveria fornecer o máximo de informações possível, pois eu tinha visto outras mensagens que foram rejeitadas por falta de informações. Enfim, espero que isso ajude outras pessoas usando o ffmpeg. Parece-me que o objetivo do hflip e vflip no ffmpeg é, no mínimo, confuso e contrário ao que eu esperava.
O arquivo merlin.mov é uma cópia de um vídeo que gravei no meu iphone, primeiro carreguei no Dropbox e depois baixei no meu laptop, executando o 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
Sei que deveria ter conseguido montar meu iphone via USB e copiado os arquivos diretamente, mas isso não funcionou; meu laptop reconheceria que o iphone estava conectado, mas não montaria seu sistema de arquivos, e não recebi nenhum aviso no meu iphone para "confiar" no laptop.
O comando que eu costumava copiar do Dropbox para o meu laptop era o seguinte:
cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
merlin.mov
O arquivo original é Vídeo 1920 x 1080 Codec HEVC / H.265 Framerate 30 / seg, Taxa de bits 8140 kbps, Áudio Codec MPEG-4 AAC Canais de áudio Estéreo, Taxa de amostragem 44100 Hz, Taxa de bits 85 kbps. Quando o reproduzo no meu iphone, ele é orientado corretamente e o som é sincronizado. Quando o reproduzo nos Vídeos do meu laptop, ele é invertido e invertido horizontalmente, e o som não é sincronizado. Aqui está a saída parcial de "ffmpeg -i merlin.mov":
Metadata:
rotate : 180
creation_time : 2017-11-02T14:41:55.000000Z
handler_name : Core Media Data Handler
encoder : HEVC
Aqui está a primeira linha de saída de "ffmpeg -version":
ffmpeg versão 3.3.3 Copyright (c) 2000-2017 os desenvolvedores do FFmpeg
A seguir, a reprodução foi invertida vertical e horizontalmente, embora tenha convertido para vídeo MPEG-4 (vídeo / mp4) e sincronizado o som:
ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4
O seguinte foi invertido verticalmente para que a reprodução fique na vertical, sincronize o som e seja convertida para MPEG-4, mas deixe a horizontal invertida incorretamente de ponta a ponta (isso não é um erro de digitação, especifiquei 'hflip'):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
O seguinte virou a horizontal para a orientação correta, mas deixou a reprodução de cabeça para baixo:
ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4
O seguinte parecia não ter nenhum efeito:
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4
Eu também tentei isso, com base em um comando que encontrei em superuser.com. Sincronizou com sucesso o som e converteu para MPEG-4, mas as orientações horizontal e vertical permaneceram incorretas:
ffmpeg -i merlin.mov \
-vf "rotate=PI:bilinear=0,format=yuv420p" \
-metadata:s:v rotate=0 -codec:v libx264 \
-codec:a copy merlinrotate.mp4
Eu também tentei isso, o que também não funcionou em termos de correção da orientação:
ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4
O processo de duas etapas a seguir finalmente conseguiu o que eu queria; vertical e horizontal, invertida, com som sincronizado e formato convertido para MPEG-4 (novamente, isso não é erro de digitação; usei hflip nos dois comandos):
ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
Aqui estão os passos:
Primeiro, abra seu arquivo de vídeo no QuickTime. Você pode iniciar o QuickTime primeiro, vá em "Arquivo" e depois em "Abrir arquivo". Ou você pode clicar com o botão direito do mouse no arquivo em si, escolher "Abrir com" e depois escolher QuickTime.
Quando o vídeo estiver aberto, clique em "Editar" e você encontrará as opções de rotação e rotação logo abaixo
Depois de bloquear a orientação desejada, você deverá exportar seu vídeo com as novas alterações adicionadas. Você encontrará a opção "Exportar" no menu "Arquivo" no QuickTime.
Escolha as configurações de arquivo para as quais deseja exportar e clique em "Ok" para iniciar a exportação.
Quando a operação de exportação estiver concluída, você encontrará seu novo arquivo onde quer que você o tenha salvado com a orientação correta!
Toda essa correção levou menos de 5 minutos para ser concluída, mas, dependendo da duração do vídeo, poderia levar muito mais tempo (ou mais curto, mais uma vez, varia).
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4
Fiz o truque para mim. Não sei por que o filtro de transposição não oferece a possibilidade de girar 180 graus de uma só vez, mas seja o que for. Verifique o Documentos para mais informações.