動画処理

ffmpeg is needed to run bellows.
目次:
● 動画を回転したい
● 動画の音声レベルを下げたい
● 動画のサムネールを作りたい
● 複数の動画を連結して一つにまとめたい


動画を回転したい

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

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