シェルスクリプトで radiko タイムフリーを保存する
上記の記事を大いに参考にさせていただき、というか重要な部分を丸パクりさせていただき、シェルスクリプトを作った。
くれぐれも。
ラジコのタイムフリーを保存することには、なんらかの違法性があるかもしれない。筆者がインターネットをめぐる著作権の法律を読んだ感じでは、公式が配布するコンテンツを保存することは、私的の利用に限れば問題ない、のではないかと思っている。
しかし専門家にはいわせれば違うのかもしれない。
確実なのは、ダウンロードしたものをどこかへ公開するのはアウトということだ。
追記 2020.12.05
—————————
ラジコの仕様変更にともなって、スクリプトを書き直しました。
下記のスクリプトから重要な部分をコピペさせていただき、自分なりにアレンジしたものとなります。下記スクリプトの作者さまには深く感謝いたします。
🔗 GitHub – uru2/rec_radiko_ts: Radiko timefree program recorder
というか、上記リンク先にある、rec_radiko_ts.sh ならエリアフリーにログインできるので、そっちのほうがいいような気がする。
—————————
radiko-dl.sh
要 ffmpeg。
brew install ffmpeg
2019 年 12 月 25 日深夜 1 時から 3 時、TBS ラジオの「爆笑問題カーボーイ」を保存するとしたら、以下のように書く。
radiko-dl.sh -id TBS -ft 20191225010000 -to 20191225030000 -n 'JUNK 爆笑問題カーボーイ'
radiko-dl.sh -id 放送局ID -ft 開始時間 -to 終了時間
必要に応じて-n '番組名'
をつけると、ファイルに番組名をつける。
-o file/to/path
で保存先を指定できる。チルダをクオートで囲むと展開されないので、-o "$HOME/Downloads"
という感じがいいかもしれない。
デフォルトでは Downloads フォルダ内に radiko フォルダを生成してダウンロード先とする。必要なら一行目の dir のパスを書き直すのがいいと思う。
📝 radiko-dl.sh
#!/bin/zsh
# Copyright (c) 2017 uru (https://twitter.com/uru_2)
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
dir=~/Downloads/radiko
readonly AUTHKEY_VALUE="bcd151073c03b352e1ef2fd66c32209da9ca0afa"
# オプションを取得
while [ $# -gt 0 ]
do
case $1 in
-id) shift; id="$1" ;;
-ft) shift; ft="$1" ;;
-to) shift; to="$1" ;;
-n) shift; program="$1" ;;
-o) shift; dir="$1" ;;
*) break ;;
esac
shift
done
# ファイル名を決める
if test -z "$program"; then
filename=`echo "$id"_"$ft"`
else
ft_unix=`date -j -f "%Y%m%d%H%M%S" "$ft" +%s`
hiduke=`date -r "$ft_unix" +"%Y-%m-%d-%H%M"`
filename=`echo ${program}'_'${hiduke}`
fi
# フォルダへ移動
if test -d "$dir"; then
cd "$dir"
else
mkdir "$dir"
cd "$dir"
fi
# 承認ひとつめ
auth1=`curl \
--silent \
--header "X-Radiko-App: pc_html5" \
--header "X-Radiko-App-Version: 0.0.1" \
--header "X-Radiko-Device: pc" \
--header "X-Radiko-User: dummy_user" \
--dump-header - \
--output /dev/null \
"https://radiko.jp/v2/api/auth1"`
authtoken=$(echo "${auth1}" | awk 'tolower($0) ~/^x-radiko-authtoken: / {print substr($0,21,length($0)-21)}')
keyoffset=$(echo "${auth1}" | awk 'tolower($0) ~/^x-radiko-keyoffset: / {print substr($0,21,length($0)-21)}')
keylength=$(echo "${auth1}" | awk 'tolower($0) ~/^x-radiko-keylength: / {print substr($0,21,length($0)-21)}')
partialkey=$(echo "${AUTHKEY_VALUE}" | dd bs=1 "skip=${keyoffset}" "count=${keylength}" 2> /dev/null | base64)
# 承認ふたつめ
curl \
--silent \
--insecure \
--header "X-Radiko-Device: pc" \
--header "X-Radiko-User: dummy_user" \
--header 'X-Radiko-AuthToken: '${authtoken} \
--header 'X-Radiko-PartialKey: '${partialkey} \
--output /dev/null \
"https://radiko.jp/v2/api/auth2"
# オプションがそろっているかチェック
if test -z "$id" || test -z "$ft" || test -z "$to"; then
echo '-id 放送局ID -ft 開始時間(20190430133000) -to 終了時間'
exit 1
fi
# 放送済みかどうかチェック
to_unix=`date -j -f "%Y%m%d%H%M%S" "$to" +%s`
now=`date +%s`
if test $to_unix -ge $now; then
echo '放送終了前です'
exit 0
fi
# ダウンロード
ffmpeg \
-loglevel error \
-fflags +discardcorrupt \
-headers 'X-Radiko-Authtoken: '${authtoken} \
-i 'https://radiko.jp/v2/api/ts/playlist.m3u8?station_id='$id'&l=15&ft='$ft'&to='$to \
-bsf:a aac_adtstoasc -acodec copy "${filename}".m4a
# 通知など出してみる
osascript -e 'display notification "'"$filename"' 完了しました" with title "radiko-dl.sh" sound name "Glass"'
開始時刻、終了時刻、番組名
このスクリプトだと開始時刻、終了時刻とかを調べるのがダルい。
なので番組表から検索するスクリプトも書いてみた。
radiko-dl.sh へ渡すオプションを生成することを目的としている。
追記 2020.12.05
————————–
ラジコの仕様変更にあわせて書き直しました。
以前はダウンロードしたファイルからエリアを調べていましたが、今回は自分でエリアを調べる必要があります。
🔗 都道府県コード
下記スクリプトの冒頭にある、area='13'
の数字をお住いの都道府県の数字に書き換えてください。
—————————
📝 findradiko.sh
#!/bin/zsh
# https://nlftp.mlit.go.jp/ksj/gml/codelist/PrefCd.html
# 上記ページなどを参照にして、都道府県コードを入力する。
# 東京なら「13」
area='13'
# 作業場のフォルダへ移動する。dl-radiko.sh の作業場とあわせる
cd ~/Downloads/radiko
quick='off'
day='today'
# オプションの取得
while [ $# -gt 0 ]
do
case $1 in
-i) shift; id="$1" ;;
-k) shift; keyword="$1" ;;
-d) shift; day="$1" ;;
-q) quick='on' ;;
*) break ;;
esac
shift
done
# 放送局ID を表示する関数
function showStID() {
curl -s https://radiko.jp/v2/station/list/JP"${1}".xml | grep -E '<\/id>|<\/name>' | sed -e 's/ //g' | perl -pe 's/<\/id>\n/ /g' | sed -e 's/<id>//g' | perl -pe 's/<name>//g' | perl -pe 's/<\/name>\n/\n/g'
}
# オプションのチェック
if test -z "$id" || test -z "$keyword"; then
echo '-i 放送局ID -k キーワード'
echo 'エリアコード:'$area
echo '------------------------------'
showStID $area
exit 1
fi
# 日付のチェック
if ! test "$day" = 'today'; then;
if test `echo "${#day}"` -eq 8; then;
day='date/'"$day"
else
echo '日付は8桁で。(2019年10月3日 → 20191003 みたいな)'
exit 0
fi
fi
# 番組表の取得
prog=`curl -s https://radiko.jp/v3/program/"${day}"/JP"${area}".xml | grep -B 1 "${keyword}" | grep -E 'prog id=|master_id=|title'`
# 番組名、開始時刻、終了時刻の取得
title=`echo "${prog}" | grep -o "<title>[^<]*</title>" | sed -e 's/<[^>]*>//g'`
ft=`echo "$prog" | tr '"' '\n' | grep -A 1 'ft=' | grep -vE 'ft=|--'`
to=`echo "$prog" | tr '"' '\n' | grep -A 1 'to=' | grep -vE 'to=|--'`
# 複数の番組が見つかった場合を想定して for ループで表示。
# -q オプションがついている場合は、そのまま保存に入る。
# あんまり連続したら怒られそうなので「sleep 60」で一分間を置く。必要ないかも。
wl=`echo $title | wc | awk '{print $1}'`
for num in `seq $wl`
do
namae=`echo $title | sed -n "$num"p`
hajimari=`echo $ft | sed -n "$num"p`
owari=`echo $to | sed -n "$num"p`
if test "$quick" = 'off'; then
echo '-n '\'"${namae}"\'' -id '"${id}"' -ft '"${hajimari}"' -to '"${owari}"
else
sh radiko-dl.sh -id "${id}" -ft "${hajimari}" -to "${owari}" -n "${namae}"
if test $wl -gt $num; then
sleep 60
fi
fi
done
使い方としては、
findradiko.sh -i 放送局ID -k キーワード
で、きょうの番組表から検索する。
2019 年 12 月 24 日 に「爆笑問題」というキーワードでこのスクリプトを実行すると、以下のような結果が返ってくる。
$ findradiko.sh -i TBS -k '爆笑問題'
-n 'JUNK 爆笑問題カーボーイ' -id TBS -ft 20191225010000 -to 20191225030000
という感じ。
この結果をコピペして radiko-dl.sh に渡せばダウンロードがはじまる。
検索範囲はその日の放送に限る。しかし 0 時をすぎた深夜の番組もヒットする。
日にちを指定する場合は -d オプションを使用する。「西暦月日」を 8 桁の数字にして渡
す。2019 年 12 月 22 日なら、-d 20191222。
なお、ラジコのタイムフリーで聞ける過去の放送は、一週間前までだ。
検索の対象となるのは番組名だけだ。パーソナリティーやゲストの名前で検索してもヒットしない。
$ findradiko.sh -i FMGUNMA -k '有吉弘行の' -d 20191222
-n '有吉弘行のSUNDAY NIGHT DREAMER' -id FMGUNMA -ft 20191222200000 -to 20191222205500
-n '有吉弘行のSUNDAY NIGHT DREAMER' -id FMGUNMA -ft 20191222210000 -to 20191222215500
このようにひとつの番組がわかれていて複数見つかったりもする。
-q
オプションをつけると自動で radiko-dl.sh にデータを渡して自動でダウンロードをはじめる。
(下から 6 行目の「sh radiko-dl.sh」を正確なパスに書き換える必要がある。デスクトップに radiko-dl.sh があるとしたら sh ~/Desktop/radiko-dl.sh という感じ)。
複数の番組がある場合、ひとつのダウンロードが終わってから一分待ち、次のダウンロードをはじめる。あんまり連続してダウンロードすると怒られそうなのでそうした。
crontab に登録する
cron はスリープ復帰してくれないが、タイムフリーのダウンロードなら時間はあまり関係ない。いつでも、Mac が起きている時間に cron をセットしておけばいいはず。
3 3 * * wed /パス/findradiko.sh -i TBS -k 'JUNK 爆笑問題カーボーイ' -q
こんな感じで-q
オプションをつけておけば、番組終了の 3 分後、つまり水曜の 3 時 3 分に自動で番組が保存されて、いいと思う。
・【Mac】定期的にスクリプトを実行する crontab | 林檎コンピュータ
Catalina で crontab を動かす場合は、下記の記事を参考。
・macOS 10.15 catalina にしたら crontab が動かない | 林檎コンピュータ