web-dev-qa-db-ja.com

FFmpegでビデオを180°回転させる方法は?

録画時に180°回転したビデオがあります。 FFmpegでこれを修正することは可能ですか?

66
Louis

originalrotated


tl; dr

以下の場合を除いて、ffmpegは自動的にビデオを回転させます。

  • 入力に回転メタデータが含まれていません
  • あなたのffmpegは古すぎます

回転メタデータ

IPhoneなどの一部のビデオは、物理的に反転されていませんが、ビデオストリームdisplaymatrix側のデータや回転メタデータを含んでいます。何人かのプレーヤーはこれらのメタデータを無視し、何人かはそうしません。入力にそのようなメタデータが含まれているかどうかを確認するには、ffmpegコンソール出力を参照してください。

$ 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は、既存のビデオストリーム回転メタデータに従ってビデオを自動的に物理的に回転させます。

自動回転機能を使用するには、2015年5月2日からのコミット1630224を含むビルドが必要です。

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

この動作を無効にするには、-noautorotateオプションを使用します。


入力にメタデータが含まれていない場合、またはあなたのffmpegが古い場合

動画を回転させるにはフィルタを使用する必要があります。回転メタデータが存在する場合は、次の例に示すように削除する必要があります。

ffmpegを使用すると、ビデオフィルタを使用して180°回転する方法を3つ選択できます。

hflip および 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

このフィルタは任意の角度に回転でき、単位は度ではなくラジアンです。この例では、π/ 1ラジアン、または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

代わりに度数を使うことができます。 1度はπ/ 180ラジアンに等しい。あなたが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

rotateフィルタを使用するときは、90で割り切れる角度に対して双一次補間をオフにする必要があります(bilinear=0を使用することによって)。それ以外の場合はぼやけて見えます。


ノート

  • フィルタリングにはエンコードが必要です。これらの例では、H.264ビデオ出力を作成しています。希望する品質を得るためのガイダンスについては FFmpeg H.264ビデオエンコーディングガイド を参照してください。

  • クロマサブサンプリングffmpegはクロマサブサンプリングを最小化または回避しようとするので(エンコーダ、入力、ffmpegバージョンなど)、format=yuv420pを含めました。これは純粋に技術的な意味では良い振る舞いですが、ほとんどのプレーヤーはより「高度な」クロマサブサンプリング方式と互換性がありません。これは-pix_fmt yuv420を使用するのと同じですが、 filterchain にあります。

  • オーディオをコピーします。-codec:a copyオプションを指定すると、エンコードの代わりに stream copy (re-mux)になります。ビデオだけを操作したい場合は、オーディオを再エンコードする必要はありません(別のオーディオフォーマットに変換したい場合を除く)。エンコードは時間がかかるので、これは時間を節約し、オーディオの品質を維持します。


再生時に回転

あるいは、再生時に回転して再エンコードを避けることもできます。 ffplayは自動的に回転します:

ffplay input.mp4

Displaymatrix側のデータがない場合やメタデータを回転させる場合は、フィルタを使用できます。

ffplay -vf "hflip,vflip" -i input.mp4

...またはお気に入りのプレイヤーを参照してください。 VLCのように、使う価値のあるほとんどのプレーヤーはこの機能を持っています。


ffmpegを取得する

Ffmpegの古いビルドはフィルタリング機能を含みません。 Linux、OS X、およびWindows用の便利なビルドを含むいくつかのオプションについては FFmpeg download ページを参照するか、 FFmpeg Wiki /を参照 for ステップバイステップのffmpegコンパイルガイド

99
llogan

2015年のv2.7リリース では、FFMPEGはデフォルトの動作を「回転」メタデータを持つ入力ビデオソースの自動回転に変更しました

あなたのスクリプトやコマンドが2.7より前のffmpegリリースでは決して実行されないことを知っているなら、最も簡単な解決策はメタデータに基づいてカスタムローテーションを削除することです。

それ以外の場合は、カスタムローテーションコードを保持し、-noautorotateフラグを追加することで将来性を保証できます(これは当時まだ維持されていた古いバージョンでサポートされています)。

7
Albin

Ffmpegをデコードバックエンドとして使用するメディアプレーヤーも、そのフィルタをすべて利用できます。このスクリーンショットを "Offset&flip"フィルタで見てください。 enter image description here

あるいは、動画を再エンコードしたい場合は、Stackoverflowの FFmpeg で動画を回転するをチェックしてください。

2
Mxx

以下は "fixedFiles"の下のディレクトリ構造を持つファイルを出力するbashスクリプトです。それは、iOSビデオを変換して回転させ、AVIをトランスコードします。スクリプトはexiftoolffmpegの両方をインストールしたことに依存しています。

