Como girar um vídeo 180 ° com o FFmpeg?

69

Eu tenho um vídeo que foi girado 180 ° quando gravado. É possível corrigir isso com o FFmpeg?

Louis
fonte
Você está perguntando sobre lançá-lo durante uma reprodução ou recodificação com a orientação correta?
Mxx #
@Mxx Eu estava pensando em recodificar, mas o que você quis dizer com durante a reprodução?
Louis
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 ffdshow-tryout.sourceforge.net/images/front1.png "Offset and flip" filter. Veja também stackoverflow.com/questions/3937387/rotating-videos-with-ffmpeg
Mxx
Oh ok, legal. Isso funcionaria para mim, mas também quero compartilhá-lo. Vou dar uma olhada na pergunta SO.
Louis
5
A redação e o título desta pergunta são realmente confusos. Virar um vídeo na vertical não é o mesmo que girá-lo 180 graus (que é o mesmo que um giro vertical e um giro horizontal). Com base na resposta aceita, estou editando para especificar a rotação. Atualmente, isso polui os resultados do Google para inverter vídeos verticalmente com ffmpeg.
Jason C

Respostas:

102

originalgirado


tl; dr

ffmpeg girará o vídeo automaticamente, a menos que:

  • sua entrada não contém metadados de rotação
  • você ffmpegé muito velho

Metadados de rotação

Alguns 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 ffmpegsaí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

Auto rotação

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.

Exemplo

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

Para desativar esse comportamento, use a -noautorotateopção


Se a entrada não contiver metadados ou se você ffmpegfor antigo

Você 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:

Exemplos

Usando ffmpegvocê 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 rotatefiltro, a interpolação bilinear deve ser desativada (usando bilinear=0) para ângulos divisíveis por 90, caso contrário, pode parecer tremida.


Notas

  • 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=yuv420pdesde ffmpegque tentarei minimizar ou evitar a subamostragem de croma (dependendo do codificador, entrada, ffmpegversã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 copyopçã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.


Girar após a reprodução

Como alternativa, você pode girar durante a reprodução e evitar a recodificação. ffplaygirará 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.


Obtendo 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 .

llogan
fonte
Obrigado, acabei de tentar -vf vflipe funcionou como um encanto. Mas foi uma recodificação. Não tenho certeza se estou lendo você direito. Você está dizendo -vf hflip,vflipque não vai recodificar?
Louis
O @Louis ffmpegexige que você recodifique ao usar filtros de vídeo e áudio. No entanto, ffplaytambém pode utilizar muitos dos filtros durante a reprodução, como mostrado no meu segundo exemplo.
Llogan
Ah, não percebi que era um programa diferente.
Louis
Gostaria de saber se existe alguma maneira de preservar a qualidade do vídeo -codec:v libx264. Pode ffmpegapenas usar a mesma codificação sem que o usuário tente descobrir?
Sadi
11
@Louis rotateusa radianos como uma unidade em vez de graus. Eu acho que as pessoas estão mais familiarizadas com os diplomas, então tentei mostrar como usar os diplomas no exemplo. Um grau é igual a π / 180 radianos. Então, se você deseja girar 45 °, basta usar rotate="45*(PI/180)".
llogan
7

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 -noautorotatesinalizador (isso é suportado em versões mais antigas que ainda eram mantidas no momento).

Albin
fonte
2

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".insira a descrição da imagem aqui

Como alternativa, se você quiser recodificar o vídeo, confira Girando vídeos com FFmpeg no Stackoverflow.

Mxx
fonte
11
Infelizmente, o transposefiltro mencionado em Girando vídeos com FFmpeg não gira 180 ° até onde eu sei.
llogan
11
@LordNeckbeard não diretamente, mas você pode encadear dois transposefiltros para obter o efeito.
evilsoup
11
@ evilsoup Ah, sim, eu não pensei nisso. O raciocínio espacial é difícil; Vamos fazer compras. Sinta-se livre para atualizar minha resposta com um exemplo.
llogan
1

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
David Costa Faidella
fonte
1

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
Thomas Smith
fonte
Por muito tempo - isso me parece uma resposta - ele simplesmente passou pelo processo de solução de problemas.
Journeyman Geek
@JourneymanGeek Na verdade, você está correto. Agora vejo no seu parágrafo final. O processo de duas etapas a seguir finalmente conseguiu o que eu queria . Bom olho. (Eu realmente li o post inteiro, mas meus olhos provavelmente estavam vidrados quando cheguei lá).
Eu digo Restabelecer Monica
Bom trabalho, melhorando sua resposta. Você fez bem ao incluir detalhes suficientes para sua resposta. Ao dar uma olhada no site, tente observar como outras boas respostas equilibram a clareza com os detalhes.
Eu digo Reinstate Monica
0

Aqui estão os passos:

  1. 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.

  2. Quando o vídeo estiver aberto, clique em "Editar" e você encontrará as opções de rotação e rotação logo abaixo

  3. 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).

fonte do blog

Philippe Matray
fonte
0
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.

panepeter
fonte