以前ここでESP32 IDF/ADFでRadikoを聞くプログラムを作成しました。と言っても、完成したプログラムに自分の希望する機能を付け加えただけでしたが。その時はRadikoを聞くにはESP32 IDF/ADFでプログラムを書く必要が有ると思っていましたが、Radikoの認証さえ通ればArduinoでもプログラムが書けるのではないかと思い試してみる事にしました。
認証から音声データ取得までの流れ
先ず大前提ですが、無料会員(Radikoの会員では無いので)としてRadikoにアクセスするものとします。下記が認証から音声データを得る大まかな流れです。
- ヘッダーに情報を設定して https://radiko.jp/v2/api/auth1 にアクセス。
- サーバーから送られて来るAuthToken、Key、オフセット情報を元に文字列を作成。
- 上記の文字列を持って、https://radiko.jp/v2/api/auth2 にアクセス。
- 認証されれば、エリア情報が送られて来ます。ここまでで認証作業終了。
- エリア情報を元に聴く事が可能なラジオ局の一覧の取得。
- ラジオ局を指定してサーバーにアクセス。
- サーバーからPlayListが送られて来ます。
- PlayListに有るURLの確認
- PlayListの中身はAAC方式のファイル一覧でした。
プログラムと説明
上記1.〜5.のプロセスを書いたプログラムを以下に示します。
radiko_00.ino
#include <Arduino.h>
#include <WiFi.h>
#include <string.h>
#include "mbedtls/base64.h"
#include <HTTPClient.h>
// Enter your WiFi setup here:
const char *SSID = "XXXXXXXX";
const char *PASSWORD = "YYYYYYYY";
void setup()
{
char * auth_key = "bcd151073c03b352e1ef2fd66c32209da9ca0afa" ;
HTTPClient http;
String _auth_token, chunk_url;
int _length, _offset;
char base64_encoded[32],token_p[32];
size_t base64_len;
const char *headerKeys[] = {"X-Radiko-AuthToken", "X-Radiko-KeyLength", "X-Radiko-KeyOffset"};
int a,b;
String str;
//----------------- part0 ------------------------------------------------------------------------------
Serial.begin(115200);
delay(500);
WiFi.disconnect();
WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_STA);
WiFi.begin(SSID, PASSWORD);
while (WiFi.status() != WL_CONNECTED)
{
Serial.println("...Connecting to WiFi");
delay(1000);
}
Serial.println("Connected");
Serial.println(SSID);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Serial.println();
//----------------- part1 ------------------------------------------------------------------------------
Serial.println("==================== Part 1 ======================================");
http.begin("https://radiko.jp/v2/api/auth1");
http.addHeader("User-Agent", "esp32/4");
http.addHeader("Accept", "*/*");
http.addHeader("X-Radiko-App", "pc_html5");
http.addHeader("X-Radiko-App-Version", "0.0.1");
http.addHeader("X-Radiko-User", "dummy_user");
http.addHeader("X-Radiko-Device", "pc");
http.collectHeaders(headerKeys, 3);
a = http.GET();
Serial.println("part1 = " + String(a));
_offset = String(http.header(headerKeys[2])).toInt();
_length = String(http.header(headerKeys[1])).toInt();
_auth_token = http.header(headerKeys[0]);
Serial.println("_auth_token = " + _auth_token);
Serial.println("_offset = " + String(_offset));
Serial.println("_length = " + String(_length));
http.end();
token_p[0] = '\0';
strncpy(token_p, &auth_key[_offset], _length);
token_p[_length] = '\0';
mbedtls_base64_encode((unsigned char *) base64_encoded, sizeof(base64_encoded),&base64_len, (unsigned char *) token_p, strlen(token_p));
Serial.print("auth_key = ");
Serial.println(auth_key);
Serial.print("token_p = ");
Serial.println(token_p);
Serial.print("base64_encoded = ");
Serial.println(base64_encoded);
Serial.println();
//----------------- part2 ------------------------------------------------------------------------------
Serial.println("==================== Part 2 ======================================");
http.begin("https://radiko.jp/v2/api/auth2");
http.addHeader("X-Radiko-AuthToken", _auth_token);
http.addHeader("X-Radiko-Partialkey", base64_encoded);
http.addHeader("X-Radiko-User", "dummy_user");
http.addHeader("X-Radiko-Device", "pc");
a = http.GET();
Serial.println("part2 = " + String(a));
str = http.getString();
Serial.print("Area data = " + str);
str = str.substring(0,str.indexOf(","));
Serial.println("Area code = " + str);
http.end();
Serial.println();
//----------------- part3 ------------------------------------------------------------------------------
// http.begin("https://radiko.jp/v2/station/list/[ID].xml");
Serial.println("==================== Part 3 ======================================");
str = "https://radiko.jp/v2/station/list/" + str + ".xml";
Serial.println(str);
http.begin(str);
http.addHeader("X-Radiko-AuthToken", _auth_token);
a = http.GET();
Serial.println("part3 = " + String(a));
str = http.getString();
Serial.println(str);
Serial.println();
//----------------- part4 ------------------------------------------------------------------------------
Serial.println("==================== Part 4 ======================================");
str = "https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/playlist.m3u8";
http.begin(str);
http.addHeader("X-Radiko-AuthToken", _auth_token);
a = http.GET();
Serial.println("part4 = " + String(a));
str = http.getString();
Serial.println(str);
chunk_url = &str[str.indexOf("https")];
Serial.println(chunk_url);
http.end();
Serial.println();
//----------------- part5 ------------------------------------------------------------------------------
Serial.println("==================== Part 5 ======================================");
http.begin(chunk_url);
http.addHeader("X-Radiko-AuthToken", _auth_token);
a = http.GET();
Serial.println("part5 = " + String(a));
str = http.getString();
Serial.println(str);
Serial.println();
}
void loop()
{
while(1) NOP();
}
Part0(26から44行)
- 自宅のWiFiに接続する為のプログラムです。
- 8,9行に自宅のWiFiのデータを指定して下さい。
Part1(45から76行)AuthToken、Key、オフセット情報を元に文字列を作成
- 上記”1.”の部分のプログラムです。
- アクセスするサイトは、”https://radiko.jp/v2/api/auth1″。
- アクセスするにあたり、Headerとして先ず下記を設定します。
- http.addHeader(“User-Agent”, “esp32/4”);
- http.addHeader(“Accept”, “/“);
- http.addHeader(“X-Radiko-App”, “pc_html5”);
- http.addHeader(“X-Radiko-App-Version”, “0.0.1”);
- http.addHeader(“X-Radiko-User”, “dummy_user”);
- http.addHeader(“X-Radiko-Device”, “pc”);
- サーバーから送られて来るAuthToken、Key、オフセット情報はレスポンスHeaderに含まれます。
- その情報を取り込む為に予めその準備をします。
- 21行: 読み込みたいHeader情報の項目リストの配列を作成
- 54行: この部分で上記をHeaderに追加。
- 55行: 上記のHeaderを設定して、GETでアクセスします。
- 56行: リターンコードを表示します。200であればOKです。
- サーバーからの情報AuthToken、Key、オフセットは以下に保存されます。
- headerKeys[0] ー> AuthToken
- headerKeys[1] ー> Key
- headerKeys[2] ー> オフセット
- 57から58行: Keyとオフセットは数字に変換して保存。
- 59行: AuthTokenは文字列として保存します。
- このAuthTokenは重要は文字列です。
- 以降サーバーにアクセツする場合、常にこの文字列をHeaderに指定する必要が有ります。
- 65,66行: この部分で2nd認証用文字列の作成しています。
- 基本文字列(13行で設定 ”bcd151073c03b352e1ef2fd66c32209da9ca0afa”)を元に文字列を作成します。
- 作成される文字列は
- 先頭: 基本文字列からオフセット分移動した文字(先頭が0)
- 長さ: Key文字
- 仮に、オフセット=9、Key=16なら、”c03b352e1ef2fd66”となります。
- 68行: 上記の文字列をbase64 encodeしています。
- 2nd認証用文字列はbase64 encodeする必要が有ります。ここでその変換を行っています。
- シリアルモニターに以下の様に表示されます。
==================== Part 1 ======================================
part1 = 200
_auth_token = eH0n5YzwBf8-bk7PyKplpA
_offset = 9
_length = 16
auth_key = bcd151073c03b352e1ef2fd66c32209da9ca0afa
token_p = c03b352e1ef2fd66
base64_encoded = YzAzYjM1MmUxZWYyZmQ2Ng==
- 画面の説明
- part1 = 200 ー> 通信が正常終了した事を示すリターンコード200
- _auth_token = eH0n5YzwBf8-bk7PyKplpA ー> AuthToken
- _offset = 9 ー> オフセット9文字
- _length = 16 ー> 長さ16文字
- token_p = c03b352e1ef2fd66 ー> オフセット、Keyから作成された文字列
- base64_encoded = YzAzYjM1MmUxZWYyZmQ2Ng== ー> base64 encode後の文字列
- ここまでで”1.”が終了です。次は、AuthTokenとbase64 encodeされた文字列を使って2次承認を行います。
Part2(77から92行)エリア情報を取得
- 上記”2.”の部分のプログラムです。
- Part1で得た、AuthTokenと作成した文字列(base64 encodeされたもの)を用いてサーバーにアクセス
- アクセス先:”https://radiko.jp/v2/api/auth2″
- Headerを下記の様に設定
- http.addHeader(“X-Radiko-AuthToken”, _auth_token); ー> ここにAuthTokenを指定
- http.addHeader(“X-Radiko-Partialkey”, base64_encoded); ー>文字列をここで指定
- http.addHeader(“X-Radiko-User”, “dummy_user”);
- http.addHeader(“X-Radiko-Device”, “pc”);
- 接続方法はGET。リターンコードで200が帰って来ればOKです。(85行でコードを表示)
- 87行:サーバーからの応答を表示しています。
- JP13,東京都,tokyo Japan
- 最初のJP13がエリアコードです。このHPにエリアコードの資料が有りました。
- サーバがここを東京と判断した様です。
- JP13,東京都,tokyo Japan
- Par2はここまで。次はこのエリアで聞けるラジオ局の一覧の取得です。
==================== Part 2 ======================================
part2 = 200
Area data = JP13,東京都,tokyo Japan
Area code = JP13
Part3(93から104行)ラジオ局一覧の取得
- 上記”3.”の部分のプログラムです。
- IPのアドレス ”https://radiko.jp/v2/station/list/[ID].xml” にアクセスするとラジオ局一覧が入手出来ます
- 上記 [ID] 部分にエリアコードを入力します。96行でその処理を行っています。
- Part2最後でstr=”JP13″となっているのでIPアドレスは”https://radiko.jp/v2/station/list/JP13.xml”です。
- 下記を設定しサーバーへGETでアクセス
- アドレス:”https://radiko.jp/v2/station/list/JP13.xml”
- Header: http.addHeader(“X-Radiko-AuthToken”, _auth_token);
- リターンコード 200ならOKです。
- サーバーから送られた本体は以下の様になっています。
<?xml version="1.0" encoding="UTF-8" ?>
<stations area_id="JP13" area_name="TOKYO JAPAN">
<station>
<id>TBS</id>
<name>TBSラジオ</name>
<ascii_name>TBS RADIO</ascii_name>
<href>https://www.tbsradio.jp/</href>
<logo_xsmall>http://radiko.jp/station/logo/TBS/logo_xsmall.png</logo_xsmall>
<logo_small>http://radiko.jp/station/logo/TBS/logo_small.png</logo_small>
<logo_medium>http://radiko.jp/station/logo/TBS/logo_medium.png</logo_medium>
<logo_large>http://radiko.jp/station/logo/TBS/logo_large.png</logo_large>
<logo width="124" height="40">http://radiko.jp/v2/static/station/logo/TBS/124x40.png</logo>
<logo width="344" height="80">http://radiko.jp/v2/static/station/logo/TBS/344x80.png</logo>
<logo width="688" height="160">http://radiko.jp/v2/static/station/logo/TBS/688x160.png</logo>
<logo width="172" height="40">http://radiko.jp/v2/static/station/logo/TBS/172x40.png</logo>
<logo width="224" height="100">http://radiko.jp/v2/static/station/logo/TBS/224x100.png</logo>
<logo width="448" height="200">http://radiko.jp/v2/static/station/logo/TBS/448x200.png</logo>
<logo width="112" height="50">http://radiko.jp/v2/static/station/logo/TBS/112x50.png</logo>
<logo width="168" height="75">http://radiko.jp/v2/static/station/logo/TBS/168x75.png</logo>
<logo width="258" height="60">http://radiko.jp/v2/static/station/logo/TBS/258x60.png</logo>
<feed>http://radiko.jp/station/feed/TBS.xml</feed>
<banner>http://radiko.jp/res/banner/TBS/20200331114320.jpg</banner>
</station>
<station>
<id>QRR</id>
<name>文化放送</name>
<ascii_name>JOQR BUNKA HOSO</ascii_name>
<href>http://www.joqr.co.jp/</href>
<logo_xsmall>http://radiko.jp/station/logo/QRR/logo_xsmall.png</logo_xsmall>
<logo_small>http://radiko.jp/station/logo/QRR/logo_small.png</logo_small>
<logo_medium>http://radiko.jp/station/logo/QRR/logo_medium.png</logo_medium>
<logo_large>http://radiko.jp/station/logo/QRR/logo_large.png</logo_large>
<logo width="124" height="40">http://radiko.jp/v2/static/station/logo/QRR/124x40.png</logo>
<logo width="344" height="80">http://radiko.jp/v2/static/station/logo/QRR/344x80.png</logo>
<logo width="688" height="160">http://radiko.jp/v2/static/station/logo/QRR/688x160.png</logo>
<logo width="172" height="40">http://radiko.jp/v2/static/station/logo/QRR/172x40.png</logo>
<logo width="224" height="100">http://radiko.jp/v2/static/station/logo/QRR/224x100.png</logo>
<logo width="448" height="200">http://radiko.jp/v2/static/station/logo/QRR/448x200.png</logo>
<logo width="112" height="50">http://radiko.jp/v2/static/station/logo/QRR/112x50.png</logo>
<logo width="168" height="75">http://radiko.jp/v2/static/station/logo/QRR/168x75.png</logo>
<logo width="258" height="60">http://radiko.jp/v2/static/station/logo/QRR/258x60.png</logo>
<feed>http://radiko.jp/station/feed/QRR.xml</feed>
<banner>http://radiko.jp/res/banner/QRR/20201007125706.png</banner>
</station>
<station>
<id>LFR</id>
<name>ニッポン放送</name>
<ascii_name>JOLF NIPPON HOSO</ascii_name>
<href>http://www.1242.com/</href>
<logo_xsmall>http://radiko.jp/station/logo/LFR/logo_xsmall.png</logo_xsmall>
<logo_small>http://radiko.jp/station/logo/LFR/logo_small.png</logo_small>
<logo_medium>http://radiko.jp/station/logo/LFR/logo_medium.png</logo_medium>
<logo_large>http://radiko.jp/station/logo/LFR/logo_large.png</logo_large>
<logo width="124" height="40">http://radiko.jp/v2/static/station/logo/LFR/124x40.png</logo>
<logo width="344" height="80">http://radiko.jp/v2/static/station/logo/LFR/344x80.png</logo>
<logo width="688" height="160">http://radiko.jp/v2/static/station/logo/LFR/688x160.png</logo>
<logo width="172" height="40">http://radiko.jp/v2/static/station/logo/LFR/172x40.png</logo>
<logo width="224" height="100">http://radiko.jp/v2/static/station/logo/LFR/224x100.png</logo>
<logo width="448" height="200">http://radiko.jp/v2/static/station/logo/LFR/448x200.png</logo>
<logo width="112" height="50">http://radiko.jp/v2/static/station/logo/LFR/112x50.png</logo>
<logo width="168" height="75">http://radiko.jp/v2/static/station/logo/LFR/168x75.png</logo>
<logo width="258" height="60">http://radiko.jp/v2/static/station/logo/LFR/258x60.png</logo>
<feed>http://radiko.jp/station/feed/LFR.xml</feed>
<banner>http://radiko.jp/res/banner/LFR/20200423102824.jpg</banner>
</station>
- 本体説明
- ラジオ局は全部で16局有りました。上記は最初の3局分のデータです。
- ここで必要なデータは<id>タグで囲まれた文字列(ID)です。例えば上記のデータでは下記の3つです。
- 1番目:TBS
- 2番目:QRR
- 3番目:LFR
- サーバーから送られて来たデータ全てについてまとめると以下の様になります。
- このIDを使って音声データPlayListを入手します。
No. ID ラジオ局名
-----------------------------------------
1: TBS TBSラジオ
2: QRR 文化放送
3: LFR ニッポン放送
4: RN1 ラジオNIKKEI第1
5: RN2 ラジオNIKKEI第2
6: INT interfm
7: FMT TOKYO FM
8: FMJ J-WAVE
9: JORF ラジオ日本
10: BAYFM78 bayfm78
11: NACK5 NACK5
12: YFM FMヨコハマ
13: IBS LuckyFM 茨城放送
14: HOUSOU-DAIGAKU 放送大学
15: JOAK NHKラジオ第1(東京)
16: JOAK-FM NHK-FM(東京)
Part4(106から119行)PlayListの取得
- 上記”4.”の部分のプログラムです。
- IPアドレス:”https://f-radiko.smartstream.ne.jp/[ID]/definst/simul-stream.stream/playlist.m3u8″の[ID]部分に上記のID文字列を指定してアクセスすると、PlayListが入手出来ます。
- 今回はFMJ(J-WAVE)を指定しています。
- “https://f-radiko.smartstream.ne.jp/FMJ/definst/simul-stream.stream/playlist.m3u8″
- メディアプレーヤー(ffmpeg等)にこのIPアドレスを与えると音声の再生が出来るようですが、ESP32にメディアプレーヤーは無いのでリンク先の内容を確認します。
- 下記を設定しサーバーへGETでアクセス
- アドレス: ”https://f-radiko.smartstream.ne.jp/FMJ/definst/simul-stream.stream/playlist.m3u8″
- Header: http.addHeader(“X-Radiko-AuthToken”, _auth_token);
- リターンコード 200ならOK。本体を表示すると以下の様になっていました。
- 本体の最後にIPアドレスが有ったのでそこにアクセスしてみました。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=48732,CODECS="mp4a.40.2"
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/chunklist_w1135514250.m3u8
Part5(120から128行)PlayListに有るURLの確認
- 上記”5.”の部分のプログラムです。
- 下記を設定しサーバーへGETでアクセス
- アドレス: ”https://f-radiko.smartstream.ne.jp/FMJ/definst/simul-stream.stream/chunklist_w1135514250.m3u8”
- Header: http.addHeader(“X-Radiko-AuthToken”, _auth_token);
- リターンコード 200ならOKです。本体を表示すると以下の様になっていました。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:288554
#EXT-X-DISCONTINUITY-SEQUENCE:0
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288554.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288555.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288556.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288557.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288558.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288559.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288560.aac
#EXTINF:5.12,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288561.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288562.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288563.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288564.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288565.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288566.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288567.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288568.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288569.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288570.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288571.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288572.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288573.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288574.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288575.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288576.aac
#EXTINF:5.12,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288577.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288578.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288579.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288580.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288581.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288582.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288583.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288584.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288585.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288586.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288587.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288588.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288589.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288590.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288591.aac
#EXTINF:4.992,
https://f-radiko.smartstream.ne.jp/FMJ/_definst_/simul-stream.stream/media-u37e6lseu_w2087160318_288592.aac
- AACファイルのダンロード先が書かれたリストでした。
- これらのファイルを順番にダウンロードし再生すればラジオの音声が聞けるのだと思います。
まとめ
Radikoへの認証と音声データの取得まで可能になりました。正確には音声データはAACファイルのリンク先を示したリストファイルで実際に音声が入っているか確認は出来ていません。次回はその確認をして行きます。
参考資料
- Radikoの聞けるWebRadioの製作
- 以前ESP32 IDF/ADFでRadikoが聞けるプログラムを書いた記事。
- 開発環境が違いますが、認証の方法等を参考にします。
- radiko録音(ダウンロード)への道 その1
- Webで見つけたサイトです。
- radikoのタイムフリーとエリアフリーから番組を録音する為の方法が説明されています。
- Radikoを聴くためのスクリプト
- Pythonで書かれたプログラムです。
- ”認証してプレイリストのURLを取得するものを、ちょっとだけ修正”と有るので参考になると思われる
- ラジコ:radiko.jp の認証とプログラム処理についてのmemo
- このサイトも認証について詳しく説明しています。