Radikoのタイムフリー機能(放送後7.5日以内の番組を聴取できる仕組み)は非常に便利ですが、「聴き忘れたまま期限が切れてしまう」「手動でのダウンロード操作が面倒」という問題が常に付きまといます。
この問題を根底から解消するために、私たちは『自動番組表クローラー』と『アーカイブポータルWebUI』を開発しました。数万件の番組情報をローカルのSQLiteデータベースにクローリングしてインデックス化し、期限が迫る番組を自動検出・バックグラウンドダウンロード。さらに、直感的なWebUIから、番組検索、進行中のダウンロード進捗(プログレスバー)確認、優先録音リクエスト、さらには録音済み音声のストリーミング再生までを統合しました。本記事では、このメディアポータルの設計思想と実装プロセスを解説します。
本システムは、バックエンドエンジンとフロントエンドUIが密接に連携するサービス指向の設計となっています:
- タイムテーブル・クローラー(バックグラウンド): 起動時にRadiko公式XML APIを巡回し、指定地域(例:JP13 東京 / JP26 京都・大阪)で放送される全番組のメタデータ(タイトル、出演者、番組詳細、放送枠)を取得。SQLiteデータベース(
programsテーブル)へ自動追加します。 - 一括ダウンロード・スケジューラー: データベースを定期的に走査し、タイムシフト視聴期限が切れる前の番組を古い順から順次キューイングし、前回紹介した「サラミ式高速並列エンジン」で自動保存。
- Python/Flask APIサーバー: SQLiteデータベースの検索や番組情報の取得、ダウンロード進捗の通知、音声ファイルの再生ストリーミングなどのAPIを提供。
- グラスモーフィズムWebUI: HTML5 / Vanilla CSS / JavaScriptで構築されたモダンな操作パネル。
クローラーが巡回するXML APIは情報量が多く、そのままでは検索に適していません。そこで、以下のSQLiteスキーマを用いて、重複なくインデックスを管理しています:
CREATE TABLE IF NOT EXISTS programs (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
station_id TEXT NOT NULL,
start_at TEXT NOT NULL, -- YYYYMMDDHHMMSS 形式
end_at TEXT NOT NULL,
performers TEXT,
summary TEXT,
description TEXT,
info_url TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_programs_start ON programs(start_at);
CREATE INDEX IF NOT EXISTS idx_programs_station_start ON programs(station_id, start_at);
インデックスを適切に張ることにより、2万件〜10万件を超える番組レコードに対しても、高速なあいまい検索や日付範囲クエリを処理できます。
バックグラウンドで行われている録音の進捗率は、downloads_YYYYMM.csv やメモリ上のジョブマネージャーからパースされ、WebUIにリアルタイムでフィードバックされます。進捗バーは、0%から100%まで滑らかなCSSトランジションアニメーションで動作し、今どの番組がどれほどの速度でダウンロードされているかが視覚的に把握できます。
番組表から「今すぐ聴きたい番組」を見つけたら、「優先DL」ボタンを押すだけで即座にバックグラウンドのキューの先頭に差し込まれ、ダウンロードが開始されます。多重起動やデータベース競合を防ぐため、バックエンドではPIDファイルによるシングルインスタンスロックを搭載。複数のタブから同時にリクエストされても競合しない安全設計です。
保存先ドライブ(H:\radiko など)以外の任意のフォルダを追加指定して、過去に別のツールで録音した手持ちのM4A/MP3ファイルを一括スキャンする機能を搭載しました。ファイル名規則から「放送局ID」「放送日時」を正規表現で自動抽出し、データベース上のURLリンクとローカルファイルをマッピング。古い資産もすべてポータルのプレイヤーから一元的に再生可能になります。
デフォルトのブラウザUIを脱却し、モダンなデザインシステムを構築しました。背景のグラデーションにぼかし(backdrop-filter: blur(16px);)を適用したグラスモーフィズムカード、インタラクティブなホバー時の浮き上がり、アクティブ状態を示すグラデーション枠線などを盛り込みました。これにより、単なる「ユーティリティツール」ではなく、「愛用したくなるパーソナルメディアセンター」としての完成度を実現しています。
今回構築した自動タイムテーブルクローラーとアーカイブWebUIの統合により、Radikoタイムフリーの期限切れによる聴き逃しは大きく減少しました。高速ダウンロードエンジンと番組表データベースの連携は非常に強力で、今後は音声認識モデル(Whisper)を用いた自動文字起こし機能や、特定のキーワードが含まれる番組が放送されたら自動で通知・優先保存する「スマート・アラート機能」の統合を計画しています。ラジオとAI技術の融合は、まだまだ多くの可能性を秘めています。