前提
- x1 ディレクトリに標準速度の動画が格納
- 元の動画は、 flv
- 新たに作る動画は mp4
- エンコーディングは 映像:mpeg4 (x264) 音声: AAC
- ffmpeg を利用。環境変数 PATH を適切に設定
- Windows + Mingw/MSYS
特徴
- 0.5倍から8倍まで簡単に速度を調整可能
- x2 x3 等のディレクトリは自動生成
- 作成済みの場合はスキップ
- ファイル作成中で異常終了したときはそのファイルの最初からやり直し
スクリプト
function filter(){
local -r speed=$1
local v="[0:v]setpts=PTS/${speed}[v]"
if [ $speed -le 2 ]; then
local a="[0:a]atempo=${speed}[a]"
elif [ $speed -le 4 ]; then
local a="[0:a]atempo=2,atempo=$speed/2[a]"
elif [ $speed -le 8 ]; then
local a="[0:a]atempo=2,atempo=2,atempo=$speed/4[a]"
fi
echo -filter_complex "$v;$a" -map [v] -map [a]
}
function speedup(){
local -r src=$1
local -r dst=$2
local -r speed=$3
local -r tmp=$(basename $dst .mp4)_tmp.mp4
[ -f $tmp ] && rm $tmp
local -r config="-crf 23 -c:a libvo_aacenc -ar 44100 -b:a 64k -c:v libx264 -qcomp 0.9 -preset slow -tune film -threads auto"
local -r args="-i $src $config $(filter $speed) $tmp"
ffmpeg $args && mv $tmp $dst
}
for speed in 2 3 4 5 6 7 8; do
for file in $(find ./x1 -name \*.flv) ; do
dst=$(echo $file | sed s/x1/x${speed}/ | sed s/flv$/mp4/ )
dir=$(dirname $dst)
mkdir -p $dir
[ -f $dst ] && continue
speedup $file $dst $speed
done
done
解説
- ffmpeg 関連
- setpts と atempo による速度の調整の詳細は、ffmpeg のWiki を参照
- atempo は 0.5 から 2.0 までしか指定できないが、連鎖させることで5倍速なども可能
- 5倍速の計算とかを 22*5/4 にすることで計算処理を単純化
- X264 のパラメータ関連
- crf は画質に関するパラメータ。23は高画質。29だとかなり低画質。 26 くらいでも全然かまわないかも。
- qcomp ビットレート変動量。デフォルト値が低すぎるので、 0.9 とか設定すると良いらしい。
- -preset slow ちょっと遅いが圧縮率がまずまず高くなる。medium とか fast とか veryfast とかも指定できる。
- -tune film を指定すると実写向けに最適なパラメータに。他に animation とかもある
- これだけ指定すれば他のパラメータはくわしく知らなくてもよさげ。
- シェルスクリプト関連
- x1 以下の flv をすべて処理するために find を利用
- && を利用することで、行数をちょっと減らしている
- basename の第2引数の指定は便利
- エンコは一旦、 ~_tmp.mp4 に対してすることで完了済みか処理途中の異常終了かを判断
- function で変数を使うとき local -r を使うと、行儀のいい、いい子ちゃんに見える
ひとりごと
- $((5 / 4)) とかだと、整数型でしか計算できないので結果が 1 になって困った
- perl とか bc を使う案もあったけど、ffmpeg に計算させることにした
- bc はそもそも Msys-git に含まれていなかった
- ffmpeg は Windows 版だと x264 や aacenc が最初からバンドルされていて便利
- x264 でのエンコは求める画質を crf で指定して、preset を slow するのが最適との結論
- 指定の簡単さ、エンコ速度、画質、出力ファイルサイズのバランスが取れている
- ビットレートを固定して two-pass にするのはエンコに時間かかる上に、画質がコントロールしづらい
- エンコ速度が重要なら veryfast とかも良い。(ファイルサイズは大きくなるが、画質は crf で指定したかんじになる)