Edited at
DMM.comDay 24

radikoとPodcastとラズパイでお手軽ラジオサーバ

※追記

ラズパイのSDを買い替えたりしていてしばらくちゃんと運用していなかったのですが、どうやらradigoのバグ?でrec-liveがちゃんと動作しないようです。この記事を書いたときの検証ではうまくいってた気がするのですが・・・:thinking: PR出すか他の方法を模索する予定です。

該当のissueはこちら => https://github.com/yyoshiki41/radigo/issues/45


これはDMM.com Advent Calendar 2018 24日目の記事です。

どうも。DMM.com 動画配信事業部の@_tinojiという者です。

みなさん、クリスマスイブをいかがお過ごしでしょうか?僕はもちろんAMラジオを聞いています。紳士として当然ですね:relaxed:

先日、自宅でエアコンをオン/オフするだけの置物になっていたRaspberry Pi 3 Model Bにラジオサーバを構築しました。そのときのあれこれを書こうと思います。ググるとたくさん情報が出てくるので、何を今さらという感じは否めませんが・・・。多少他とは違う方法でやっているので、まぁご容赦ください。

※ 当然ですが、私的利用の範囲を超えたラジオの録音は違法です。あくまで自分で楽しむためにご利用ください。


tl;dr



  • radigoというツールを使用してradikoを録音する。

  • ちょっとしたシェルスクリプトとcronで予約録音を行う。

  • RSSを生成して、ラズパイに適当なWebサーバを立ててPodcastで配信する。

  • わりといい感じ!:ok_hand:


radikoはもちろん良いんだけど・・・

みなさんはどうやってラジオを聞いてますか?

なになに、ラジオを持っていてそれで聞いている?お、今どき珍しいですね。そこの君は?え?ゆーちゅーb、おっとその話はそこまでだ:raised_hand:違法アップロードされたものを聞いている君は、この記事を読んだあとすぐにラズパイを買いに行くんだ。おじさんとの約束だよ。

そうですね、今はほとんどradikoで聞いている人がほとんどではないでしょうか。radikoではタイムフリーという、放送から1週間以内であればいつでも聞くことができる機能があって非常にありがたいのですが、1週間を過ぎると聞けなくなってしまう、聞き始めてから聴取可能期限がある等の制限がなかなかツライです。ラジオ好きは同じ回を何度も聞きたい生き物なんです。


先駆者たち

ということで、録音したいですね。軽くググってみると、radikoから録音する試みはすでに盛んに行われており、Raspberry Piを使用している記事もいくつか出てきます。

radicastはGitHubで公開されているのですが、そこにはradikoのタグが!おっ、と思ってクリックしてみると、radicastの倍のスター数を獲得しているリポジトリがありました。それがradigoです。ググったら作者のQiita記事も見つかりました。

radigoを使って録音とPodcast配信までやってみた的な記事はなかったので、それをやっていくことにしました。

私の場合、Podcastで録音したファイルを予めダウンロードしておく(というか自動でダウンロードされるようにしておく)ことがほとんどなので、ラズパイにはLAN内で接続できればいいことにします。


radigoのインストール

それではここからが肝心の構築手順になります。

READMEにはDockerイメージを使用したインストール方法も書いてありますが、今回はDockerは使わずにやってみます。


goのインストール

Rapberry PiのCPUアーキテクチャがARMなため、README通りにはインストールできないと思われます。makeではdepのインストールでこけますし、releasesにはARM用のバイナリは置いていません。なのでGoをインストールしてgo getでインストールします。

Goもちゃんとアーキテクチャにあったものをインストールする必要があります。私のラズパイのアーキテクチャはarmv7lでした。

$ uname -m

armv7l

https://golang.org/dl/ を見てみるとarmv6l用のバイナリがあり、それで問題なく動きました。wgetで取得し、公式通りに展開してパスを通します。


radigoのインストール

$ go get github.com/yyoshiki41/radigo/cmd/radigo/...

インストールしたradigoにもパスを通しておきます。


.bash_profile

export PATH=$PATH:$GOPATH/bin



依存ツールのインストール

ffmpegrtmpdumpが必要です。rtmpdumpapt-getで入りますが、ffmpegはこれまたARMなビルドを入手する必要があります。私はこちらからダウンロードしました。armhfarmelというのがありますが、armhfでいいぽいです。

$ wget https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-armhf-static.tar.xz

適当に展開してffmpegのバイナリだけパスの通った場所に置きます。


動作確認

試しにライブ放送を録音してみます。以下のコマンドを実行して、outputディレクトリにAACファイルができればOKです。

$ radigo rec-live -id=LFR -t=60

Now downloading..
+------------+---------------+
| STATION ID | DURATION(SEC) |
+------------+---------------+
| LFR | 60 |
+------------+---------------+
- Completed!
/tmp/output/20181222232808-LFR.aac


Webサーバを立てる

なんでもいいのでWebサーバを立てます。私はNginxにしました。特になにも考えず、デフォルト設定のまま起動しておきます。


RSSファイルの生成

Podcastで配信するにはオーディオファイルだけではなくRSSファイルが必要です。Podcastを簡単に配信するアプリなどではいい感じにRSSファイルを作ってくれるんでしょうが、今回はオーディオファイルから自前で作る必要があります。いい感じのスクリプトがあるのでご安心を:ok_hand:

