おれのIT日記

2025/10/03 (金)

Linux

らじる★らじるに続いてRadikoのシェル録音にも挑む


全国500億人の「既存アプリに出来るだけ頼らずシェルスクリプトでffmpegを使いネットラジオのライブ放送をcronで録音する」ことに命をかけている皆さん、おれもその一人です。技術力は低いですが。
こと"らじる★らじる"のライブ録音に限定すれば、手製のシェル派でもまだ戦えることを、前回の日記の通り、おれ自ら確認いたしました。
しかしこれを、我々シェル派の勝利と見るのは早計、間違いです。敵ながらあっぱれ、NHK最後の良心、お情け、とでも言うべきものでしょう。
もしNHKが制限をかけようと思えば、いくらでも簡単に制限できるからです。……そう、Radikoのように!!

我が家では今年の4月末でしたかね、Radikoの仕様変更があって以降、私的用途および自己満足感目的に限定した慎ましい録音が、できなくなっています。
「もうだめだ、今日からはスマホアプリで録音だぁ。でも手動は面倒くせえ」と毎週、グチを垂れておりました。

タイトルのとおり鼻息荒く、Radikoにも同様の手法で挑みましたが、結論を先に書きます。

・Radikoを、シェルスクリプト+ffmpegだけで録音することは、おれの技術では、無理でした。
 できたとしても、今後も頻繁に起こるであろう変更に個人で追随するのはきっと無理。
しかし諦めることはありません。ffmpegの代わりにStreamlinkを導入すれば、空しくなるほど簡単です。
 おれも知りませんでしたが、cronで従来の録音シェルを動かす、というスタイルを崩さずに使えます。
 具体的には下に記述するように、ffmpegコマンドの代わりにstreamlinkコマンドを呼ぶ、という感じです。
 あなたや私が大好きなシェルスクリプトを、簡単な修正で使い続けられます!

なお"らじる★らじる"の対応紹介と同様、"聞き逃し"の取得は含みません。
おれ自身の需要がないので、ライブ放送を、リアルタイムに録音する行為に限定した説明になります。
かつ、Linux限定です。なお、おれは最新のLinux MintおよびMX Linuxを中心に、複数PCで同じシェルを動かして確認していますし、我が家のPCはポンコツばかりなので超絶最新スペックは不要なはずです。だから、あなたの環境でも、たいがい大丈夫でしょう。

■ Streamlinkの利用方法

ChatGPTは、Streamlink以外に、radiko-cliというものも挙げてくれましたが、今回はStreamlinkで用が足りましたので、こちらに限定して紹介します。

