動画処理

ffmpeg is needed to run bellows.
目次:
● 動画を回転したい
● 動画の音声レベルを下げたい
● 動画のサムネールを作りたい
● 複数の動画を連結して一つにまとめたい
● 動画の一部を切り取りたい
● Intel QSVで変換したい
●iOS/iPadOSで認識しないmp4(H.265)動画ファイルを認識できるようにする


動画を回転したい

youtube-dl でダウンロードした動画、たまにスマホ用とかで縦向き動画が横向きに倒れたものがありますよね(^^;;; それを補正します。動画・音声は一切触らず、メタデータをいじります。
動画によってはこれでは不十分な場合もあります。すみません。

$ ffmpeg -i 入力動画.mp4 -c copy -metadata:s:v rotate=時計周り回転数角度  出力動画.mp4

動画の音声レベルを下げたい

よく音量レベルがでかすぎて音割れする動画がありますよね。それを補正します。

$ ffmpeg -i 入力動画.mp4 -strict -2 -vcodec copy -af "volume=-15dB"  出力動画.mp4

※ volumeのところで指定しますが、単位は dB です。負の値を与えると音量を下げます。
※ 単位なしだと、音量レベルに掛け算するみたい。 volume=2 だと2倍に音量を上げ、volume=0.5 だと音量レベルを半分にするみたい。

動画のサムネールを作りたい

ファイルをアップロードしてゴニョゴニョするウェブシステムを作ってる内に、サムネール表示させたいな、と思いつつ、画像やPDFファイルなら ImageMagick の convert コマンドを使えばすぐできるんだけど、動画は・・・ってことで、ffmpeg を使えば簡単にできそうです、というか、簡単にできます。

$ ffmpeg -y -v quiet -ss 秒数 -i 入力動画.mp4 -vframes 1 -vf scale=200:-1 -vcodec png サムネール画像.png

※ 秒数は、動画開始後の何秒後かのフレームをサムネール画像にする。
※ scale=width:height のところで、 サムネールのサイズを決定する。
※ width/heightのどちらかを -1 にすると、他方のサイズは動画のアスペクト比から自動的に決定してくれる。
※ vcodec は サムネール画像のフォーマット。jpeg にする場合は、 mjpeg を指定。

長辺サイズを基準にサムネール画像のサイズを決定したい場合は、事前に ffprobeで width,height を抽出する必要がある・・・かも。

$ ffprobe -v quiet -print_format json -show_format -show_streams 入力動画.mp4

上記のようにすると、JSON形式で動画の情報を返してくれるので、PHPなら、exec関数なりsystem関数なりでJSONの結果を得て、json_decode関数で読んでやればいい。
大抵、streamsキーの値の配列の最初に動画が入っているので・・・

<?php
exec('ffprobe -v quiet -print_format json -show_format -show_streams 入力動画.mp4 2> /dev/null ',$result,$status);
if($status) 
  throw new Exception('ffprobe failed...');

$json = json_decode(implode('',$result));
$movie_stream = $json['streams'][0];
$width = $movie_stream['width'];
$heihgt = $movie_stream['height'];

複数の動画を連結して一つにまとめたい

エッチな動画やセクシーな動画、アイドルのイメージ動画など、ダウンロード販売サイトで作品を購入した時、DRMフリーの動画ファイルをダウンロードできる場合、一つの作品が複数のファイルに分割してある時がありますよね? そういうときはなるべくなら一つのファイルにまとめたいことがよくあります。
その場合、動画ファイルのパスを列挙したテキストファイルを ffmpeg で読み込んで連結することが可能です。

# 連結させたい動画ファイル(mp4ファイル)を一つのディレクトリにまとめて、そのディレクトリで・・・
$ ls *.mp4 | xargs -I{} echo file \'{}\' > files.txt

# 生成した files.txt を ffmpegに食わせます。
$ ffmpeg -safe 0 -f concat -i files.txt -c copy output.mp4

※ シェルスクリプトを一つ書いとけばラクかもしれません。

動画の一部を切り取りたい

長尺の動画で、この部分だけの動画が欲しい! っていう時、ありますよね。。。クライマックスシーンだけ!みたいな。そういうときに便利です。あらかじめ動画のタイムインデックスを調べておきます。また、-ss とか -to を使う時、入力ファイル指定 -i の位置には注意しないといけません。指定する順番を間違えると全く違った結果になると思います。

# ex. 01:23:45 から 02:34:56 までを切り取りたい!
$ ffmpeg -ss 01:23:45 -to 02:34:56 -i movie.mp4 -c copy movie-cut.mp4

※ ググると “-async 1” を入れる、みたい。音ずれ?があるときは入れた方がいいみたい。
※ よく分かんないです。すみません。m(__)m

Intel QSVで変換したい

動画に関する知識がないので正直わからん。

$ ffmpeg -i <入力ファイル> -vcodec h264_qsv -acodec copy -global_quality 15 <出力ファイル.mp4>

iOSで認識しないmp4(H.265)動画ファイルを認識できるようにする

H.265コーデックで作られた動画ファイルがたまにiPadやiPhoneで認識しない時があったりします。
たいていの場合、コーデックIDが “hev1” と埋め込まれているのが原因だということを知りました。iOSやiPadOSでは、なぜか hev1 ではなく、hvc1 と埋め込まれているものしか認識できないみたい? 詳細は分かりませんが、そういうことらしいです。

ってことで、映像と音声の内容は -c copy でコピーして、コーデックIDを変更すればいいようです。理屈は分かんないけど、ffmpegで一発です。

$ ffmepg -y -i <入力ファイル> -c copy -tag:v hvc1 <出力ファイル.mp4>