録画時に180°回転したビデオがあります。FFmpegでこれを修正することはできますか?
録画時に180°回転したビデオがあります。FFmpegでこれを修正することはできますか?
回答:
ffmpeg
次の場合を除き、動画を自動的に回転させます:
ffmpeg
は年を取りすぎていますiPhoneなどの一部のビデオは、物理的に反転されていませんが、ビデオストリームディスプレイマトリックス側のデータが含まれているか、メタデータを回転しています。これらのメタデータを無視するプレーヤーと無視しないプレーヤーがいます。参照してください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
フィルターを使用する場合bilinear=0
、90で割り切れる角度に対して双線形補間をオフにする必要があります(そうしないと、ぼやけて見える場合があります)。
フィルタリングにはエンコードが必要です。これらの例は、H.264ビデオ出力を作成します。必要な品質を得るためのガイダンスについては、FFmpeg H.264ビデオエンコーディングガイドを参照してください。
クロマのサブサンプリング。エンコーダ、入力、バージョンなどに応じて、クロマサブサンプリングを最小化または回避しようとするためformat=yuv420p
、私は含めffmpeg
ましたffmpeg
。これは純粋に技術的な意味では良い動作ですが、ほとんどのプレーヤーは、より「高度な」クロマサブサンプリングスキームと互換性がありません。これはを使用するのと同じですが、-pix_fmt yuv420
便利なのはフィルターチェーンにあります。
オーディオをコピーします。この-codec:a copy
オプションは、エンコードではなくコピー(re-mux)をストリーミングします。ビデオのみを操作する場合は、オーディオを再エンコードする必要はありません(別のオーディオ形式に変換する場合を除く)。エンコードには時間がかかるため、これにより時間が節約され、オーディオの品質が維持されます。
または、再生時に回転し、再エンコードを回避できます。ffplay
自動的に回転します:
ffplay input.mp4
displaymatrix側のデータがない場合、またはメタデータを回転させる場合は、フィルターを使用できます。
ffplay -vf "hflip,vflip" -i input.mp4
...またはお気に入りのプレーヤーを参照します。VLCなど、使用する価値のあるほとんどのプレーヤーにはこの機能があります。
ffmpeg
ffmpegの古いビルドには、フィルタリング機能が含まれていません。Linux、OS X、およびWindows用の便利なビルドを含むいくつかのオプションについてはFFmpegダウンロードページを参照するか、ステップバイステップのffmpegコンパイルガイドについてはFFmpeg Wikiを参照してください。
-vf vflip
、それは魅力のように機能しました。しかし、それは再エンコードでした。私があなたを正しく読んでいるかどうかはわかりません。-vf hflip,vflip
再エンコードしないと言っていますか?
ffmpeg
では、ビデオおよびオーディオフィルターを使用するときに再エンコードする必要があります。ただし、ffplay
2番目の例に示すように、再生中に多くのフィルターを使用することもできます。
-codec:v libx264
だろうか?ffmpeg
ユーザーがそれを理解しようとせずに、同じエンコーディングを使用できますか?
デコードバックエンドとしてffmpegを使用するメディアプレーヤーも、そのすべてのフィルターを利用できます。「オフセットとフリップ」フィルターを使用したこのスクリーンショットをご覧ください。
または、動画を再エンコードする場合は、Stackoverflow でFFmpegを使用して動画を回転するをご覧ください。
transpose
フィルターを連結して効果を得ることができます。
以下は、「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
USB経由でiPhoneをマウントし、ファイルを直接コピーすることができたはずですが、それは機能しませんでした。私のラップトップは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 Copyright(c)2000-2017 FFmpeg開発者
次の例では、再生がMPEG-4ビデオ(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
手順は次のとおりです。
まず、QuickTimeでビデオファイルを開きます。最初にQuickTimeを起動し、「ファイル」に移動してから「ファイルを開く」に移動できます。または、ファイル自体を右クリックして「開く」を選択し、QuickTimeを選択することもできます。
ビデオが開いたら、「編集」をクリックすると、すぐ下に回転および反転オプションが表示されます。
目的の向きをロックしたら、追加した新しい変更をビデオにエクスポートする必要があります。QuickTimeの[ファイル]メニューの下に[エクスポート]オプションがあります。
エクスポートするファイル設定を選択し、「OK」をクリックしてエクスポートを開始します。
エクスポート操作が完了すると、正しい方向で保存することを選択した場所に新しいファイルが見つかります!
この修正全体を完了するのに5分もかかりませんでしたが、ビデオの長さによっては、もっと長くかかる場合があります(または、短くなりますが、繰り返します)。