私は下の方を使用し、AACファイルにも対応するように修正しました。mimeタイプを取得しているところに分岐を追加するだけです。また、Rubyスクリプトなのでapt-getでRubyを入れておきます。

if (/\.mp3$/ =~ item['fname']) then

mime = 'audio/mp3'
elsif (/\.aac$/ =~ item['fname']) then
mime = 'audio/aac'
else
mime = 'audio/mp4'
end


動作確認

$ ruby makepodcast.rb Podcastのタイトル ディレクトリURL オーディオ保存ディレクトリ

で実行します。ディレクトリURLの末尾には/をつける必要がありそうです。実行してenclosuretypeがファイルのフォーマットと一致していればOKです。

標準出力されるだけなので、実際に使うときはリダイレクトしてファイルに書き込みます。

$ ruby makepodcast.rb title http://192.168.x.x/radio/ /tmp/output/

<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
<channel>
<title>title</title>
<item>
<title>20181222235406-LFR</title>
<enclosure url="http://192.168.x.x/radio/20181222235406-LFR.aac"
length="60593"
type="audio/aac" />
<guid isPermaLink="true">http://192.168.x.x/radio/20181222235406-LFR.aac</guid>
<pubDate>Sat, 22 Dec 2018 23:54:08 +0900</pubDate>
</item>
</channel>
</rss>


配信テスト

これでPodcastで配信テストをしてみます。先程録音したファイルをドキュメントルートに配置し、RSSファイルをこんな感じで作成します。

$ ruby path/to/file/makepodcast.rb title http://192.168.x.x/test/ /var/www/html/test/ > /var/www/html/test/title.rss

こんな構造。

$ tree /var/www/html/

/var/www/html/
└── test
├── 20181222235406-LFR.aac
└── title.rss

Podcastアプリからライブラリ>番組>編集>PodcastをURLで追加でRSSファイルのURLを入力します。

「購読」をタップして、購読済みになれば登録されています。

作成した番組のエピソードを実際に再生して、ちゃんと再生されればOKです!ここでエラーになる場合はRSSファイルがおかしいとかそんな感じだと思います。


cronで録音予約

このままでは手動で録音するしかありません。タイムフリー期間なら放送終了後の番組をradigo recで時間を指定して簡単に録音できますが、それでもめちゃめちゃ面倒です。録音予約をして自動で録音されるようにしましょう。クラシカルにcronで行ってみます。


シェルスクリプト

ここまでの一連の流れを行うだけの簡単なシェルスクリプトを書きます。現状radigoで保存先が指定できないので、いちいちmvしてます。

$ ./rec.sh タイトル ラジオ局ID 録音時間 のように実行します。


rec.sh

#!/bin/bash

DOC_ROUTE="/var/www/html"
WORK_DIR="/root/radio"
HOST_IP=`hostname -I | cut -f1 -d' '` # eth0
TITLE=$1
STATION=$2
DURATION=$3
TITLE_HOME="${WORK_DIR}/${TITLE}"
TITLE_DIR="${DOC_ROUTE}/${TITLE}"

# mkdir
[ ! -e $TITLE_HOME ] && mkdir -p $TITLE_HOME
[ ! -e $TITLE_DIR ] && mkdir -p $TITLE_DIR

# rec
cd $TITLE_HOME
radigo rec-live -id=$STATION -t=$DURATION
mv $TITLE_HOME/output/*.aac $TITLE_DIR

# make rss file
ruby $WORK_DIR/makepodcast.rb $TITLE http://$HOST_IP/$TITLE/ $TITLE_DIR > $TITLE_DIR/$TITLE.rss



cron

crontabがそのまま予約表になります。今後はこれをいじるだけになるのでそこそこ楽なはずです。ラグを考慮して前後一分ぐらいバッファを取ったほうがいいかもしれませんね。

# オードリーのオールナイトニッポン

0 1 * * 0 /bin/bash -lc "/root/radio/rec.sh AudreyANN LFR 7200"
# アルコアンドピースのDCガレージ
0 0 * * 3 /bin/bash -lc "/root/radio/rec.sh DCGarage TBS 3600"

初回の録音が完了したら、Podcastで購読の登録をしておけばあとは自動で毎週ダウンロードされていくはずです。

以上です。わりといい感じになりました!みなさんも良いラジオライフを〜〜:wave:


補足

いくつか補足的な。


ファイルサイズ

AACの場合、1時間で20MBちょいになります。例えば2時間の番組を週に10本録音する場合、年間20GBを超えます。


クラウドでホストするのもいいかも?

ファイルサイズが結構大きいので、ラズパイのSDカードで運用するのはなかなか大変かもしれません。もちろん適当に消していけばいいですが、バックナンバーも聞きたいですよね・・・?(ラジオ番組のバックナンバーをオンデマンド配信してくれたら嬉しいのになぁ、って100万回思ってる)

ということで安めのクラウドのサービスでホスティングするのがいいかもしれません。S3が妥当な選択肢だと思います。適度にGlacierにアーカイブして節約すれば結構安く抑えられるはずなので、ラズパイでの運用が限界を迎えたらやってみようと思います〜!