ffmpeg でやったことまとめ
なぜか今頃になって ffmpeg 多用する機会に恵まれてしまったので、なんのためにそのオプションを付けてしまったのかを記録として残しておく。
ffmpeg
のバージョン
ffmpeg -version
ffmpeg version 5.1 Copyright (c) 2000-2022 the FFmpeg developers
built with Apple clang version 13.1.6 (clang-1316.0.21.2.5)
configuration: --prefix=/usr/local/Cellar/ffmpeg/5.1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
libavutil 57. 28.100 / 57. 28.100
libavcodec 59. 37.100 / 59. 37.100
libavformat 59. 27.100 / 59. 27.100
libavdevice 59. 7.100 / 59. 7.100
libavfilter 8. 44.100 / 8. 44.100
libswscale 6. 7.100 / 6. 7.100
libswresample 4. 7.100 / 4. 7.100
libpostproc 56. 6.100 / 56. 6.100
ことに至った経緯は、h.264 でフォーマットされていても、Mac の場合、デフォルトで見られないケースがあるのでフォーマットを平滑化しようと考えたから。
Mac でも見えない → iPhone/iPad の標準でも見られないケースがある、と言うことでもある。
目標として、 h.264(avc1), yuv420p + aac あたりに落ち着いて欲しいのでそのように。
コーデック
-vcodec h264_videotoolbox -acodec aac
ビデオは h.264 で GPU 使いたかったので、videotoolbox
で、audio が aac
ハードウェアエンコードする場合、品質を固定するには bitrate を指定する必要があるので、元の動画の bitrate をそのまま採用することにした。いちいちチェックはアレなので、ファイル名渡して、自動的に拾ってくるようにしてる。空白の数が微妙だったので awk
でしれっと拾ってる。しかしなぜ、ffprobe
も ffmpeg
も標準エラー出力ばっかりなんだ。
shell 便利
ffprobe "${FILENAME}" 2>&1 | grep bitrate | awk '{print \$6}'
ここで取得した bitrate を、次のオプションに渡している。上記の実行結果は ${BITRATE}
に保管してる。
-b:v ${BITRATE}k
色の range が相性悪くて h.264(high) あたりになってしまい、結局 Mac で見られないケースには、次のオプションを指定。詳しくはよくわからん。
-bsf:v h264_metadata=video_full_range_flag=0
yuv420p
指定するのは、次のオプション。
-pix_fmt yuv420p
そんな感じで作った shell がこれ。わが家仕様なので、たまたまこうしたらちょうど良い結果になった。
#!/bin/sh
BASEDIR="before"
TARGETDIR="after"
FILENAME="${1##*/}"
FILEBODY="${FILENAME%.*}"
FILE_EXT="${FILENAME##*.}"
BASEFILE="${BASEDIR}/${FILENAME}"
BITRATE=`ffprobe "./${BASEFILE}" 2>&1 | grep bitrate | awk '{print \$6}'`
if [ ${FILE_EXT} = "ts" ]; then
OPT="-bsf:v h264_metadata=video_full_range_flag=0"
TARGETFILE="${TARGETDIR}/${FILEBODY}.mp4"
else
OPT="-pix_fmt yuv420p"
TARGETFILE="${TARGETDIR}/${FILENAME}"
fi
ffmpeg -i "${BASEFILE}" -vcodec h264_videotoolbox -acodec aac -b:v ${BITRATE}k ${OPT} "${TARGETFILE}"
時間指定のやつ忘れてた
動画をアニgif にする場合