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

※追記
ラズパイのSDを買い替えたりしていてしばらくちゃんと運用していなかったのですが、どうやらradigoのバグ？で`rec-live`がちゃんと動作しないようです。この記事を書いたときの検証ではうまくいってた気がするのですが・・・:thinking: PR出すか他の方法を模索する予定です。
該当のissueはこちら => https://github.com/yyoshiki41/radigo/issues/45

---

これは[DMM.com Advent Calendar 2018](https://qiita.com/advent-calendar/2018/dmm) 24日目の記事です。

どうも。DMM.com 動画配信事業部の[@_tinoji](https://twitter.com/_tinoji)という者です。
みなさん、クリスマスイブをいかがお過ごしでしょうか？僕はもちろんAMラジオを聞いています。紳士として当然ですね:relaxed:
先日、自宅でエアコンをオン/オフするだけの置物になっていたRaspberry Pi 3 Model Bにラジオサーバを構築しました。そのときのあれこれを書こうと思います。ググるとたくさん情報が出てくるので、何を今さらという感じは否めませんが・・・。多少他とは違う方法でやっているので、まぁご容赦ください。

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


# tl;dr
- [radigo](https://github.com/yyoshiki41/radigo)というツールを使用して[radiko](http://radiko.jp/)を録音する。
- ちょっとしたシェルスクリプトとcronで予約録音を行う。
- RSSを生成して、ラズパイに適当なWebサーバを立ててPodcastで配信する。
- わりといい感じ！:ok_hand:


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

そうですね、今はほとんどradikoで聞いている人がほとんどではないでしょうか。radikoではタイムフリーという、放送から1週間以内であればいつでも聞くことができる機能があって非常にありがたいのですが、1週間を過ぎると聞けなくなってしまう、聞き始めてから[聴取可能期限](http://faq.radiko.jp/faq/show/235?category_id=21&page=1&sort=sort_access&sort_order=desc)がある等の制限がなかなかツライです。ラジオ好きは同じ回を何度も聞きたい生き物なんです。


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

- [Raspberry Pi 3でRadikoの録音＆再生](https://mtunn.wordpress.com/2017/02/08/raspberrypi3%E3%81%A7radiko/)
    - シェルスクリプトをゴリゴリ書いて録音する方法。
- [RaspberryPi で radikoを録音して Podcastで配信する（構築編）](https://omiso46.blogspot.com/2018/01/raspberrypi-radiko-podcast.html)
    - [radicast](https://github.com/soh335/radicast)というツールでPodcast配信まで行う方法。

radicastはGitHubで公開されているのですが、そこには`radiko`のタグが！おっ、と思ってクリックしてみると、radicastの倍のスター数を獲得しているリポジトリがありました。それが[radigo](https://github.com/yyoshiki41/radigo)です。ググったら[作者のQiita記事](https://qiita.com/yyoshiki41/items/f81442d7dc2d0ddcf15b)も見つかりました。

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

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

# radigoのインストール
それではここからが肝心の構築手順になります。

[README](https://github.com/yyoshiki41/radigo)にはDockerイメージを使用したインストール方法も書いてありますが、今回はDockerは使わずにやってみます。

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

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

```shell
$ uname -m
armv7l
```

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

### radigoのインストール

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

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

```shell:.bash_profile
export PATH=$PATH:$GOPATH/bin
```

### 依存ツールのインストール
`ffmpeg`と`rtmpdump`が必要です。`rtmpdump`は`apt-get`で入りますが、`ffmpeg`はこれまたARMなビルドを入手する必要があります。私は[こちら](https://johnvansickle.com/ffmpeg/)からダウンロードしました。`armhf`と`armel`というのがありますが、`armhf`でいいぽいです。

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

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


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

```shell
$ 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:

- https://gist.github.com/kelan/1659457
- https://gist.github.com/matchy2/5552631
    - [使い方](https://tech.matchy.net/archives/237)

私は下の方を使用し、AACファイルにも対応するように修正しました。[mimeタイプを取得しているところ](https://gist.github.com/matchy2/5552631#file-makepodcast-rb-L37)に分岐を追加するだけです。また、Rubyスクリプトなので`apt-get`でRubyを入れておきます。

```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の末尾には`/`をつける必要がありそうです。実行して`enclosure`の`type`がファイルのフォーマットと一致していればOKです。

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

```shell
$ 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ファイルをこんな感じで作成します。

```shell
$ 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を入力します。
<img width="300" alt="IMG_6355.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/130232/7952a4ac-5444-9635-2f5e-185b6ac23094.png">

「購読」をタップして、購読済みになれば登録されています。
<img width="300" alt="IMG_6356.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/130232/e0e80b4a-bb88-7ac2-7d19-e6f7b50301f3.png">

作成した番組のエピソードを実際に再生して、ちゃんと再生されればOKです！ここでエラーになる場合はRSSファイルがおかしいとかそんな感じだと思います。
<img width="300" alt="IMG_6357.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/130232/14f06c14-f631-aeba-e9da-226fc372d0b0.png">


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

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

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

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

```shell
# オードリーのオールナイトニッポン
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にアーカイブして節約すれば結構安く抑えられるはずなので、ラズパイでの運用が限界を迎えたらやってみようと思います〜！