FFmpegでビデオを回転させる


417

私はFFmpegでビデオを回転する方法を理解しようとしています。ポートレートモードで撮影したiPhoneビデオを使用しています。MediaInfo(優れたライブラリ、btw)を使用して現在の回転の角度を決定する方法を知っていますが、今はFFmpegに行き詰まっています。

私が読んだことから、使用する必要があるのはvfilterオプションです。私が見るところによると、それはこのように見えるはずです:

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

ただし、これを機能させることはできません。まず、-vfiltersはもう存在しません。現在は-vfになっています。第二に、私はこのエラーを受け取ります:

No such filter: 'rotate'
Error opening filters!

私の知る限り、私はFFmpegのすべてオプションのビルドを持っています。ffmpeg -filtersを実行すると、次のようになります。

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.

vfliphflipのオプションを用意するのはすばらしいことですが、それらを使用しても目的の場所に行けません。少なくともビデオを90度回転させる機能が必要です。270度も同様に優れたオプションです。回転オプションはどこにありますか?


私の答えを更新しました。そのフィルタは先月ソースに追加されたようです。
rwilliams 2010年

76
180度回転を検索する場合:-vf "vflip,hflip"
OrangeDog

4
これをデコードせずにビデオを再エンコードせずに実現できるかどうか疑問に思っています-jpegtranがJPEG画像をロスレスで回転できる方法...
Mikhail T.

2
回転フラグについてはこちらをご覧ください:stackoverflow.com/questions/15335073/...
Davor Josipovic

1
「transpose = 1、transpose = 1」で180度回転したビデオをvimeoにアップロードしました。回転した動画は再生できますが、vimeoで拒否されました。@OrangeDogのアプローチ-vf "vflip,hflip"は魅力のように機能します。
2016

回答:


682

時計回りに90回転:

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

転置パラメーターの場合は、次を渡すことができます。

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

-vf "transpose=2,transpose=2"180度使用します。

ここから最新のffmpegバージョンを使用してください(静的ビルドは正常に動作します)。

これはオーディオとビデオの部分を再エンコードすることに注意してください。通常、を使用して、オーディオに触れることなくオーディオをコピーできます-c:a copy。ビデオ品質を変更するには、ビットレートを(たとえばで-b:v 1M)設定するか、VBRオプションが必要な場合はH.264エンコーディングガイドを参照してください。

解決策は、この便利なスクリプトを使用することです。


8
ビデオにはまだ方向情報が含まれているため、iPhoneでビデオが正しく修正されなくなります。
srcspider 2013

25
このコマンドを使用すると、低品質のビデオ出力が得られます。ただし、今発見したように、このパラメーターも使用している場合を除きます-vcodec libx264。しかし、ffmpegがすでにそれを知っているはずなので、どのエンコーディングを使用するかを調べる必要がなかったら、それは素晴らしいことです。助言がありますか?
2013年

8
サディと同じように、元のビデオの品質を「コピー」する方法はありますか?
アレックジェイコブソン

58
180の場合は使用できます-vf "transpose=2,transpose=2"
Alex Pliutau

23
現在のドキュメントでは、「数値は非推奨であり、シンボリック定数を優先して削除する必要がある」と述べています。ffmpeg.org/ffmpeg-filters.html#transposeこのようにcclock_flipclockcclockまたはclock_flip代わりに012または3
l --marc l 2016年1

149

ビデオを再エンコードしたくない場合で、プレーヤーが回転メタデータを処理できる場合は、ffmpegを使用してメタデータの回転を変更できます。

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

11
最初に回転メタデータをチェックしてみてはいかがですかffmpeg -i input.m4v 2>&1 | grep rotate
Lidaobing

60
これは断然最良の答えです。しかし、やるべき改善が少しあります。ビデオの残りのメタデータ(日付、カメラなど)が失われないようにするには、を実行しますffmpeg -i input.m4v -map_metadata 0 -metadata:s:v rotate="90" -codec copy output.m4v。これにより、入力ファイルのすべてのグローバルメタデータがグローバルメタデータとして出力ファイルにコピーされ、ローテーションメタデータのみが変更されます。
migle

11
ポートレートモードのビデオがあり、それを「回転解除」して標準の1920x1080にしたい場合は、おそらくが必要ですrotate=0
mivk 2016年

1
試してみましたが-metadata:s:v rotate="180"、うまくいきませんでした。それはうまくいくはずですか?
OndraŽižka2017年

7
再エンコードが不要であり、ほとんどのビデオプレーヤーがメタデータローテーションをサポートするため、IMHOの最良のソリューション。また、Googleフォトなどのクラウドサービス。ただし、ffmpegが必ずしもすべてのメタデータを元のファイルからコピーするわけではないことに注意してください。したがって、私は明示的に、元のファイルから他のすべてのメタデータをコピーするために指定することをお勧めします:ffmpeg -i input.mp4 -codec copy -map_metadata 0 -metadata:s:v:0 rotate=0 output.mp4
アンドレアス・

