radikoサーバ仕様変更

オイラはFreeBSDでrtmpdump使ってradikoを録音しとるわけなんですが、昨日のTOP5録音を失敗していたので調べたら、radikoの仕様が変わったそうです。

古い記述だとこんな感じでエラーになります。
RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
Connecting ...
ERROR: RTMP_Connect0, failed to connect socket. 61 (Connection refused)

アチコチで見かけるスクリプトに、細かいところで手を入れてるスクリプトを公開しときます。
FreeBSD用のスクリプトなので、他のOSの場合は適当に修正する必要があります。dateんところのオプションとか。
outputbaseは環境にあわせて書き換えて。

2014.9.13修正: URIが変わったらしいのでそれ反映。あと、リトライ時の修正を目的にちょいと書き換えてます。

#!/bin/sh

PATH=${PATH}:/usr/local/bin; export PATH
LANG=C; export LANG

playerurl=http://radiko.jp/player/swf/player_3.0.0.01.swf
playerfile=/tmp/player.swf
keyfile=/tmp/authkey.png
outputbase=/home/ykvym/radiko_out
outputdateline=$( date -v +1M +%Y%m%d%H%M )

if [ $# -eq 2 ]; then
channel=$1
backEndTime=$2
else
echo "usage : $0 channel_name back_end"
exit 1
fi


#
# get player
#
getPlayer() {
if [ ! -f ${playerfile} ]; then
wget -q -O ${playerfile} ${playerurl}

if [ $? -ne 0 ]; then
echo "failed get player"
exit 1
fi
fi
}

#
# get keydata (need swftool)
#
getKeydata() {
if [ ! -f ${keyfile} ]; then
swfextract -b 14 ${playerfile} -o ${keyfile}

if [ ! -f ${keyfile} ]; then
echo "failed get keydata"
exit 1
fi
fi

if [ -f auth1_fms ]; then
rm -f auth1_fms
fi

#
# access auth1_fms
#
wget -q \
--header="pragma: no-cache" \
--header="X-Radiko-App: pc_1" \
--header="X-Radiko-App-Version: 2.0.1" \
--header="X-Radiko-User: test-stream" \
--header="X-Radiko-Device: pc" \
--post-data='\r\n' \
--no-check-certificate \
--save-headers \
https://radiko.jp/v2/api/auth1_fms

if [ $? -ne 0 ]; then
echo "failed auth1 process"
exit 1
fi

#
# get partial key
#
authtoken=`perl -ne 'print $1 if(/x-radiko-authtoken: ([\w-]+)/i)' auth1_fms`
offset=`perl -ne 'print $1 if(/x-radiko-keyoffset: (\d+)/i)' auth1_fms`
length=`perl -ne 'print $1 if(/x-radiko-keylength: (\d+)/i)' auth1_fms`

partialkey=`dd if=${keyfile} bs=1 skip=${offset} count=${length} 2> /dev/null | base64`

echo "authtoken: ${authtoken} \noffset: ${offset} length: ${length} \npartialkey: ${partialkey}"

rm -f auth1_fms

if [ -f auth2_fms ]; then
rm -f auth2_fms
fi

#
# access auth2_fms
#
wget -q \
--header="pragma: no-cache" \
--header="X-Radiko-App: pc_1" \
--header="X-Radiko-App-Version: 2.0.1" \
--header="X-Radiko-User: test-stream" \
--header="X-Radiko-Device: pc" \
--header="X-Radiko-Authtoken: ${authtoken}" \
--header="X-Radiko-Partialkey: ${partialkey}" \
--post-data='\r\n' \
--no-check-certificate \
https://radiko.jp/v2/api/auth2_fms

if [ $? -ne 0 -o ! -f auth2_fms ]; then
echo "failed auth2 process"
exit 1
fi

echo "authentication success"

areaid=`perl -ne 'print $1 if(/^([^,]+),/i)' auth2_fms`
echo "areaid: ${areaid}"

rm -f auth2_fms
}

#
# rtmpdump
#
execRtmpdump() {

#
#get rec time
#
startUnixTime=$( date +%s )
backEndUnixTime=$( /usr/local/bin/ruby19 -e "require \"time\";t=Time.parse(\"${backEndTime} JST\"); p t.to_i" )
seconds=$( expr ${backEndUnixTime} - ${startUnixTime} )
if [ ${seconds} -lt 0 ]; then
seconds=$( expr 86400 + ${seconds} )
fi
rtmpdump -v \
-r "rtmpe://f-radiko.smartstream.ne.jp/" \
--playpath "simul-stream.stream" \
--app "${channel}/_definst_" \
-W ${playerurl} \
-C S:"" -C S:"" -C S:"" -C S:${authtoken} \
--live -B ${seconds} \
--flv ${output}
RET=$?
rm -f ${keyfile}
return ${RET}
}

###

count=0
RET=9
while [ ${RET} -ne 0 ]
do
count=$(expr ${count} + 1)
if [ ${count} -gt 20 ]; then
exit 1
fi
output=${outputbase}/${channel}_${outputdateline}_${count}.flv
getPlayer
getKeydata
execRtmpdump
RET=$?
sleep 1
done



スクリプトは第一引数は局、第二引数は録音終了時刻をHH:MMフォーマットで指定します。
> /dokoka/bin/radiko.sh TBS 0:30 >/dev/null 2>&1
こんな感じ。
スクリプト内のoutputbaseで指定した場所にファイルが吐かれます。
rubyつかってunixtimeを引っ張ってますが、Linuxだとdateで出来るという話です。

全体的に他者が使うことを想定してないので、エラー判定とか処理が甘いです。

オイラはcronで動かしてます。
開始時間ちょうどに録音をはじめると最初部分が録れないので、一分早く起動するようにしてます。
なので、
outputdateline=$( date -v +1M +%Y%m%d%H%M )
とやってます。
リトライ箇所はこれでいいのかよくわかってませんが、いまんとこはこうしてます。リトライ契機はもうちょっと手を入れたいところ。残り分数で見るしかないよなあ・・・