とてもご無沙汰しております。
昨日は「今日は一日アニソン三昧」でしたね。まどマギが5年前だということに気づいて老けこんだ方も多いのではないでしょうか。
で、実に4年ぶりの「アニソン三昧」なので、らじる★らじるで録音しようと思ってはりきってタスクスケジューラに登録しておいたわけですが、10時すぎに起きてきて確認したらわずか1分しか録音できていなかったんですね。そりゃ落ち込みますよ。
幸い RTMPExloreX という便利なソフトを知っていましたので、そちらで録音して第2部・第3部は無事だったわけですが、自分で rtmpdump を叩いて録音できなきゃタスクスケジューラに登録しようがないので、アニソン三昧を聞きつつ原因を探りましたので、そこで得た知見をここに記しておきます。
認証が必要だった
NHKらじる★らじるの録音が60秒で止まったら。: 技術系とかいろいろ書くブログ@京の街角
ググったらこのページにたどりつきました。やっぱり radiko と同じで認証が必要だったんですね。
手順を写させていただくと、
- http://www3.nhk.or.jp/netradio/files/swf/rtmpe.swf をダウンロード。
- 1. でダウンロードした SWF を解凍する。
- 2. で解凍した SWF を HMAC-SHA256 でハッシュ値をとる。
- rtmpdump で swfVfy に SWF の URL を指定するかわりに、 swfhash に 3. のハッシュ値を、swfsize に2. で解凍した SWF のファイルサイズを指定する。
という具合になっています。
SWFを解凍する?
SWF は Flash ファイルだろ?解凍ってなんだ?とお思いの方もいらっしゃるかもしれませんが、SWF のファイル形式は FWS、CWS、ZWS の3種類があります。
- FWS: 非圧縮の SWF ファイル。
- CWS: 最初の8バイト以降が ZLIB で圧縮された SWF ファイル。
- ZWS: 最初の8バイト以降が LZMA で圧縮された SWF ファイル。
1. の SWF ファイルは CWS なので、これを解凍して FWS にする必要があります。これに使えるプログラムとしては、 flasm とか cws2fws.exe などがあります。cws2fws は ffmpeg に付属していますが、そのままコンパイルすると挙動がおかしく正常に解凍できないので、私はそれに手を加えて自前で用意しました。それ以外でも、次のページで公開されているものはうまく動作するようです。
SWF decompressor & compressor (CWS->FWS, FWS->CWS)
シェルスクリプト
3. のハッシュ値をとる操作は、openssl を使うのが一般的なようです。
ということで、シェルスクリプトを書いてみました。wget、openssl、cws2fws、rtmpdump が使えることが前提です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
#!/bin/bash function usage() { echo "Usage: rec_rajiru channel [branch] filename duration" echo " channel=('R1'|'R2'|'FM')" echo " branch=('AK'|'BK'|'CK'|'HK'); 'AK' by default." exit 1 } if [ "$#" -ge 3 ]; then if [ "$1" != "R1" ] && [ "$1" != "R2" ] && [ "$1" != "FM" ]; then usage fi if [ "$1" = "R2" ]; then playpath="NetRadio_R2_flash@63342" fi if [ "$#" = 4 ] && ([ "$1" != "R1" ] || [ "$1" != "FM" ]); then if [ "$2" = "AK" ]; then if [ "$1" = "R1" ]; then playpath="NetRadio_R1_flash@63346" elif [ "$1" = "FM" ]; then playpath="NetRadio_FM_flash@63343" fi elif [ "$2" = "BK" ]; then if [ "$1" = "R1" ]; then playpath="NetRadio_BKR1_flash@108232" elif [ "$1" = "FM" ]; then playpath="NetRadio_BKFM_flash@108233" fi elif [ "$2" = "CK" ]; then if [ "$1" = "R1" ]; then playpath="NetRadio_CKR1_flash@108234" elif [ "$1" = "FM" ]; then playpath="NetRadio_CKFM_flash@108235" fi elif [ "$2" = "HK" ]; then if [ "$1" = "R1" ]; then playpath="NetRadio_HKR1_flash@108442" elif [ "$1" = "FM" ]; then playpath="NetRadio_HKFM_flash@108237" fi fi ch="$2$1" file="$3" dur="$4" elif [ "$#" = 4 ]; then ch="$1" file="$3" dur="$4" else ch="$1" file="$2" dur="$3" fi lc=`tr '[a-z]' '[A-Z]' <<< ${ch}` time=`date +"%s%3N"` rm -f "rtmpe_ver2015.swf" "rtmpe_ver2015_u.swf" wget -O "rtmpe_ver2015.swf" "http://www3.nhk.or.jp/netradio/files/swf/rtmpe_ver2015.swf?tm=${time}" cws2fws rtmpe_ver2015.swf rtmpe_ver2015_u.swf size=`wc -c rtmpe_ver2015_u.swf` hash=`openssl sha -sha256 -hmac "Genuine Adobe Flash Player 001" rtmpe_ver2015_u.swf | cut -d ' ' -f 2` rtmpdump --rtmp "rtmpe://netradio-${lc}-flash.nhk.jp/live" \ --playpath "${playpath}" \ --app "live" \ --swfhash "${hash}" --swfsize "${size}" \ --pageUrl "http://www3.nhk.or.jp/netradio/player/index.html?ch=${lc}&area=tokyo" \ --live \ --stop ${dur} \ --flv ${file} # --swfVfy "http://www3.nhk.or.jp/netradio/files/swf/rtmpe_ver2015.swf?tm=${time}" \ else usage fi |
1. で挙げた URL とダウンロードするファイルが違いますが、こちらの方が新しいようなので採用しています。
第1引数にチャンネルを指定します。ラジオ第1は R1、第2は R2、NHK-FM は FM としてください。
第2引数には放送局を指定することができます。AK が東京、BK が大阪、CK が名古屋、HK が仙台です。省略することもでき、その場合は自動で東京になります。なお、ラジオ第2は配信されているのが東京局のみなので、放送局を指定しても効果はありません。
第3引数にはファイル名を、第4引数には録音する時間を秒単位で指定してください。
いくつかの組み合わせでテストして動作することを確認していますが、自己責任でお願いします。不具合に関しては報告いただければ修正します。
いかがだったでしょうか。なお、radiko の録音は次のページをスクリプトを使えばすべて解決すると思いますので参考にしてみてください。