ffmpegで手持ちの動画を任意のサイズ・ビットレートに一括変換するスクリプトを書いてみました。自分用なのでエラー処理は適当。私はスマホ用の低ビットレート動画をこのスクリプトを使って作成しています。もしもこのスクリプトを使う場合は、下記動作概要を理解した上でご利用ください。
重要な点は、一度エンコードした(された)ファイルはエンコード対象としないので、同じディレクトリに対して複数回スクリプトを実行しても安心ということです。
動作概要
・エンコード対象は、target_directory配下のtarget_dir_depthで指定した階層までにあり、mp4/avi/mpg拡張子のファイルでかつファイル名の先頭にencoded_と付いてないファイル
・v_bitrateの数値はビデオのビットレート、a_bitrateはオーディオのビットレートであり、動画の総ビットレートはv_bitrate + a_bitrateとなる
・オーディオはaac→aacであっても再エンコードされ劣化する(コピーを実装するのが面倒くさい)
・エンコードされたファイルのファイル名は、encoded_オリジナルのファイル名_enc_size.mp4で、output_dir配下のenc_sizeディレクトリに出力される
・エンコードが成功したオリジナルのファイル名は、先頭にencoded_とついたファイル名となる
#!/bin/sh
### Please edit the values to suit your environment
target_dir="/your/movie/folder"
output_dir="/your/movie/folder"
enc_size="320x240"
v_bitrate="300k"
a_bitrate="64k"
target_dir_depth="2"
###
### main
###
start_time=`date +%s`
count=0
# make output directory
if [ -e "${output_dir}/${enc_size}" ] ; then
if [ -w "${output_dir}/${enc_size}" ] ; then
:
else
echo "ERROR: You don't have write permissions to the output directory."
exit 1
fi
else
mkdir -p ${output_dir}/${enc_size} || exit 1
fi
# set Internal Field Separator
IFS="
"
# encode
for fullpath in `find ${target_dir}/ -maxdepth ${target_dir_depth}`
do
filename=${fullpath##*/}
suffix=${fullpath##*.}
if [ -f "${fullpath}" ] && [ ! -z "${filename%%encoded_*}" ] ;then
case ${suffix} in
mp4|avi|mpg)
ffmpeg -i "${fullpath}" -b:v ${v_bitrate} -b:a ${a_bitrate} -s ${enc_size} "${output_dir}/${enc_size}/encoded_${filename%.*}_${enc_size}.mp4" && mv "${fullpath}" "${fullpath%/*}/encoded_${filename}" && count=`expr ${count} + 1`;;
*)
echo "${filename} is skipped encoding, because the file type is not supported."
esac
else
continue
fi
done
# calculate processing time
finish_time=`date +%s`
p_time=`expr ${finish_time} - ${start_time}`
if [ ${count} -gt 0 ] ; then
echo "It took ${p_time} second(s) to encode processing of ${count} file(s)."
else
echo "This script did not do anything."
fi