OpenGL/ALSA環境向けキャプチャツールglcでキャプチャした動画ファイルを無劣化の形式にエンコードする
glcではキャプチャした内容を劣化のない形式で保存するが、これは一般的な動画プレーヤでは再生できず、再生できるようにするにはglc-playによる変換が必要となるが、yuv4mpeg形式も連番PNG形式もディスク領域を大きく使用してしまう。
「OpenGLアプリケーションが快適にキャプチャできるglcについて(キャプチャ、再生、エンコード)」の作業や「OpenGL/ALSA環境向けキャプチャツールglcの(H.264+AAC).mp4向けエンコード支援スクリプトを更新(2010/1/6版)」で扱ったスクリプトでは大きくファイルサイズを小さくできるが、可逆ではない(H.264 + AAC).mp4という形式を最終的に出力するようになっており、出力ファイルを動画編集ソフトで編集するのには向かない。
そこで、ロスレス(無劣化)指定のH.264コーデックを用いて中間ファイルとして使える「(H.264 ロスレス + WAVE).avi」形式のファイルを生成する用途のスクリプトを作成した。音声については現時点ではWAVEのまま(FLACにするとうまく再生できない)でファイルサイズは大きめになる(オプションで音声なしの出力にも対応した)が、KdenliveやOpenShotといった動画編集ソフトでクリップとして取り込んで再生が正常に行えることを確認した。拡大/縮小にも対応したが、この処理は可逆ではないので、拡大/縮小する場合は元の.glcファイルを消すことは推奨しない(消す場合は別途サイズ変更なしで変換してそれを残す)。
動作にはglcの他、Zenity,libx264,libx264サポート付きのFFmpegが必要。スレッド数はCPUの認識数から自動的に指定するようにした。MEncoderは使用していない。
スクリプトはテスト不足につき、不具合が残っている可能性がある。
[任意]ファイル名: glc2losslessavi.sh ライセンス: GPL-3 (or lator)
#! /bin/bash # glc -> (H.264 lossless + WAVE).avi convert/encode script # version 20110121 # (C) 2011 kakurasan # Licensed under GPLv3+ PATH=/bin:/usr/bin STREAM_AUDIO=1 STREAM_VIDEO=1 FPS=30 TMP_AUDIO=audio.wav OUTFILE=../glc2losslessavi-output.avi print_usage() { printf "Usage: %s ( [OPTIONS...] ) [INPUT] -a NUM use audio stream NUM -c WIDTHxHEIGHT scale to WIDTHxHEIGHT -d NUM use video stream NUM -f FPS set frame rate to FPS (default: %s) -h print help -m TERM display log using TERM (X terminal emulator) -o OUTFILE set output location -p use spline algorithm (with -c option, default: lanczos) -v video only Environment variables: GLCPLAY glc-play command (default: glc-play) FFMPEG ffmpeg command (default: ffmpeg) ICON use ICON for notification icon " ${0} ${BITRATE_AUDIO} ${FPS} ${BITRATE_VIDEO} } SCALE=0 SPLINE=0 VIDEOONLY=0 USE_XTERM=0 while getopts 'a:c:d:f:hm:o:pv' OPT do case ${OPT} in a) STREAM_AUDIO=${OPTARG} ;; c) SCALE=1 SIZE=${OPTARG} ;; d) STREAM_VIDEO=${OPTARG} ;; f) FPS=${OPTARG} ;; m) USE_XTERM=1 TERMINAL=${OPTARG} ;; o) OUTFILE="${OPTARG}" OUTDIR="$(dirname ${OUTFILE})" if [ ! -d "${OUTDIR}" ]; then if ! mkdir -p "${OUTDIR}"; then echo "Error: Cannot create output directory \"${OUTDIR}\"" >&2 exit 1 fi fi OUTFILE=$(cd $(dirname "${OUTFILE}") && pwd)/$(basename "${OUTFILE}") ;; p) SPLINE=1 ;; v) VIDEOONLY=1 ;; ?) print_usage exit 1 ;; esac done shift $((${OPTIND} - 1)) if [ ${#} -lt 1 ]; then print_usage exit 1 fi INFILE=${1} if [ ! -f ${INFILE} ]; then echo "Error: input file \"${INFILE}\" not found." >&2 exit 1 fi LOGFILE="$(printf ../glc2losslessavi-%s-%s.log "$(basename "${INFILE}")" $(date +%Y%m%d%H%M%S))" TEMPDIR=$(mktemp -d glc2losslessavi.XXXXXXXX) if [ ${?} -ne 0 ]; then echo "Error: cannot create tempdir" >&2 exit 1 fi INFILE=$(cd $(dirname ${INFILE}) && pwd)/$(basename ${INFILE}) cd ${TEMPDIR} GLCPLAY=${GLCPLAY:-glc-play} FFMPEG=${FFMPEG:-ffmpeg} SCALEFLAGS="" if [ ${SCALE} -eq 1 ]; then SCALEFLAGS="-s ${SIZE}" if [ ${SPLINE} -eq 1 ]; then SCALEFLAGS="${SCALEFLAGS} -sws_flags spline+print_info" else SCALEFLAGS="${SCALEFLAGS} -sws_flags lanczos+print_info" fi fi THREADSFLAGS="-threads $(egrep "^processor\s:\s[0-9]+$" /proc/cpuinfo | wc -l)" CMD_VIDEO_CONV="${GLCPLAY} -g \"0;0;1;1;1\" ${INFILE} -o - -y ${STREAM_VIDEO}" CMD_VIDEO="${FFMPEG} ${THREADSFLAGS} -i - ${SCALEFLAGS} -i ${TMP_AUDIO} -acodec copy -vcodec libx264 -vpre lossless_max -y -r ${FPS} ${OUTFILE}" CMD_VIDEO_NOAUDIO="${FFMPEG} ${THREADSFLAGS} -i - ${SCALEFLAGS} -vcodec libx264 -vpre lossless_max -y -r ${FPS} ${OUTFILE}" CMD_AUDIO_CONV="${GLCPLAY} -a ${STREAM_AUDIO} ${INFILE} -o ${TMP_AUDIO}" exec 3> >(zenity --notification --listen ${ICON:+--window-icon }${ICON:-}) touch "${LOGFILE}" if [ ${USE_XTERM} -eq 1 ]; then ${TERMINAL} -e tail -f "${LOGFILE}" & PID=${!} fi if [ ${VIDEOONLY} -eq 0 ]; then # extract audio (WAVE) echo "tooltip: ${CMD_AUDIO_CONV}" >&3 echo "${CMD_AUDIO_CONV}" >> "${LOGFILE}" ${CMD_AUDIO_CONV} >> "${LOGFILE}" 2>&1 || exit 1 if [ ! -f ${TMP_AUDIO} ]; then echo "audio not found" exit 1 fi echo "message: audio: done" >&3 # encode: (H.264 lossless + WAVE).avi echo "tooltip: ${CMD_VIDEO_CONV} | ${CMD_VIDEO}" >&3 echo "${CMD_VIDEO_CONV} | ${CMD_VIDEO}" >> "${LOGFILE}" ${CMD_VIDEO_CONV} | ${CMD_VIDEO} >> "${LOGFILE}" 2>&1 || exit 1 echo "message: video: done" >&3 else # encode: (H.264 lossless).avi echo "tooltip: ${CMD_VIDEO_CONV} | ${CMD_VIDEO_NOAUDIO}" >&3 echo "${CMD_VIDEO_CONV} | ${CMD_VIDEO_NOAUDIO}" >> "${LOGFILE}" ${CMD_VIDEO_CONV} | ${CMD_VIDEO_NOAUDIO} >> "${LOGFILE}" 2>&1 || exit 1 echo "message: video (no audio): done" >&3 fi echo "message: all done" >&3 if [ ${USE_XTERM} -eq 1 ]; then kill ${PID} fi cd .. rm ${TEMPDIR} -fr
関連記事:
- 「CLIとGUIの架け橋」zenity
- OpenGLアプリケーションが快適にキャプチャできるglcについて(キャプチャ、再生、エンコード)
- OpenGL/ALSA環境向けキャプチャツールglcの(H.264+AAC).mp4向けエンコード支援スクリプトを更新(2010/1/6版)
- x264とそのライブラリを用いたFFmpeg,MEncoderの可逆(ロスレス)エンコードに関する覚え書き(前半)
- x264とそのライブラリを用いたFFmpeg,MEncoderの可逆(ロスレス)エンコードに関する覚え書き(後半)
- Linux上で認識されるCPU(物理/コア/論理)の数に関するメモ(Linux 2.6.35時点)
- FFmpegで映像のエンコード時に拡大/縮小を行う際のオプション指定について(バージョン0.6.1時点)
使用したバージョン: