radikoをキーワードで予約する

timerコマンドを使ってradikoらじる★らじるを自由に録音できるようになったのだけど、予約するためには時間を指定しなければならない。時間を指定するということは、予約するためには必須の要因なのかもしれないけど、その方法で予約できるのは、自分が過去に視聴したり、番組表を見て興味を持った内容に限られてしまう...。
このインターネット時代、番組表はWebで配信されている。そして当然のようにradikoの番組表も簡単にダウンロードすることができる。ならば、ダウンロードした番組表から興味のあるキーワード検索して、未知の番組を発見できると嬉しくなりそう。やってみた。

radiko API

放送局別の番組表
http://radiko.jp/v2/api/program/station/today?station_id=FMJ
  • J-WAVEの1週間分の番組
http://radiko.jp/v2/api/program/station/weekly?station_id=FMJ
エリアID別の番組表
  • 東京エリアの今放送されている番組表
http://radiko.jp/v2/api/program/now?area_id=JP13
  • 東京エリアの今日放送される番組表
http://radiko.jp/v2/api/program/today?area_id=JP13
  • 東京エリアの明日放送される番組表
http://radiko.jp/v2/api/program/tomorrow?area_id=JP13
エリアIDで受信可能な放送局リスト
  • StationIDリスト
$ curl -s http://radiko.jp/v2/station/list/JP13.xml | xpath //id 2>/dev/null | sed -e 's/<id>//g' -e 's/<\/id>/\
> /g'
TBS
QRR
LFR
RN1
RN2
INT
FMT
FMJ
JORF
BAYFM78
NACK5
YFM
HOUSOU-DAIGAKU
  • StationNameリスト
$ curl -s http://radiko.jp/v2/station/list/JP13.xml | xpath //name 2>/dev/null | sed -e 's/<name>//g' -e 's/<\/name>/\
> /g'
TBSラジオ
文化放送
ニッポン放送
ラジオNIKKEI第1 
ラジオNIKKEI第2
InterFM
TOKYO FM
J-WAVE
ラジオ日本 
bayfm78
NACK5
FMヨコハマ 
放送大学

検索した番組を取得する手順

  • 以上のradiko APIを利用して、放送局別に1週間分の番組表を検索してみようと思う。
http://radiko.jp/v2/api/program/station/weekly?station_id=FMJ
  • 例えば、上記URLにアクセスすると、J-WAVEの1週間分の番組情報が取得できる。

f:id:zariganitosh:20130214100839p:image:h450

  • 抜粋してみると、番組情報は1番組ごとにprogタグで囲まれた中に書き込まれるようだ。
  • 各progタグは17行の情報で構成されていると理解した。
  • 最終行のprogを閉じるタグにはそれ以上の情報が書き込まれることはないので、
  • grepコマンドで検索して、ヒットした行から先頭方向に16行を抽出すれば、その番組先頭のprogタグが含まれることになる。
  • progタグを手に入れたら、その属性には放送開始時刻や継続時間が書き込まれているので、その情報を元に予約できるはず。
<radiko>
<ttl>3600</ttl>
<srvtime>1360803665</srvtime>
<stations>
<station id="FMJ">
<name>J-WAVE</name>
<scd>
<progs>
<date>20130211</date>

<prog ft="20130211050000" to="20130211060000" ftl="0500" tol="0600" dur="3600">
<title>J'S SELECTION</title>
<sub_title/>
<pfm></pfm>
<desc>
休日の月曜日。今日はどんな予定ですか。少しずつ春が近づくこの頃、心に響くSLOW MUSICを聴きながら、気持ちいい一週間のスタートを!
</desc>
<info>
<a href='http://www.j-wave.co.jp/original/jsselection/' target='_blank'><img src='http://www.j-wave.co.jp/radiko/img/noa/71.gif'></a><br /><br /> <br /><br /> twitterハッシュタグは「<a href="http://twitter.com/#!/search/%23jwave">#jwave</a></info>
<metas>
<meta name="twitter" value="#jwave"/>
<meta name="twitter-hash" value="#jwave"/>
<meta name="facebook-fanpage" value="http://www.facebook.com/radiko.jp"/>
</metas>
<url>http://www.j-wave.co.jp/original/jsselection/</url>
</prog>

<prog ft="20130211060000" to="20130211090000" ftl="0600" tol="0900" dur="10800">
<title>J-WAVE TOKYO MORNING RADIO</title>
<sub_title/>
<pfm>別所哲也</pfm>
<desc>
radikoキーワード「哲也を街に連れ出して」 ラジコから番組をお聴きのみなさんに素敵なプレゼントをご用意!番組Webサイト「プレゼント」から「キーワード」を記入してご応募ください!
</desc>
<info>
<a href='http://www.j-wave.co.jp/original/tmr/' target='_blank'><img src='http://www.j-wave.co.jp/radiko/img/noa/4.gif'></a><br /><br /> 番組へのメッセージはこちら<br /> メール:<a href='mailto:morning@j-wave.co.jp'>morning@j-wave.co.jp</a> <br /><br /> twitterハッシュタグは「<a href="http://twitter.com/#!/search/%23jwave">#jwave</a></info>
<metas>
<meta name="twitter" value="#jwave"/>
<meta name="twitter-hash" value="#jwave"/>
<meta name="facebook-fanpage" value="http://www.facebook.com/radiko.jp"/>
</metas>
<url>http://www.j-wave.co.jp/original/tmr/</url>
</prog>
...(中略)...

実例

  • 例えば、J-WAVEの1週間分の番組表から「滝川クリステル」を検索して、ヒットした位置から16行先頭方向に抽出するには、以下のコマンドを実行するのだ。
curl -s http://radiko.jp/v2/api/program/station/weekly?station_id=FMJ | grep -B16 '滝川クリステル'
            <info>&lt;a href=&apos;http://www.j-wave.co.jp/original/tokiohot100/&apos; target=&apos;_blank&apos;&gt;&lt;img src=&apos;http://www.j-wave.co.jp/radiko/img/noa/119.gif&apos;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;

番組へのメッセージはこちら&lt;br /&gt;
メール:&lt;a href=&apos;mailto:hot100@j-wave.co.jp&apos;&gt;hot100@j-wave.co.jp&lt;/a&gt;
&lt;br /&gt;&lt;br /&gt;
twitterハッシュタグは「&lt;a href=&quot;http://twitter.com/#!/search/%23jwave&quot;&gt;#jwave&lt;/a&gt;」</info>
            <metas>
              <meta name="twitter" value="#jwave" />
              <meta name="twitter-hash" value="#jwave" />
              <meta name="facebook-fanpage" value="http://www.facebook.com/radiko.jp" />
            </metas>
            <url>http://www.j-wave.co.jp/original/tokiohot100/</url>
          </prog>
          <prog ft="20130217170000" to="20130217180000" ftl="1700" tol="1800" dur="3600">
            <title>NIPPON EXPRESS SAUDE! SAUDADE…</title>
            <sub_title></sub_title>
            <pfm>滝川クリステル</pfm>
            <desc>滝川クリステルがブラジルとフランスをめぐる音楽の旅にご案内します。「大人の音楽映画祭」で上映されるドキュメンタリー映画「アントニオ・カルロス・ジョビン」もご紹介します。</desc>
  • さらにパイプで繋いで、progタグを検索すれば、progタグのみ取得できるのだ。
  • ft="20130217170000"属性とdur="3600"属性を見れば、予約録音できるはず。
  • つまり、2013年2月17日17:00から3600秒放送されるサウジ・サウダージが予約できるのである!
curl -s http://radiko.jp/v2/api/program/station/weekly?station_id=FMJ | grep -B16 '滝川クリステル'|grep '<prog ft='
          <prog ft="20130217170000" to="20130217180000" ftl="1700" tol="1800" dur="3600">

シェルスクリプトにまとめる

#!/bin/bash

timer_format() {
  IFS=' '
  set `echo $@|expand`
  m=`echo $1|cut -c5-6`
  d=`echo $1|cut -c7-8`
  hhmm=`echo $1|cut -c9-12`
  echo $m/$d $hhmm /usr/local/bin/rec_radikoru.sh -o radikoru/ -t $2 $3
}

show_keyword_line() {
  IFS=' '
  set `echo $@|expand`
  echo "--------------------" $@
  xpath $PROGRAM_XML //prog[@ft="$1"] 2>/dev/null|grep $KEYWORD
  echo "===================="
}

preset_timer() {
  for line in "$@"
  do
    if `echo $line|grep -q '\w\{2,\}'`; then
      show_keyword_line $line $ID_NAME
      echo timer -${VALUE_de:=e} `timer_format $line $ID_NAME`
      echo
      if [ "$OPTION_d" = "TRUE" -o "$OPTION_e" = "TRUE" ]; then
        ./timer -$VALUE_de `timer_format $line $ID_NAME`
      fi
    fi
  done
}

show_usage() {
  echo "Usage: $COMMAND [-de] SEARCH_WORD [AREA_ID]"
}




cd `dirname $0`
COMMAND=`basename $0`

# 引数解析
while getopts de OPTION
do
  case $OPTION in
    d ) OPTION_d="TRUE" ; VALUE_de="d" ;;
    e ) OPTION_e="TRUE" ; VALUE_de="e" ;;
    * ) show_usage ; exit 1 ;;
  esac
done

shift $(($OPTIND - 1)) #残りの非オプションな引数のみが、$@に設定される

