web-dev-qa-db-fra.com

Rotation de vidéos avec FFmpeg

J'ai essayé de comprendre comment faire pivoter des vidéos avec FFmpeg. Je travaille avec des vidéos iPhone prises en mode portrait. Je sais comment déterminer les degrés de rotation actuels à l'aide de MediaInfo (excellente bibliothèque, d'ailleurs), mais je suis bloqué sur FFmpeg maintenant.

D'après ce que j'ai lu, vous devez utiliser une option vfilter . D'après ce que je vois, cela devrait ressembler à ceci:

ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4

Cependant, je ne peux pas que cela fonctionne. Tout d’abord, - vfilters n’existe plus, c’est maintenant - vf . Deuxièmement, je reçois cette erreur:

No such filter: 'rotate'
Error opening filters!

Autant que je sache, je dispose de FFmpeg dans toutes ses options. Running ffmpeg -filters indique ceci:

Filters:
anull            Pass the source unchanged to the output.
aspect           Set the frame aspect ratio.
crop             Crop the input video to x:y:width:height.
fifo             Buffer input images and send them when they are requested.
format           Convert the input video to one of the specified pixel formats.
hflip            Horizontally flip the input video.
noformat         Force libavfilter not to use any of the specified pixel formats
 for the input to the next filter.
null             Pass the source unchanged to the output.
pad              Pad input image to width:height[:x:y[:color]] (default x and y:
 0, default color: black).
pixdesctest      Test pixel format definitions.
pixelaspect      Set the pixel aspect ratio.
scale            Scale the input video to width:height size and/or convert the i
mage format.
slicify          Pass the images of input video on to next video filter as multi
ple slices.
unsharp          Sharpen or blur the input video.
vflip            Flip the input video vertically.
buffer           Buffer video frames, and make them accessible to the filterchai
n.
color            Provide an uniformly colored input, syntax is: [color[:size[:ra
te]]]
nullsrc          Null video source, never return images.
nullsink         Do absolutely nothing with the input video.

Avoir les options pour vflip et hflip sont super et tout, mais ils ça ne me mènera pas où je dois aller. J'ai besoin de la capacité de faire pivoter les vidéos de 90 degrés au minimum. 270 degrés serait une excellente option à avoir aussi bien. Où sont passées les options de rotation?

374
jocull

Rotation de 90 dans le sens des aiguilles d'une montre:

ffmpeg -i in.mov -vf "transpose=1" out.mov

Pour le paramètre transpose, vous pouvez passer:

0 = 90CounterCLockwise and Vertical Flip (default)
1 = 90Clockwise
2 = 90CounterClockwise
3 = 90Clockwise and Vertical Flip

Utilisez -vf "transpose=2,transpose=2" pour 180 degrés.

Assurez-vous d'utiliser une version récente de ffmpeg à partir d'ici (une construction statique fonctionnera correctement).

Notez que cela réencodera les parties audio et vidéo. Vous pouvez généralement copier le son sans le toucher, en utilisant -c:a copy. Pour changer la qualité vidéo, définissez le débit (par exemple avec -b:v 1M]) ou consultez le guide de codage H.264 si vous souhaitez les options VBR.

Une solution consiste également à utiliser ceci script de commodité .

612
Alexy

Si vous ne souhaitez pas ré-encoder votre vidéo ET que votre lecteur puisse gérer les métadonnées de rotation, vous pouvez simplement modifier la rotation dans les métadonnées à l'aide de ffmpeg:

ffmpeg -i input.m4v -metadata:s:v rotate="90" -codec copy output.m4v
115
Rodrigo Polo

Avez-vous essayé transpose encore? J'aime (de l'autre réponse)

 ffmpeg -i input -vf transpose=2 output

Si vous utilisez une ancienne version, vous devez mettre à jour ffmpeg si vous souhaitez utiliser la fonctionnalité de transposition, telle qu'elle a été ajoutée en octobre 2011.

La page FFmpeg télécharger propose des versions statiques que vous pouvez exécuter directement sans devoir les compiler.

80
rwilliams

Je suis tombé sur cette page en cherchant la même réponse. Cela fait maintenant six mois que cela a été demandé à l'origine et les versions ont été mises à jour plusieurs fois depuis. Cependant, je voulais ajouter une réponse à toute personne qui se trouve ici à la recherche de cette information.

J'utilise Debian Squeeze et FFmpeg version à partir de ces référentiels.

La page MAN de ffmpeg indique l’utilisation suivante

ffmpeg -i inputfile.mpg -vf "transpose=1" outputfile.mpg

La clé étant que vous ne devez pas utiliser une variable de degré, mais une variable de réglage prédéfinie de la page MAN.

0=90CounterCLockwise and Vertical Flip  (default) 
1=90Clockwise 
2=90CounterClockwise 
3=90Clockwise and Vertical Flip
18
Zonjai

Pour faire pivoter l'image dans le sens des aiguilles d'une montre, vous pouvez utiliser le filtre de rotation, qui indique un angle positif en radians. Avec 90 degrés équivalant à PI/2, vous pouvez le faire comme suit:

ffmpeg -i in.mp4 -vf "rotate=PI/2" out.mp4

dans le sens anti-horaire l'angle doit être négatif

ffmpeg -i in.mp4 -vf "rotate=-PI/2" out.mp4

Le filtre de transposition fonctionnera également bien à 90 degrés, mais pour les autres angles, il s'agit d'un choix plus rapide ou unique.

14
Bijou Trouvaille
ffmpeg -vfilters "rotate=90" -i input.mp4 output.mp4 

ne fonctionnera pas, même avec la dernière source ...

doit changer l'ordre:

ffmpeg -i input.mp4 -vf vflip output.mp4

fonctionne bien

11
nano

Si vous obtenez un message "Le codec est expérimental mais les codecs expérimentaux ne sont pas activés", utilisez ceci:

ffmpeg -i inputFile -vf "transpose=1" -c:a copy outputFile

Arrivé avec moi pour certains fichiers .mov avec audio AAC.

6
sabujp

Ce script produira les fichiers avec la structure de répertoires sous "fixedFiles". À l'heure actuelle est fixé aux fichiers MOV et va exécuter un certain nombre de transformations en fonction de la "rotation" originale de la vidéo. Fonctionne avec les vidéos iOS capturées sur un Mac exécutant Mavericks, mais devrait être facilement exportable. Repose sur avoir installé les deux exiftool et 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
3

La réponse d'Alexy a presque fonctionné pour moi, sauf que j'avais cette erreur:

base de temps 1/90000 non prise en charge par la norme MPEG 4, la valeur maximale admise pour le dénominateur de base de temps est 65535

Je devais juste ajouter un paramètre (-r 65535/2733) à la commande et cela fonctionnait. La commande complète était donc:

ffmpeg -i in.mp4 -vf "transpose=1" -r 65535/2733 out.mp4
2
smoyth

Malheureusement, la version Ubuntu de ffmpeg prend en charge les filtres vidéo.

Vous devez utiliser avidemux ou un autre éditeur pour obtenir le même effet.

De manière programmatique, mencoder a été recommandé.

1
ldig