読者です 読者をやめる 読者になる 読者になる

良いあそなすちゃん

良い方のあそなすちゃんです!

ラジオ録音環境を整えた話

全国60億人のラジオ大好きっ子のみんなこんにちは。

ラジオ録音ということですが、思い出として小学生か中学生のころラジオの録音がしたくて家のラジカセに頑張って録音(主に深夜の馬鹿力)していたのが最古の記憶です。がしかし2010年代になり身の回りからラジカセもカセットテープもなくなりiPhoneやパソコンでなんとかしなくてはならなくてラジオ聴取が厳しい暗黒時代になって少しラジオから遠ざかっていたところに、radikoの登場によりラジオ録音への道が一気に開かれました。少し調べるだけで様々な方法でラジオを録音する方法が紹介されています。

かくいう僕も何年か前に rtmpdump についてはniconico生放送の録画をしたくて調べていた時期がありその応用で rtmpdump と ffmpeg を組み合わせたラジオ録音環境を整えました。多分それが2013年とか14年とかそれぐらい。構成はとても素朴でVPSでcronを動かしてrtmpdumpで録音してそれをffmpegでいい感じのmp3に変換するという流れを組んでいました。

この方法では結構問題点があり、

* ラジオ1本あたり1時間以上と長い放送だと途中で聞くのをやめたあとに途中から再生を再開する方法がない

* 端末にダウンロードしたあとにもう聞かない音源を消すのが結構億劫

* 更新の確認が手動(毎週手元のマシンにscpしてた)

という点があります。あります、というかこの問題点に気がついたのは podcast を聴き始めて、ちまたにあふれているpodcastクライアントでは上記の問題を一気に解決できるような体験を提供していて初めて、「ああ、自分は今まで苦労して録音したラジオを聞いてたんだな」ということに気が付きましたので、そういうことです。

より良い体験ができることは1年ぐらい前から知っていたのですが、先述のとおり、素朴な構成とはいえ、悪く言えば運用でカバーするシェルスクリプトの中で書いてるのでそれを書き直すのが面倒なのと、構成を変えて次の録音のタイミングで失敗したら悲しい、などの理由からとても腰が重たかったのでした。

しかし、この4月から僕と誕生日が同じであり、中学生のころからずっと聞いてたラジオのパーソナリティこと伊集院光氏が昼の帯番組を持つことで心機一転でやってやりましょうという運びになりました。

やりましょうってことなので慎重に録音のシェルスクリプトリファクタリングするところから始めました。リファクタリング、といってもテストコードは皆無なので少しずつスクリプトを書き直す方法を幾つか紹介します。

30秒だけ録音して確認のサイクルをあげる

rtmpdump のdurationを指定できるオプションがありそれを30秒など短いに指定して確認できるサイクルを増やすことでより高速に確認できるようにした。30秒にとくに意味はありません。10秒とかでもいいと思います。

変換のタイミングを非同期にやっていたのを同期でやる

なぜか昔の僕は録音のタイミングと録音した音源の変換(mp3圧縮)を非同期にやっていたのですが、非同期でやるメリットはないので、保存した後そこからそのままffmpeg に食わせるようにした。

この2点だけでとりあえず録音から再生可能な状態までもってこれるようになりました。

その他細かいこと

あとは細やかでよりささやかなオプションとして録音できるチャンネルを引数で指定できるようにしたり、シェルスクリプトとしてはシンプルに録音する時間を分単位で指定できるようにしました。なので開始時間については cron を使い、録音のスクリプトには録音したい時間(分)与えると良い、という状態にもっていきました。

小話ですが、スクリプトの起動に数秒かかるので1時スタートのラジオだと頭の数秒が欠けてしまうのでcronの時間指定する場合には1分ほど前に指定するのがよいです。ちなみに、この1分前の時間から録音スタートというのが今の構成のイケてないところで例えば日曜日00時00分から開始するラジオだと土曜日の23時59分を指定しなくてはならなくて少しもどかしいのでなんか別の方法を用いて解決したいところ(cronの-jオプションでいい感じにできればいいなとか思ってます)

また、チャンネルを指定できるようにしたのは、上坂すみれさんのラジオが同様にこの春から始まったからです。黒うさぎも好きでした。

改善したいところ

録画開始時間の点は先述のとおりですが、既存の仕組みだとradiko内をNode.jsを使ってクローリングしていたり、xmlをパースするのにruby、日時やファイルの操作にshell、細かい正規表現perlという感じで前まではshell一本でかけていたところが急に複雑になったのでもう少しシンプルにしたいところですね。多分Node.jsでクローリングしているところはよっぽどのことがない限りは変わらない(プレイヤーの情報などを持ってきているだけ)のでハードコードしてもいいのかもしれないなとか思っている。

Podcastについて

さて録音環境が改善されたので、毎週scpするのはもう流石にやめようという感じです。Podcastについては仕様にそったXMLを用意してインターネット上に配置してクライアント側でそのXMLのURLを食わせればOKな感じですが、少しハマった点として

enclosure に指定するURLは必ず開けるURLにすること

最初ミスっててアクセスできないURLをXMLに埋め込んでいたらiPhonePodcastクライアントでは謎の挙動をしてデバグ困難だったのでちゃんとアクセス可能なURLをいれること。

また、音源のファイル名に日本語が入ってるとこれまた謎の挙動をするのでエスケープするなどしてあげるとよかったです。

XML、結構面倒だったのでライブラリを使うほうが実はハマリポイント少なかったかもです。

Dropboxだと稀に同期に失敗する

これは原因不明なのですが、何度かに一回更新に失敗するので自前のサーバなどに置いておくといいでと思います。

小話

自前録音環境でまだ運用実績が皆無なので実はこれとは別に radicast というソフトウェアを使って録音環境を構築しています。

GitHub - soh335/radicast: recording radiko and serving rss for podcast

radicastはDockerの環境さえあれば特に何もせず動くので便利です。とりあえず2本体制で運用しているのですが、今のところ問題はなく動いています。自前録音はVPSでやっているのですがVPSが死ぬことを考慮してradicastは自宅の余っているPCで動かしています。運用実績がついてくれば radicast はやめて、自前の録音環境だけで済ませようと思います。

また録音するサーバを一時期とある大阪リージョンのVPSで動かしていたのですが、なぜかその時は思ってた番組とは違う番組が録音されてしまったので、東京側にあるリージョンで動かすようにしました。アレをアレすれば石狩でも多分東京のラジオが聞けると思います(適当)し、僕の勘違いだったのかもしれません。ほげほげ。

まとめ

自前のラジオ録音環境を整えた話でした。この変更により今週からiPhonePodcastクライアントで通勤中などに気軽に聞けるようになりました。

久しぶりに自分の為のコードを書いたのでとても楽しかったです。結構手軽なスクリプトが書けたのでWebのUIから録音できるようになればより便利かなと思ったりなどなど。

こういう録音はアニメ録画とは違い番組ひとつあたりのファイルサイズが小さいのでバンバン録音しておいてもさしてNASの容量などを圧迫しないのがいいですね。月一で家のNASにダウンロードなどして保存してますが、たまにサバゲに行ってGoProで様子を録画すると1日で60GB増えるのに比べたらゴミみたいなもんです。

ちなみに僕の書いたスクリプトは公開していないし、個人の範囲で楽しむためpodcastのリンクも公開しませんが、録音に関しては、運用が一番大変で録音のスクリプトはシェルだけでも50行もあればかけるのでインターネットで適用に調べたりすればあとはなんとかなります。やっていきましょう。