if [ $# = 0 ]; then
  show_usage ; exit 1
fi

# オプション処理
KEYWORD="$1"
AREA_ID=${2:-`./rec_radiko.sh -a|tail -1|cut -d, -f1`}
STATION_IDs=`curl -s http://radiko.jp/v2/station/list/${AREA_ID}.xml|xpath //id 2>/dev/null|sed -e 's/<id>//g' -e 's/<\/id>/,/g'|tr ',' '\n'`
STATION_NAMEs=`curl -s http://radiko.jp/v2/station/list/${AREA_ID}.xml|xpath //name 2>/dev/null|sed -e 's/<name>//g' -e 's/<\/name>/,/g'|tr ',' '\n'`
IDs_NAMEs=`paste <(echo "$STATION_IDs") <(echo "$STATION_NAMEs")|expand`
PROGRAM_XML=`mktemp -t com.bebekoubou.radiko_program`

echo AreaID=$AREA_ID
echo

_IFS="$IFS"
IFS=$'\n'
for ID_NAME in $IDs_NAMEs
do
  IFS="$_IFS"
  set $ID_NAME
  curl -s http://radiko.jp/v2/api/program/station/weekly?station_id=$1 > $PROGRAM_XML
  
  IFS=$'\n'
  prog=`grep -B16 "$KEYWORD" $PROGRAM_XML|grep '<prog ft='`
  prog_ft=`echo "$prog"|sed 's/^.*ft="\([0-9]*\)".*$/\1/'`
  prog_dur=`echo "$prog"|sed 's/^.*dur="\([0-9]*\)".*$/\1/'`
  ft_dur=`paste <(echo "$prog_ft") <(echo "$prog_dur")|expand`
  preset_timer $ft_dur
done
IFS="$_IFS"

rm -f $PROGRAM_XML

使い方

  • 引数に検索したい単語を入力すれば、ヒットした情報から予約情報を取り出すのだ。
  • ヒットした情報の下部には、予約時に必要なtimerコマンドの書式も表示されるので、これをそのままコピーして実行すれば、予約もできるのである。
$ find_radiko.sh 別所
AreaID=JP13

-------------------- 20130211060000 10800 FMJ J-WAVE
            <pfm>別所哲也</pfm>
====================
timer -e 02/11 0600 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 10800 FMJ

-------------------- 20130212060000 10800 FMJ J-WAVE
            <pfm>別所哲也</pfm>
====================
timer -e 02/12 0600 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 10800 FMJ

-------------------- 20130213060000 10800 FMJ J-WAVE
            <pfm>別所哲也</pfm>
====================
timer -e 02/13 0600 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 10800 FMJ

-------------------- 20130214060000 10800 FMJ J-WAVE
            <pfm>別所哲也</pfm>
====================
timer -e 02/14 0600 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 10800 FMJ
  • さらに-eオプションを指定すれば、ヒットした情報を即timer予約してしまう。
  • ちなみに、-dオプションを指定すれば、その予約をtimer予約から削除するのだ。
$ find_radiko.sh -e 滝川クリステル
AreaID=JP13

-------------------- 20130217170000 3600 FMJ J-WAVE
            <pfm>滝川クリステル</pfm>
            <desc>滝川クリステルがブラジルとフランスをめぐる音楽の旅にご案内します。「大人の音楽映画祭」で上映されるドキュメンタリー映画「アントニオ・カルロス・ジョビン」もご紹介します。</desc>
====================
timer -e 02/17 1700 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 3600 FMJ

======== edit
02/17 	1700 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 3600 FMJ
======== sync-wake
======== launchd list
02/17   1700 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 3600 FMJ
======== schedule list
Scheduled power events:
 [1]  wake at 02/17/13 16:59:30
  • ところで、grepコマンドは忠実に文字検索するだけなので、「スキー」で検索しても以下のように予想外の番組がヒットしてしまう場合もある。
  • アスキー」とか「テルミ・ラスカウスキー」に含まれる文字によって、雪山のスキーとは無関係の「スキー」がヒットしてしまった。
$ find_radiko.sh スキー
AreaID=JP13

-------------------- 20130217010000 1800 QRR 文化放送
            <desc>親愛なる女性に向けてラジオの前のたった一人のあなたのためにお届けする「Story」にあふれたラジオ。携帯サイト「アニメロミックスDearGirl」と連動しつつ、アスキー・メディアワークス「シルフ」の作品も紹介していきます。</desc>
====================
timer -e 02/17 0100 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 1800 QRR

-------------------- 20130214233000 1800 RN1 ラジオNIKKEI第1
テルミ・ラスカウスキー(同時通訳者/ITセキュリティ専門家)&lt;br>
====================
timer -e 02/14 2330 /usr/local/bin/rec_radikoru.sh -o radikoru/ -t 1800 RN1
  • また、radikoが提供する番組表に基づくので、Visionで検索しても何も表示されない...。
  • J-WAVEの番組表ではVisionは6分間の1番組として扱われるのだけど、
  • radikoでは1時間の番組の一部として扱われてしまっているので。(ちょっと残念)
$ find_radiko.sh Vision
AreaID=JP13

動作環境

  • MacBook Pro Retina OSX 10.8.2
  • 以下のコマンドが/usr/local/binにインストールされて機能する状態であること。
    • rec_radikoru.sh
    • rec_radiko.sh
    • rec_radiru.sh
    • timer
    • timer-add-schedule
    • timer-rm-schedule
    • timer-sync-wake