83

もう試しましたtransposeか?のように(他の答えから)

 ffmpeg -i input -vf transpose=2 output

古いバージョンを使用している場合、トランスポーズ機能を使用するには、2011年10月に追加されたため、ffmpegを更新する必要があります。

FFmpeg ダウンロードページには、コンパイルすることなく直接実行できる静的ビルドが用意されています。


1
いいえ。それが存在することを知りませんでした。それを試してみます。
ジョクル

転置フィルターは私のFFmpegビルドには存在しないようです。どうすれば追加できますか?
10

2011-05-15時点のドキュメントのバージョンでは、正しいリンクはffmpeg.org/ffmpeg-doc.html#SEC93
Peter Hansenの

6
受け入れられた回答の1.5年前に有用な回答を提供したことで罰せられたようです。
rwilliams 2013年

1
@JonasBフィルターをコンマで区切ります。stackoverflow.com/questions/6195872/…を
rwilliams

19

同じ答えを探しているときにこのページに出くわしました。これが最初に要求されてから6か月が経過し、それ以来ビルドが何度も更新されています。しかし、私はこの情報を探してここに出くわした誰かのために答えを追加したかったのです。

私はそれらのリポジトリからDebian SqueezeとFFmpegバージョンを使用しています。

ffmpegのMANページには、次の使用法が記載されています

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

重要なのは、度数変数を使用するのではなく、MANページから事前定義された設定変数を使用することです。

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

情報をありがとう!私は通常、ソースからのビルドに問題があるため、実際にこれを機能させることはできませんでした。私はそれを今再び働かせることができるかどうか見るかもしれません。
ジョクル

transpose = 3は、イメージをミラーリングします
ダニエル神戸

transpose = 2は、270回転したビデオのミラーリングなしで機能しました
Daniel Kobe

17

画像を時計回りに回転するには、ラジアンで正の角度を示す回転フィルターを使用できます。90度がPI / 2と等しいので、次のように実行できます。

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

反時計回りの場合、角度は負でなければなりません

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

転置フィルターは90度でも同じように機能しますが、他の角度では、これはより高速であるか、唯一の選択肢です。


2
これは素晴らしい。*乗算として動作するため、ラジアンのより細かい分解能を得ることが可能であることがわかりました:ffmpeg -i in.avi -vf "rotate=-8*PI/40" -q 1 out.avi
eqzx

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

最新のソースを使用しても動作しません...

順序を変更する必要があります:

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

正常に動作します


これは、間違ったファイルにフィルターを適用しているためです... ffmpeg -i input.mp4 -vf "rotate = 90" output.mp4を試してみてください。それでうまくいきます
patrick

2
「ビデオをラジアンで表された任意の角度で回転させます。」ドキュメント:ffmpeg.org/ffmpeg-filters.html#rotateつまり、ラジアンrotate=PI/2またはrotate=90*PI/180が必要です
l --marc l

これは素晴らしい
Tessaracter

7

「コーデックは実験的ですが実験的コーデックが有効になっていません」というエラーが表示される場合は、次のコードを使用します。

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

aacオーディオを含む.movファイルで私と一緒に起こった。


これは私にとってうまくいった唯一の例でしたが、品質はひどく、非常にブロック状でした。また、1080x1920ビデオを352x640に縮小しました。スイッチが1つまたは2つ欠けていると思います。助言がありますか?
ロリッフェ2013

1
@LOlliffe add-sameq
Andrew Schleifer

2
@AndrewSchleiferありがとう。私はそれを試しましたが、ffmpegが私に投げ返しましたOption 'sameq' was removed. If you are looking for an option to preserve the quality (which is not what -sameq was for), use -qscale 0 or an equivalent quality factor option. Failed to set value '1' for option 'sameq': Invalid argument -qscaleもエラーを出します。Please use -q:a or -q:v, -qscale is ambiguous、まだ動作します。
ロリッフェ2013

3

「fixedFiles」の下のディレクトリ構造を持つファイルを出力するこのスクリプト。現時点ではMOVファイルに固定されており、ビデオの元の「回転」に応じていくつかの変換を実行します。Mavericksを実行しているMacでiOSでキャプチャしたビデオで動作しますが、簡単にエクスポートできるはずです。exiftool と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

2
痛い...これはうまくいくかもしれませんが、それは完全に恐ろしいです。まず第一に、シェルプログラミングの一般的なルール:パイプ内でgrep、cut、awk、またはsedの1つだけを必要とすることはありません。grep | cut | sedはすべて、sedまたはawkのいずれかで実行できます。次に、より具体的には、必要なタグのみを出力するようにexiftoolに要求できます。つまり、Rotationを除外する代わりに、「exiftool -Rotation」だけを出力します。第3に、それほど多くの「evals」は必要なく、「if test ...」は、読みやすさと効率の両方のために、ケース$ ROTATIONで置き換える必要があります。幸運を!
ミハイルT.13年