(おれの採用しているスクリプト表示用JSが、#!以下をコメントとみなしてヘンな強調表示をしていると思うんですがご容赦ください。こーゆー指定方法なんです)
このコマンドを実行すると、J-Waveが録音されはじめ、CTRL-Cでブッチすると、そこまでの録音ファイルが残ります。
コマンドのオプション指定方法を最低限おさえたうえで、おれがcronで動かしているシェルスクリプトの該当箇所は下記のとおり置き換えました。



ffmpegベースの手法では、自力で取得したauth1、auth2の文字列をヘッダに設定したうえ、組み立てた動的なURL(GETパラメータを含む)を -i オプションの引数で指定していました。
一方、streamlinkは動的なURLの組立て自体を、面倒みてくれます。
また、ffmpegの呼出しでは、音質などに影響するコーデックの指定を細かめに書いていたところ、今回のstreamlink利用では、"best"ひとことで済ませたこともあり、全体に、自作シェルスクリプトでの呼出しオプションが短くシンプルになっています。
実質的に指定するのは、${channel}部分だけで、FMJと書けばJ-Waveが、INTならinterFMが、と言った具合です。
これら、${channel}部分に指定できる文字列は、例えばブラウザでRadiko聴取中に、解析ツール(CTRL+Shift+Iなどで起動するアレ)を使い調べられます。覚えたりメモしたりするのが面倒なら、そうですね、例えばJP13.xmlというのを見つけてダウンロードしておくとRadikoが扱う放送局を識別する3,4文字程度の識別子の一覧がわりになります。

なおffmpegでは-tオプションで録音時間を指定していましたが、Streamlinkでは、同じオプションがないみたい。
上記例では、timeoutで時間を指定してStreamlinkを呼び出す形としています。時間が来たらStreamlinkをブッチ!という、ワイルドな?使い方です。
うちではこれで困ってませんが、もっとスマートなやり方があるかもしれません。
※ 上の例での$DURATIONは秒単位です。おれは、テスト録音の時は、timeout 1 streamlink(以下略)とやってます。

■ Streamlinkの導入方法

おれは今回Streamlinkで足りてしまったので、他のオープン系ツールは試していませんが、あれですかね、ほとんどの皆さんはもう知ってたんでしょうね。だから、世の中、あまり悲鳴が聞こえてこなかったのかも。
でも、おれは知らなかったんです。正確に言うと頼ることを避けていました。正直に言いましょう、たとえば今回採用したStreamlinkについて言うと、Python製と聞いただけで拒否反応、アナフィラキシー、その他の症状に襲われまして、
「この歳になってPythonなんか覚えたくねぇ。定年後の乏しい脳細胞を消費したかねぇや!」
と、食わず嫌いでございました。

実は今回の導入にあたって、apt installはもちろん打ちましたし、利用するために既存の録音シェルの書き換えは最低限ありましたが、シェル構造の作り直しは全く不要でした。そしてPythonどころか、定義ファイルさえ、一行も書いておりません。


pip は Python パッケージをインストールするツールなんだそうです。このあたり、Perl爺でRubyもPythonも毛嫌いするおれには未知の世界であり、ChatGPTの言うがままです。


streamlink 6.4.2 のように表示されれば OK。

あとは、利用方法の項で紹介したように動かしてみてください。ctrl-Cで止めるか、timeoutで呼び出すか、という2つの方法を、ChatGPTは教えてくれました。

最後に、おれと同じようにcronで録音している方は、下記のように/usr/local/binなどに、シンボリックリンクを置くといいよと、ChatGPTが勧めてきました。
なぜなら、上記手順の結果、Streamlinkは ~/.local以下に格納されているから、そのままだとcrontabにいちいちフルパスを書かねばならず不便なので。

いったん、従いましたけどね。
あまりスマートではない、というか、イマ風じゃないですよね。
SlackwareやPlamo Linuxの頃を思い出すじゃないか、オイChatGPT、お前なかなか古臭くてイイ奴だナ! と言う気持ちになりました。

※おれは無料利用しかしないからかな、ChatGPTはホントときどき、古いこと言うんですよ。
※例えば起動時にうまく動かないコマンドの対処のため、「/etc/rc.localに書け」とか。
※いまどきそんな、後で何やったか絶対忘れそうな場当たり対応方法は、なかなか、アドバイスに挙げないでしょう。

■ なぜシェルでの手動解析が困難と諦めたか

以下はおまけです。
ChatGPTが言うには、いまでもRadikoの通信シーケンスは大きくは変わっておらず、下記の流れだというんですね。
(彼が言うには、Streamlinkのソースがこういう構成になっとるんだと)

1. authorize() メソッドで Auth1 → Auth2 を呼んで認証を完了
2. その戻り値から token(AuthToken)と area_id を得る
3. 時間指定ライブ(Time-Shift / タイムフリー)用 URL を https://radiko.jp/v2/api/ts/playlist.m3u8 に生成
4. URL パラメータに station_id や start/end 時刻等を追加
5. m3u8 を取得し、それをストリームとして扱う

で、一個ずつやっていったんですが、auth1は、今まで世間に流通しているスクリプトで取れるんです。
問題は、auth2あたりでして。
上の「2.」が出来ないんですよ。具体的には、area_idを取れないんです。
つまり、この4月にRadiko録音スクリプトが動かなくなったのは、上記の取得方法を複雑にしてくれちゃったからなんです。
従来の、世間に流通しているスクリプトでは、とれません。
ChatGPTの助言を受けて、手動でテストしましたが、area_idを取るには、たとえばおれだと「東京」のarea_idが欲しいのですが、IPで制約かけちゃってるらしいのね。

『東京、と判断してもらえるIPアドレスから接続しなおしてください』

とChatGPTは平然と言うんですがね、マンション光で接続しているおれに向かって何言ってんだこのポンコツAIめ、と、壊してやりたくなりましたね。

(正直言うと、ChatGPTの説明も二転三転するので、この「東京うんぬん」の説明もちょっと怪しいと思ってて、まだこの先があるかもしれません。それに、Streamlinkは、そこをどうやって回避してるのかも腑に落ちません。Streamlinkのソースをおれも読んで追ってみて、ひとつひとつ動かして確認するのが、近道なのでしょうが、もうおれはイヤになっちゃったんです。申訳ないのですが、やってません)
「不甲斐ねぇ奴だ、俺に任せろ!」
という勇者のアナタ、やってみて、なにかわかったら、ぜひ共有してくれると嬉しいです。

以上です。