Comskip に生成されるvdrの時間計算をshell scriptでやる方法

comskip については以下を参照

www.jifu-labo.net

ここからの自動化処理の殆どが、perlだったりrubyだったり、はたまたWindows Batchだったり

Winユーザなら便利すぎる素晴らしいソフトウェアがあったり

github.com

そんなの無視してshell scriptで処理しようぜって話ですが、時間計算が結構めんどくさい

0:00:00.00 start
0:00:55.21 end
0:08:42.22 start
0:10:13.01 end
0:20:07.08 start
0:21:36.00 end
0:28:26.00 start
0:29:55.15 end

こんなのがあった場合、以下のように切り出したいわけです。

ffmpeg -i input.ts -ss 0:00:55.21 -t  82.88 -c copy output_1.ts
ffmpeg -i input.ts -ss 0:10:13.01 -t 632.03 -c copy output_2.ts
ffmpeg -i input.ts -ss 0:21:36.00 -t 649.28 -c copy output_3.ts
ffmpeg -i "concat:output_1.ts|output_2.ts|output_3.ts|output_4.ts" -c copy output.ts

while か for でいけそうですが、-t オプションが曲者な訳です そこで以下のように計算しました

t=$(echo "scale=2; `date '+%s.%2N' -d '0:00:55.21'` - `date '+%s.%2N' -d '0:08:42.22'`" | bc);

解説

date '+%s' -d '0:00:55.21'

で秒数変換されます。しかし、ffmpeg の -t オプションでは SS.MS で表記してるので

date '+%s.%2N' -d '0:00:55.21'

で SS.MS時間に変換ができます。このまま計算して

$((date '+%s.%2N' -d '0:00:55.21' - `date '+%s.%2N' -d '0:08:42.22'`))

といきたい所ですが、デフォルトのbashスクリプトでは小数点以下を含んだ計算に対応していません。そこでbcを使います。

echo "3.22 - 2.11" | bc

のような使い方をします。よって以下のようになる訳です。

echo "scale=2; `date '+%s.%2N' -d '0:00:55.21'` - `date '+%s.%2N' -d '0:08:42.22'`" | bc