サイコロなし:[Parsed_pad_2 @ 0x7f8b15c3a580] Input area -420:0:1500:1080 not within the padded area 0:0:1080:1080 or zero-sized\ n ` [Parsed_pad_2 @ 0x7f8b15c3a580] Failed to configure input pad on Parsed_pad_2\ n Error reinitializing filters!\ n Failed to inject frame into filter network: Invalid argument\ n Error while processing the decoded data for stream #0:0\ nConversion failed!
Slipp D. Thompson

2

アレクシーの答えは、私がこのエラーを受け取っていたことを除いて、ほとんど私にとってうまくいきました:

タイムベース1/90000はMPEG 4標準ではサポートされていません。タイムベースの分母の最大許容値は65535です

コマンドにパラメーター(-r 65535/2733)を追加するだけで動作しました。したがって、完全なコマンドは次のとおりです。

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

「NTSCフィルム」のフレームレートを探している場合24000/1001は、より正確になります。
レイノ

2

最後に言及したソリューションとは異なるアプローチの追加のソリューションは、カメラドライバーがv4l2カメラコントロールをサポートしているかどうかを確認することです(これは非常に一般的です)。
ターミナルで次のように入力してください:

v4l2-ctl -L

カメラドライバーがv4l2カメラコントロールをサポートしている場合は、次のようになります(以下のリストは、カメラドライバーがサポートするコントロールによって異なります)。

               contrast (int)    : min=0 max=255 step=1 default=0 value=0 flags=slider
             saturation (int)    : min=0 max=255 step=1 default=64 value=64 flags=slider
                    hue (int)    : min=0 max=359 step=1 default=0 value=0 flags=slider
white_balance_automatic (bool)   : default=1 value=1 flags=update
            red_balance (int)    : min=0 max=4095 step=1 default=0 value=128 flags=inactive, slider
           blue_balance (int)    : min=0 max=4095 step=1 default=0 value=128 flags=inactive, slider
               exposure (int)    : min=0 max=65535 step=1 default=0 value=885 flags=inactive, volatile
         gain_automatic (bool)   : default=1 value=1 flags=update
                   gain (int)    : min=0 max=1023 step=1 default=0 value=32 flags=inactive, volatile
        horizontal_flip (bool)   : default=0 value=0
          vertical_flip (bool)   : default=0 value=0

運が良ければ、horizo​​ntal_flipvertical_flipをサポートします
次に、必要なことは次の方法でhorizo​​ntal_flipを設定することだけです。

v4l2-ctl --set-ctrl horizontal_flip=1

またはvertical_flip

v4l2-ctl --set-ctrl vertical_flip=1

次に、ビデオデバイスを呼び出して新しいビデオをキャプチャし(下の例を参照)、ビデオを回転または反転します。

ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -vcodec libx264 -f mpegts input.mp4

もちろん、既存のビデオを処理する必要がある場合は、この方法が目的のソリューションではありません。

このアプローチの利点は、センサーレベルで画像を反転するため、ドライバーのセンサーが既に画像を反転していることです。これにより、アプリケーション(FFmpegなど)をさらに不要な処理から節約できます。


ここでv4l2についての素晴らしい情報。記録時間で正しい向きに回転させることは明らかに望ましい:)これはほぼ10歳の質問(すごい!)それは任意のコンテキストを提供:)場合に役立ちます元々 iOSデバイスからアップロードされた動画について尋ねた
jocull

私はこのコミュニティでは少し新しいですが、この質問はここで私の年功よりはるかに古いです...私は本当にそれが良い(そして一般的な)質問だと思うので、この古い質問は多くのFFmpegユーザーを助け続けると信じています。
JM

1

残念ながら、ffmpegのUbuntuバージョンはビデオフィルターをサポートしています。

同じ効果を得るには、avidemuxまたはその他のエディターを使用する必要があります。

プログラム的な方法では、メンコーダーが推奨されています。


1
「Ubuntuバージョンのffmpegはビデオフィルターをサポートしていませ」という意味ですか?
user1438038

2
参考:「FFmpegはUbuntu 15.04 Vivid Vervetに戻ってきました。」またはUbuntu用にコンパイルできます。-> trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu
l --marc l

avconvは(14.04で)動作し、まったく同じように動作するようです。(しかし、それ以降のバージョンでは、必ずFFmpegを使用してください。)
SilverWolf-モニカを復活させる

1

スマートフォン:縦向きの形式で動画を録画しました

それをウェブサイドに送信したいのですが、左に90°(反時計回り、横向き)でした。

ffmpeg -i input.mp4 -vf "rotate=0" output.mp4

それを行います。縦書きに戻りました

debianバスター:ffmpeg --version ffmpegバージョン4.1.4-1〜deb10u1 Copyright(c)2000-2019 FFmpeg開発者

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.