#!/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つの連続したffmpegコマンドを見つけるでしょう。その前のテキストは、情報が不足しているために他のメッセージが破棄されているのを見たのと同様に、できるだけ多くの情報を提供することを目的としていました。とにかく、これがffmpegを使っている人に役立つことを願っています。 ffmpegでのhflipとvflipの目的は、少なくとも混乱を招き、私が期待していたことに反することであると私には思われます。

ファイルmerlin.movは、私が私のiPhoneで撮ったビデオのコピーです。最初にDropboxにアップロードされ、そして私のラップトップにダウンロードされ、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

私は私のiPhoneをUSB経由でマウントしてファイルを直接コピーすることができたはずですが、それはうまくいきませんでした。私のラップトップはiphoneが接続されていることを認識しますが、そのファイルシステムをマウントしませんでした、そして私はラップトップを "信頼する"という私のiphoneのプロンプトを得ませんでした。

私がDropboxから私のラップトップにコピーするのに使ったコマンドはこれです:

    cp ~/Dropbox/Camera\ Uploads/Video\ Nov\ 02\,\ 9\ 41\ 55\ AM.mov \
            merlin.mov

元のファイルはビデオ1920 x 1080コーデックHEVC/H.265フレームレート30 /秒、ビットレート8140 kbps、オーディオコーデックMPEG-4 AACオーディオチャネルステレオ、サンプルレート44100 Hz、ビットレート85 kbps。私は自分のiPhoneでそれを再生すると、それは正しく方向づけられ、そして音は同期されます。ノートパソコンの動画で再生すると、上下左右が逆になり、音が同期しません。これは "ffmpeg -i merlin.mov"からの部分的な出力です。

    Metadata:
    rotate          : 180
    creation_time   : 2017-11-02T14:41:55.000000Z
    handler_name    : Core Media Data Handler
    encoder         : HEVC

これが "ffmpeg -version"からの出力の最初の行です。

ffmpegバージョン3.3.3著作権(c)2000-2017 FFmpeg開発者

次の例では、MPEG-4 video(video/mp4)に変換してサウンドを同期しましたが、再生は垂直方向と水平方向の両方で反転したままになりました。

    ffmpeg -i merlin.mov -vf 'hflip,vflip' merlinhflipvflip.mp4

次は垂直方向に反転して再生が直立し、音声が同期してMPEG-4に変換されましたが、水平方向が誤って反転していました(これはタイプミスではなく、 'hflip'を指定しました)。

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4

次の例では、水平方向を正しい方向に反転させていますが、再生を上下逆にしています。

    ffmpeg -i merlin.mov -vf 'vflip' merlinvflip.mp4

次のものはまったく効果がないようです。

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
    ffmpeg -i merlinhflip.mp4 -vf 'vflip' merlin2stepA.mp4

私もsuperuser.comで見つけたコマンドに基づいてこれを試しました。それはうまく音声を同期させ、MPEG-4に変換しました、しかし水平方向と垂直方向の両方が不正確なままでした:

    ffmpeg -i merlin.mov \
            -vf "rotate=PI:bilinear=0,format=yuv420p" \
            -metadata:s:v rotate=0 -codec:v libx264 \
            -codec:a copy merlinrotate.mp4

私もこれを試しましたが、オリエンテーションを修正するという意味ではうまくいきませんでした。

    ffmpeg -noautorotate -i merlin.mov merlinnoautorotate.mp4

次の2段階のプロセスで、ついに私の欲しいものが完成しました。垂直方向と水平方向の両方が反転され、音声が同期され、フォーマットがMPEG-4に変換されました(これもタイプミスではありません。両方のコマンドでhflipを使用しました)。

    ffmpeg -i merlin.mov -vf 'hflip' merlinhflip.mp4
    ffmpeg -i merlinhflip.mp4 -vf 'hflip' merlin2stepB.mp4
1
Thomas Smith
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4

私のためにトリックをしました。転置フィルタが一度に180度回転する可能性を提供しないのはよくわかりませんが、何でも。詳しくは ドキュメント をご覧ください。

0
panepeter

手順は次のとおりです。

  1. まずQuickTimeでビデオファイルを開きます。最初にQuickTimeを起動し、「ファイル」に移動してから「ファイルを開く」に移動することができます。または、ファイル自体を右クリックして「アプリケーションから開く」を選択してから「QuickTime」を選択することもできます。

  2. ビデオが開いたら、[編集]をクリックすると、回転と反転のオプションがすぐ下に表示されます。

  3. 希望の向きをロックしたら、追加した新しい変更を加えてビデオをエクスポートする必要があります。 QuickTimeの[ファイル]メニューに[エクスポート]オプションがあります。

エクスポートしたいファイル設定を選択し、「OK」をクリックしてエクスポートを開始します。

エクスポート操作が完了すると、正しい方向で保存することを選択した場所に新しいファイルが見つかります。

この修正全体で完了するのに5分もかかりませんでしたが、ビデオの長さによっては、はるかに長い時間がかかる場合があります(または短くなりますが、やはり異なります)。

ブログのソース

0
Philippe Matray