FreeBSDでラジコを利用する、その1

今月 4月1日からラジコの仕様が変更となった影響で、WindowsXP上で使用させてもらっているRadika 1.71のm4a録音に不都合が生じてしまいました。この現象に関しては、再生・録音開始時刻を必要な時間だけ前倒しするか、フックによる録音でmp3形式を選択することにより回避しているが、継続して「ラジコ」や「radiko」をキーワードとして検索していたところ、FreeBSD OSでもラジコを録音している人がいることが判明しました。

常時稼働させているFreeBSDサーバー上でラジコを録音できるなら、録音したい時間前にわざわざ Windows PC を起動させる必要がなくなります。深夜番組を録音したい日もPCを付けっぱなしにする必要がないため、多少静かになることが期待できます。
本番マシン(FreeBSD 8.3)で直接テストするのはちょっと恐いので、先日FreeBSD 9.1のインストールテストをして放置していたマシンで実験してみることにしました。

テスト1

参考にさせていただいたページの一つ目が、http://www.asahi-net.or.jp/~sy8y-siy/memo/radiko/index.html です。

この情報によると、

  • rtmpdump
  • swftools
  • wget
  • base64
  • ffmpeg

が必要になるということなので、 /usr/ports からインストールしました。インストールのコンフィグはデフォルト。
インストール後、同ページに紹介されているスクリプトを radikoRec.sh という名前で実行権を与えて保存し、実行してみましたが、

> radikorec.sh HOUSOU-DAIGAKU 10
areaid: 
RTMPDump v2.4
(c) 2010 Andrej Stepanchuk, Howard Chu, The Flvstreamer Team; license: GPL
WARNING: No application or playpath in URL!
Connecting ...

という感じで、動きません。まあ、上記URLが記述された時期が、2012/07/24ということなので、その後何度かラジコの仕様が変更されたことを考えれば当然の結果でしょう。

テスト2

次に、参考にさせていただいたページが http://karaage.de-blog.jp/mmmm/2012/10/radiko_90f9.html です。 基本的には、最初のURLと同じパッケージとスクリプトを使用しているものですが、2012年10月のラジコしよう変更に対応した情報になっています。
こちらのスクリプトを保存して使用させていただいたところ、そのまま動作しました。

このテスト2のページを参考にテスト1スクリプトを修正させていただいたところ、テスト1のスクリプトも動作するようになりました。

<diff orig.sh new.sh の結果>

5c7
< playerurl=http://radiko.jp/player/swf/player_2.0.1.00.swf
---
> playerurl=http://radiko.jp/player/swf/player_3.0.0.01.swf
38c40
< swfextract -b 5 $playerfile -o $keyfile
---
> swfextract -b 14 $playerfile -o $keyfile
115,117c117,119
< -r "rtmpe://radiko.smartstream.ne.jp" \
< --playpath "simul-stream" \
< --app "${station}/_defInst_" \
---
> -r "rtmpe://w-radiko.smartstream.ne.jp" \
> --playpath "simul-stream.stream" \
> --app "${station}/_definst_" \

考察

テスト1のスクリプトが「コマンド <放送局コード> <録音時間(分)>」の形式でコマンドを発行し m4a 形式でファイルに保存されるのに対し、テスト2のスクリプトは「コマンド <放送局コード> <録音終了時刻>」形式で発行し flv 形式でファイルに保存される点が異なるようです。録音ファイル保存場所に関してはテスト1が /tmp/radiko を使うのに対し、テスト2はスクリプト中で指定。機能的にはテスト2が優れている感じですが、私の好みとしては、録音時間を分で指定するテスト1の方が使いやすいと感じます。
テスト1のスクリプトを読んでみると、録音自体はflv形式で行われており、録音終了時にffmpegでm4a形式に変換しているようです。
私は iTunes やiPodで聴きたいので、flv を m4a に変換する行をテスト1のサイトから拝借しテスト2のサイトのスクリプトに追加してみました。flvは(動作確認して安定度差を確認したあと)変換後に消去するようにします。

output=${outputbase}/${channel}_${outputdateline}_${count}.flv
m4a_output=${outputbase}/${channel}_${outputdateline}_${count}.m4a
#
#get rec time
#
startUnixTime=$( date +%s )
backEndUnixTime=$( ruby -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://w-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}
ffmpeg -loglevel quiet -y -i "${output}" -acodec copy "${m4a_output}"
rm "${output}"
RET=$?

このスクリプトやテスト2のページからリンクされている http://blog.half-moon.org/archives/332 のページを見てみると、今回組み込んだツールでラジコを聴く仕組みが何となく理解できます。

  • swftools と rtmpdump でFlash形式で配信されている音声データをキャプチャ。
  • wget でラジコサーバーと情報交換
  • base64 で認証関係のデータをデコードかエンコード
  • ffmpeg で、flv形式録音データをm4a形式に変換(オプションパラメータを変えればmp3に変換できるかも)

ここまで出来るようにしてくれた人たちに感謝感謝です。

ただし、Radika でできることがこのツール群とスクリプトですべてできるわけではありません。リアルタイム再生は出来ません。このスクリプトで記録したファイルと、radika を使用して録音した場合で大きく異なるのは、番組表情報を録音ファイルに組み込めないこと。iTunes に読み込んだとき番組情報が空っぽでちょっと寂しい点ですが、これくらい我慢するしかないでしょう。

課題

あとは、1) タイマー録音できるかどうか(cronから起動できるか)、2) 同時に複数番組録音が可能かどうか、3) 録音品質とファイルサイズのバランスは許容範囲かどうか。ここら辺を確認する必要がありそうです。

さて、Unixシステム上でラジコ番組を自動録音して音声ファイル化できるといういことは、別の便利な使い方ができるということにつながります。FreeBSD dropbox-api コマンドを使ってDropboxサーバーにアップロードし、出先のモバイルデバイスで聴くとか、cron とスクリプトで自宅Webサーバー上にRSSファイルを作成してiTunesでPodcastとして聴くようにするとか。

今回はFreeBSDのコマンドベースでラジコ番組を録音できることを確認するところまで完了しました。常時稼働サーバーで負荷を掛けずに安定録音できるかどうかが課題です。
今回テストに使用したスクリプトはこちら

Comments

  1. スクリプトの終わり部分に ffmpeg で flv ファイルを m4a に変換するコマンドを追加しましたが、これはNGでした。
    この2行はコメントアウトすべきです。または、挿入位置を変更すべきでした。
    録音が全て正常に終了すれば問題ないのですが、番組途中に何らかの要因により中断してしまった場合、ffmpeg により録音リトライが中断されてしまいます。ファイルフォーマット変換をする場合は、別の位置で別のコマンドで行うか、別のプログラムで行うべきだと思います。

    私が追加した行はコメントアウトしました。

コメントを残す