録画時に180°回転したビデオがあります。 FFmpegでこれを修正することは可能ですか?
以下の場合を除いて、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コンパイルガイド 。
2015年のv2.7リリース では、FFMPEGはデフォルトの動作を「回転」メタデータを持つ入力ビデオソースの自動回転に変更しました 。
あなたのスクリプトやコマンドが2.7より前のffmpegリリースでは決して実行されないことを知っているなら、最も簡単な解決策はメタデータに基づいてカスタムローテーションを削除することです。
それ以外の場合は、カスタムローテーションコードを保持し、-noautorotate
フラグを追加することで将来性を保証できます(これは当時まだ維持されていた古いバージョンでサポートされています)。
Ffmpegをデコードバックエンドとして使用するメディアプレーヤーも、そのフィルタをすべて利用できます。このスクリーンショットを "Offset&flip"フィルタで見てください。
あるいは、動画を再エンコードしたい場合は、Stackoverflowの FFmpeg で動画を回転するをチェックしてください。
以下は "fixedFiles"の下のディレクトリ構造を持つファイルを出力するbashスクリプトです。それは、iOSビデオを変換して回転させ、AVIをトランスコードします。スクリプトは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つの連続した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
ffmpeg -i input.mp4 -filter:v "transpose=1,transpose=1" output.mp4
私のためにトリックをしました。転置フィルタが一度に180度回転する可能性を提供しないのはよくわかりませんが、何でも。詳しくは ドキュメント をご覧ください。
手順は次のとおりです。
まずQuickTimeでビデオファイルを開きます。最初にQuickTimeを起動し、「ファイル」に移動してから「ファイルを開く」に移動することができます。または、ファイル自体を右クリックして「アプリケーションから開く」を選択してから「QuickTime」を選択することもできます。
ビデオが開いたら、[編集]をクリックすると、回転と反転のオプションがすぐ下に表示されます。
希望の向きをロックしたら、追加した新しい変更を加えてビデオをエクスポートする必要があります。 QuickTimeの[ファイル]メニューに[エクスポート]オプションがあります。
エクスポートしたいファイル設定を選択し、「OK」をクリックしてエクスポートを開始します。
エクスポート操作が完了すると、正しい方向で保存することを選択した場所に新しいファイルが見つかります。
この修正全体で完了するのに5分もかかりませんでしたが、ビデオの長さによっては、はるかに長い時間がかかる場合があります(または短くなりますが、やはり異なります)。