TanaRadio
spotify apple_podcasts amazon_music
L

TanaRadio

たな 394 Episodes
たな
チャッピー
ジェームズ
サリー
ひとみ
エディ

👑 現在のトップリスナー

匿名リス
1

私立工科系大学教員(科学史)の日々の出来事や雑感。日記,メモ,ブログなど
TanaRadio Blog ( https://tanakahi.hatenablog.com/ )

371 日記 | 過去3日分を古い順に再生

371 日記 | 過去3日分を古い順に再生

Jul 1, 2026 13:10 たな

あるポッドキャストの過去3日分を古い順に再生できるようになりました(フェーズ5B完了)。フェーズ5B 詳細マニュアル 過去3日分だけを古い順に並べる 0. 今回の目標 5Aでは、RSSから取得したエピソードをそのまま playlist.m3u にしました。 5Bでは、そこに次の条件を加えます。 過去3日分だけを対象にする ↓ 古いエピソードから新しいエピソードへ並べる ↓ mpvで連続再生する つまり、こういう再生になります。 3日前のエピソード ↓ 2日前のエピソード ↓ 昨日のエピソード ↓ 今日のエピソード これは「最新からつまみ食い」ではなく、「数日分を朝のラジオのように順番に追いつく」ためのモードです。構想メモでも、この「3日前から古い順」は追いつき再生として位置づけられています。 今回はまだ、以下はやりません。 複数RSS 棚選び ボタン追加 LED表示 ロータリーエンコーダー 再生履歴 ここ、欲張らなくて正解です。5Bは地味ですが、ここで「時間順に声を流す」感覚が出てきます。ラジオらしさが一段増します。 ステップ1:作業フォルダに移動する Raspberry Piでターミナルを開きます。 cd ~/tanaradio5 確認します。 pwd ls 次のようなファイルが見えればOKです。 feed.txt make_playlist_5a.py playlist.m3u 5Aが成功しているので、たぶんこの状態になっているはずです。 ステップ2:5Aのファイルは残しておく 5Aのスクリプトは成功版として残します。 今回は新しく、 make_playlist_5b.py を作ります。 5Aを上書きしない方が安全です。工作でもプログラムでも、成功した状態を残すのは大事です。ここを雑にすると、あとで「昨日の自分、何をした?」となります。昨日の自分はだいたいメモを残していません。困ったものです。 ステップ3:5B用スクリプトを作る 次を入力します。 nano make_playlist_5b.py 開いたら、以下をそのまま貼り付けてください。 #!/usr/bin/env python3 import urllib.request import xml.etree.ElementTree as ET from pathlib import Path from datetime import datetime, timedelta, timezone from email.utils import parsedate_to_datetime FEED_FILE = "feed.txt" PLAYLIST_FILE = "playlist_5b.m3u" INFO_FILE = "playlist_5b_info.txt" # 5Bでは「過去3日分」を対象にする DAYS_BACK = 3 # 表示用。日本時間で確認できるようにする JST = timezone(timedelta(hours=9)) def read_feed_url(): path = Path(FEED_FILE) if not path.exists(): raise FileNotFoundError(f"{FEED_FILE} が見つかりません。") url = path.read_text(encoding="utf-8").strip() if not url: raise ValueError(f"{FEED_FILE} にRSS URLが書かれていません。") return url def download_rss(url): print(f"RSSを取得します: {url}") request = urllib.request.Request( url, headers={ "User-Agent": "TanaRadio-Pi/5B" } ) with urllib.request.urlopen(request, timeout=20) as response: return response.read() def find_audio_url(item): # RSSのenclosureタグから音声URLを探す enclosure = item.find("enclosure") if enclosure is not None: audio_url = enclosure.attrib.get("url") if audio_url: return audio_url # 念のため media:content 形式にも軽く対応する for child in item: if child.tag.endswith("content"): audio_url = child.attrib.get("url") if audio_url: return audio_url return None def get_text(item, tag_name): element = item.find(tag_name) if element is not None and element.text: return element.text.strip() return "" def parse_pub_date(item): text = get_text(item, "pubDate") if not text: return None # RSSのpubDateは多くの場合、次のような形式 # Tue, 30 Jun 2026 08:00:00 +0900 # Tue, 30 Jun 2026 00:00:00 GMT try: dt = parsedate_to_datetime(text) except Exception: return None # タイムゾーン情報がない場合はUTCとして扱う if dt.tzinfo is None: dt = dt.replace(tzinfo=timezone.utc) # 比較しやすいようにUTCへ変換 return dt.astimezone(timezone.utc) def format_dt_jst(dt): return dt.astimezone(JST).strftime("%Y-%m-%d %H:%M") def collect_episodes(rss_data): root = ET.fromstring(rss_data) channel = root.find("channel") if channel is None: raise ValueError("RSSのchannelが見つかりません。") items = channel.findall("item") if not items: raise ValueError("RSS内にitemが見つかりません。") episodes = [] skipped_no_audio = 0 skipped_no_date = 0 for item in items: title = get_text(item, "title") audio_url = find_audio_url(item) pub_date = parse_pub_date(item) if not audio_url: skipped_no_audio += 1 continue if pub_date is None: skipped_no_date += 1 continue episodes.append({ "title": title if title else "タイトルなし", "audio_url": audio_url, "pub_date": pub_date, }) return episodes, skipped_no_audio, skipped_no_date def make_playlist(episodes, skipped_no_audio, skipped_no_date): now = datetime.now(timezone.utc) cutoff = now - timedelta(days=DAYS_BACK) selected = [ episode for episode in episodes if episode["pub_date"] >= cutoff ] # 古い順に並べる selected.sort(key=lambda episode: episode["pub_date"]) info_lines = [] info_lines.append("TanaRadio Pi フェーズ5B プレイリスト情報") info_lines.append("") info_lines.append(f"対象期間: 過去{DAYS_BACK}日分") info_lines.append(f"現在時刻: {format_dt_jst(now)} JST") info_lines.append(f"対象開始: {format_dt_jst(cutoff)} JST") info_lines.append("") info_lines.append(f"RSSから取得した音声付きエピソード数: {len(episodes)} 件") info_lines.append(f"音声URLなしでスキップ: {skipped_no_audio} 件") info_lines.append(f"公開日時なし/日時解析失敗でスキップ: {skipped_no_date} 件") info_lines.append(f"今回プレイリストに入れる数: {len(selected)} 件") info_lines.append("") info_lines.append("今回入れるエピソード:") info_lines.append("") for i, episode in enumerate(selected, start=1): info_lines.append( f"{i}. {format_dt_jst(episode['pub_date'])} JST | {episode['title']}" ) Path(INFO_FILE).write_text( "\n".join(info_lines) + "\n", encoding="utf-8" ) if not selected: raise ValueError( f"過去{DAYS_BACK}日分のエピソードが見つかりませんでした。" f"確認用に {INFO_FILE} を見てください。" ) playlist_lines = ["#EXTM3U"] for episode in selected: playlist_lines.append( f"# {format_dt_jst(episode['pub_date'])} JST | {episode['title']}" ) playlist_lines.append(episode["audio_url"]) Path(PLAYLIST_FILE).write_text( "\n".join(playlist_lines) + "\n", encoding="utf-8" ) print(f"{PLAYLIST_FILE} を作成しました。") print(f"{INFO_FILE} を作成しました。") print(f"対象エピソード数: {len(selected)} 件") def main(): try: feed_url = read_feed_url() rss_data = download_rss(feed_url) episodes, skipped_no_audio, skipped_no_date = collect_episodes(rss_data) make_playlist(episodes, skipped_no_audio, skipped_no_date) print("完了しました。") except Exception as e: print("エラーが発生しました。") print(e) if __name__ == "__main__": main() 保存します。 Ctrl + O Enter Ctrl + X ステップ4:実行できるようにする 次を入力します。 chmod +x make_playlist_5b.py ただし、前回のような「import: コマンドが見つかりません」系の事故を避けるため、今回はまず python3 で実行します。 python3 make_playlist_5b.py うまくいくと、次のように表示されます。 RSSを取得します: https://listen.style/p/xxxxx/rss playlist_5b.m3u を作成しました。 playlist_5b_info.txt を作成しました。 対象エピソード数: 3 件 完了しました。 ステップ5:作成されたファイルを確認する 次を入力します。 ls 次のようなファイルが見えればOKです。 feed.txt make_playlist_5a.py make_playlist_5b.py playlist.m3u playlist_5b.m3u playlist_5b_info.txt 今回重要なのはこの2つです。 playlist_5b.m3u playlist_5b_info.txt ステップ6:プレイリスト情報を確認する まず、確認用ファイルを開きます。 cat playlist_5b_info.txt たとえば次のような表示になります。 TanaRadio Pi フェーズ5B プレイリスト情報 対象期間: 過去3日分 現在時刻: 2026-06-30 10:20 JST 対象開始: 2026-06-27 10:20 JST RSSから取得した音声付きエピソード数: 10 件 音声URLなしでスキップ: 0 件 公開日時なし/日時解析失敗でスキップ: 0 件 今回プレイリストに入れる数: 3 件 今回入れるエピソード: 1. 2026-06-28 08:00 JST | エピソードタイトルA 2. 2026-06-29 09:00 JST | エピソードタイトルB 3. 2026-06-30 07:30 JST | エピソードタイトルC ここで見るべき点は2つです。 1. 対象開始が「約3日前」になっているか 2. エピソードが古い順に並んでいるか この2つが合っていれば、5Bの中心部分は成功です。 ステップ7:playlist_5b.m3u の中身を確認する 次を入力します。 head playlist_5b.m3u 次のように表示されればOKです。 #EXTM3U # 2026-06-28 08:00 JST | エピソードタイトルA https://... # 2026-06-29 09:00 JST | エピソードタイトルB https://... 件数も確認できます。 grep -v '^#' playlist_5b.m3u | sed '/^$/d' | wc -l これで表示される数字が、playlist_5b_info.txt の「今回プレイリストに入れる数」と同じならOKです。 ステップ8:mpvで再生する いよいよ再生します。 mpv playlist_5b.m3u 音が出れば成功です。 mpvの基本操作は5Aと同じです。 スペースキー:一時停止/再開 Enter:次へ q:終了 聴いてみて、古いエピソードから順に流れているか確認してください。 ステップ9:うまくいったら通常名にコピーする 5B版がうまく動いたら、これを通常の playlist.m3u として使えるようにしておきます。 cp playlist_5b.m3u playlist.m3u その後は、いつものように次で再生できます。 mpv playlist.m3u ただし、今後しばらくは確認しやすいので、 mpv playlist_5b.m3u のまま使っても構いません。 ステップ10:5Bの成功条件 フェーズ5Bの成功条件は、次の4つです。 1. make_playlist_5b.py を作れた 2. playlist_5b.m3u が作成された 3. playlist_5b_info.txt で「過去3日分・古い順」を確認できた 4. mpv playlist_5b.m3u で再生できた この4つができれば、5Bは成功です。 よくあるエラー 1. 過去3日分のエピソードが見つかりませんでした これは、必ずしも失敗ではありません。 原因は単純で、RSS内に本当に過去3日分のエピソードがない可能性があります。 まず確認します。 cat playlist_5b_info.txt もし「RSSから取得した音声付きエピソード数」はあるのに、「今回プレイリストに入れる数」が0なら、日付条件に合うエピソードがなかったということです。 テストだけしたい場合は、スクリプト内のここを一時的に変えます。 DAYS_BACK = 3 たとえば30日にします。 DAYS_BACK = 30 保存して、もう一度実行します。 python3 make_playlist_5b.py これで動けば、スクリプト自体は正常です。最後に DAYS_BACK = 3 に戻してください。 2. 公開日時なし/日時解析失敗でスキップ が多い RSS内の pubDate がうまく読めていない可能性があります。 LISTENの通常RSSなら、おそらく大丈夫だと思います。 ただし、別サービスのRSSでは日付形式が少し違う場合があります。 この段階では、まずLISTENの公開RSSで試すのが安全です。 3. 音声URLなしでスキップ が多い これは、RSSに音声ファイルのURLが入っていない場合です。 原因としては次が考えられます。 RSS URLが番組配信用ではない 限定配信で取得できない RSS形式が特殊 5Bではまだ公開RSSだけで進めましょう。限定配信や購入済み音声は、ここに混ぜない方がいいです。沼に足を入れるのは、長靴を履いてからです。 4. 実行するとまた import: コマンドが見つかりません と出る その場合は、次のように実行してください。 python3 make_playlist_5b.py ./make_playlist_5b.py ではなく、python3 を前につけます。 それでもダメなら、ファイルの先頭行を確認します。 head -n 3 make_playlist_5b.py 先頭がこうなっていればOKです。 #!/usr/bin/env python3 import urllib.request import xml.etree.ElementTree as ET もし #!/usr/bin/env python3 より前に余計な文字や空行がある場合は、nano で直してください。 nano make_playlist_5b.py 今回はここで止めてよいです 5Bではここまでで十分です。 RSSを読む ↓ 公開日時を見る ↓ 過去3日分だけ選ぶ ↓ 古い順に並べる ↓ mpvで再生する これができれば、次の5Cで「RSSを複数本にする」準備が整います。 ここまで来ると、TanaRadio Piはかなり「フォロー中ラジオ」の原型に近づいてきます。まだボタンもLEDも増えていませんが、中身は確実にラジオらしくなっています。#声日記 #TanaRadioPi

370 日記 | RSSからプレイリストを作る

370 日記 | RSSからプレイリストを作る

Jun 30, 2026 19:53 たな

RSSからプレイリストを作って,それにより連続再生することができました(フェーズ5A完了)。フェーズ5A 詳細マニュアル RSS 1本から playlist.m3u を作る 0. 今回の目標 今回やることはこれだけです。 LISTENなどのRSSを1本用意する ↓ PythonでRSSを読む ↓ 音声ファイルのURLを取り出す ↓ playlist.m3u を作る ↓ mpvで連続再生する 今回はまだ、以下はやりません。 複数RSS 棚選び 再生モード選び LED ロータリーエンコーダー 再生履歴 ここを欲張らないのが大事です。 まず「RSSから音声URLを取り出してmpvで鳴らす」だけ成功させます。 ステップ1:作業フォルダを作る Raspberry Piでターミナルを開きます。 以下を入力します。 mkdir -p ~/tanaradio5 cd ~/tanaradio5 確認します。 pwd 次のように表示されればOKです。 /home/ユーザー名/tanaradio5 たとえばユーザー名が pi なら、 /home/pi/tanaradio5 です。 ステップ2:mpvが使えるか確認する フェーズ4でmpvは使っているはずですが、念のため確認します。 mpv --version mpvのバージョン情報が出ればOKです。 もし、 command not found のように出たら、mpvを入れます。 sudo apt update sudo apt install -y mpv ステップ3:RSS URLを1本用意する まずは、TanaRadioなど、公開RSSを1本使います。 作業フォルダ内に feed.txt を作ります。 nano feed.txt 開いたら、RSS URLを1行だけ貼り付けます。 例: https://listen.style/p/xxxxx/rss ここは、実際のTanaRadioのRSS URLに置き換えてください。 保存します。 Ctrl + O Enter Ctrl + X 確認します。 cat feed.txt RSS URLが1行表示されればOKです。 ステップ4:Pythonスクリプトを作る 次に、RSSを読んで playlist.m3u を作るPythonファイルを作ります。 nano make_playlist_5a.py 次のコードをそのまま貼り付けます。 #!/usr/bin/env python3 import urllib.request import xml.etree.ElementTree as ET from pathlib import Path FEED_FILE = "feed.txt" PLAYLIST_FILE = "playlist.m3u" def read_feed_url(): path = Path(FEED_FILE) if not path.exists(): raise FileNotFoundError(f"{FEED_FILE} が見つかりません。") url = path.read_text(encoding="utf-8").strip() if not url: raise ValueError(f"{FEED_FILE} にRSS URLが書かれていません。") return url def download_rss(url): print(f"RSSを取得します: {url}") request = urllib.request.Request( url, headers={ "User-Agent": "TanaRadio-Pi/5A" } ) with urllib.request.urlopen(request, timeout=20) as response: return response.read() def find_audio_url(item): # RSSのenclosureタグから音声URLを探す enclosure = item.find("enclosure") if enclosure is not None: audio_url = enclosure.attrib.get("url") if audio_url: return audio_url # 念のため、media:content 形式にも軽く対応する for child in item: if child.tag.endswith("content"): audio_url = child.attrib.get("url") if audio_url: return audio_url return None def get_text(item, tag_name): element = item.find(tag_name) if element is not None and element.text: return element.text.strip() return "" def make_playlist(rss_data): root = ET.fromstring(rss_data) channel = root.find("channel") if channel is None: raise ValueError("RSSのchannelが見つかりません。") items = channel.findall("item") if not items: raise ValueError("RSS内にitemが見つかりません。") playlist_lines = ["#EXTM3U"] count = 0 for item in items: title = get_text(item, "title") audio_url = find_audio_url(item) if not audio_url: continue if title: playlist_lines.append(f"# {title}") playlist_lines.append(audio_url) count += 1 if count == 0: raise ValueError("音声URLを1件も見つけられませんでした。") Path(PLAYLIST_FILE).write_text( "\n".join(playlist_lines) + "\n", encoding="utf-8" ) print(f"{PLAYLIST_FILE} を作成しました。") print(f"音声URL数: {count} 件") def main(): try: feed_url = read_feed_url() rss_data = download_rss(feed_url) make_playlist(rss_data) print("完了しました。") except Exception as e: print("エラーが発生しました。") print(e) if __name__ == "__main__": main() 保存します。 Ctrl + O Enter Ctrl + X ステップ5:Pythonファイルを実行できるようにする chmod +x make_playlist_5a.py ステップ6:プレイリストを作る 実行します。 ./make_playlist_5a.py うまくいくと、たとえば次のように出ます。 RSSを取得します: https://listen.style/p/xxxxx/rss playlist.m3u を作成しました。 音声URL数: 10 件 完了しました。 確認します。 ls 次の3つが見えればOKです。 feed.txt make_playlist_5a.py playlist.m3u ステップ7:playlist.m3u の中身を確認する head playlist.m3u 次のように、音声URLらしきものが出ていればOKです。 #EXTM3U # エピソードタイトル https://... # エピソードタイトル https://... この段階で、RSSから音声URLを取り出すところは成功です。 ステップ8:mpvで再生する いよいよ再生します。 mpv playlist.m3u 音が出れば成功です。 mpvの基本操作は次の通りです。 スペースキー:一時停止/再開 Enter:次へ q:終了 もし音が出ない場合は、まず別の音声ファイルやYouTubeなどでRaspberry Piから音が出るか確認してください。 ここでの問題は、RSSではなく音声出力側の可能性があります。 ステップ9:成功条件 フェーズ5Aの成功条件は、次の3つです。 1. feed.txt にRSS URLを1本書けた 2. make_playlist_5a.py で playlist.m3u を作れた 3. mpv playlist.m3u で音声が再生できた この3つができれば、フェーズ5Aは成功です。 よくあるエラー 1. feed.txt が見つかりません 原因: 作業フォルダが違う feed.txt を作っていない 確認: pwd ls ~/tanaradio5 にいて、feed.txt があるか見ます。 2. 音声URLを1件も見つけられませんでした 原因としては、 RSS URLが間違っている RSSが音声配信用ではない RSSの形式が少し特殊 限定配信で取得できない などが考えられます。 まずは公開RSSで試すのがよいです。 3. mpv playlist.m3u で音が出ない 原因は大きく3つです。 Raspberry Piの音声出力先が違う USBスピーカーやBluetoothスピーカーが未接続 音量が小さい、またはミュート 確認: mpv --volume=80 playlist.m3u これで少し大きめの音量で再生できます。 今回はここで止めてよいです 5Aでは、ここまでで十分です。 RSSを読む playlist.m3uを作る mpvで鳴らす これだけです。 次の5Bでは、このプレイリスト生成に、 過去3日分だけ 古い順 という条件を加えます。 でも今はまだ、そこへ行かなくて大丈夫です。 まずは「RSSがmpvで鳴る」。ここをきっちり成功させましょう。これはフェーズ5の土台です。#声日記 #TanaRadoPi

369 日記 | フェーズ5の計画を立てる

369 日記 | フェーズ5の計画を立てる

Jun 29, 2026 13:33 たな

フェーズ5の計画を立てました。5A:RSS 1本から playlist.m3u を作る 5B:過去3日分・古い順にする 5C:RSS複数本にする 5D:既存3ボタンで mpv プレイリストを操作する 5E:棚ファイルを作り、コマンドで棚を切り替える 5F:棚選びボタン+LED1を追加する 5G:再生モードボタン+LED2を追加する 5H:必要になったら再生履歴を作る 5I:最後に音量ロータリーエンコーダーを追加する#声日記 #TanaRadioPi

368 日記 | TanaRadioの音声ファイル再生をボタンで制御

368 日記 | TanaRadioの音声ファイル再生をボタンで制御

Jun 28, 2026 23:01 たな

TanaRadioの音声ファイル再生をボタンで制御できるようになり,フェーズ4が完了しました。mpvで音声を再生し、3ボタンで制御する 今日の到達目標 今日のゴールはこれです。 Chromiumを使わずに mpvでTanaRadioの音声を再生し 3つの物理ボタンで操作する 3ボタンの役割は、これまでと同じです。 GPIO17:再生/一時停止 GPIO27:10秒戻る GPIO22:10秒進む 配線はすでに成功しているので、今日は基本的にソフトウェア側の作業です。 ステップ0:現在の成功版をバックアップする まず、今うまく動いているChromium版を保存しておきます。 cp ~/tanaradio/buttons3_playerctl.py ~/tanaradio/buttons3_playerctl_success.py 確認します。 ls ~/tanaradio buttons3_playerctl_success.py が見えればOKです。 これは保険です。 mpv版でつまずいても、Chromium版にはいつでも戻れます。 ステップ1:mpvと必要なPython部品を入れる ターミナルで次を実行します。 sudo apt update sudo apt install -y mpv python3-feedparser python3-gpiozero mpvが入ったか確認します。 mpv --version バージョン情報が出ればOKです。 mpvは、--input-ipc-server を使うことで外部プログラムからJSON IPCで操作できます。今日はPythonからこの仕組みを使います。 ステップ2:TanaRadioのRSS URLを用意する mpvは、LISTENのページそのものではなく、音声ファイルURLを再生します。 その音声ファイルURLを取得するために、今回はRSSを使います。LISTENのTanaRadioページには「RSSを開く」「LISTENのRSS URLをコピー」といった導線があります。 TanaRadioのページで、RSS URLをコピーしてください。 メモとして、ターミナルではなく紙やテキストに一度控えておくとよいです。 TanaRadio RSS URL = ここにコピーしたURL まだRSS URLがわからない場合は、ここで止まって大丈夫です。 今日の最大の山は、実は配線ではなく「mpvに渡す音声URLを取ること」です。 ステップ3:RSSから最新音声URLを取り出すスクリプトを作る 作業フォルダに移動します。 cd ~/tanaradio 新しいファイルを作ります。 nano ~/tanaradio/get_latest_audio.py 中身はこれです。 RSS_FEED_URL のところだけ、コピーしたTanaRadioのRSS URLに置き換えてください。 #!/usr/bin/env python3 import feedparser import sys RSS_FEED_URL = "ここにTanaRadioのRSS URLを貼る" feed = feedparser.parse(RSS_FEED_URL) if not feed.entries: print("RSSからエピソードを取得できませんでした。", file=sys.stderr) sys.exit(1) latest = feed.entries[0] if not latest.enclosures: print("最新エピソードに音声ファイルURLが見つかりませんでした。", file=sys.stderr) sys.exit(1) audio_url = latest.enclosures[0].href print(audio_url) 保存します。 Ctrl + O Enter Ctrl + X 実行します。 python3 ~/tanaradio/get_latest_audio.py 長いURLが表示されれば成功です。 https://...mp3 または、 https://...m4a のようなものが出るはずです。 ステップ4:mpvだけで音声を再生する まず、Pythonやボタンを使わず、mpv単体で再生できるか試します。 AUDIO_URL=$(python3 ~/tanaradio/get_latest_audio.py) mpv --no-video "$AUDIO_URL" 音声が出れば成功です。 停止するときは、 q を押します。 ここで音が出れば、Chromiumなし再生の入口を突破です。 ステップ5:mpvを外部制御できるか試す 次に、mpvを「外から操作できる状態」で起動します。 まず、もしmpvが残っていたら止めます。 pkill mpv 次に、mpvを待機状態で起動します。 mpv --no-video --idle=yes --input-ipc-server=/tmp/tanaradio-mpv.sock このターミナルはそのまま開いたままにします。 別のターミナルを開いて、次を実行します。 AUDIO_URL=$(python3 ~/tanaradio/get_latest_audio.py) python3 - <<EOF import socket, json sock = "/tmp/tanaradio-mpv.sock" audio_url = "$AUDIO_URL" message = json.dumps({"command": ["loadfile", audio_url, "replace"]}) + "\n" client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) client.connect(sock) client.send(message.encode("utf-8")) client.close() EOF これでmpvから音声が流れれば成功です。 このテストは少し面倒ですが、意味は単純です。 mpvを起動して待機させる ↓ 別のPythonからmpvへ命令を送る ↓ 音声を読み込ませる ここまでできれば、ボタン制御の準備は整っています。 mpvを終了するときは、mpvを起動しているターミナルで、 q を押します。 ステップ6:3ボタンmpv制御スクリプトを作る いよいよ本番です。 nano ~/tanaradio/buttons3_mpv.py 中身はこれです。 ここでも RSS_FEED_URL のところだけ置き換えてください。 #!/usr/bin/env python3 from gpiozero import Button from signal import pause import subprocess import socket import json import os import time import sys import feedparser RSS_FEED_URL = "ここにTanaRadioのRSS URLを貼る" MPV_SOCKET = "/tmp/tanaradio-mpv.sock" def get_latest_audio_url(): feed = feedparser.parse(RSS_FEED_URL) if not feed.entries: print("RSSからエピソードを取得できませんでした。") sys.exit(1) latest = feed.entries[0] if not latest.enclosures: print("最新エピソードに音声ファイルURLが見つかりませんでした。") sys.exit(1) title = latest.get("title", "No title") audio_url = latest.enclosures[0].href print("Latest episode:", title) print("Audio URL:", audio_url) return audio_url def start_mpv(): if os.path.exists(MPV_SOCKET): os.remove(MPV_SOCKET) subprocess.Popen([ "mpv", "--no-video", "--idle=yes", f"--input-ipc-server={MPV_SOCKET}" ]) for _ in range(50): if os.path.exists(MPV_SOCKET): print("mpv is ready.") return time.sleep(0.1) print("mpv socket was not created.") sys.exit(1) def send_mpv(command): message = json.dumps({"command": command}) + "\n" try: with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client: client.connect(MPV_SOCKET) client.send(message.encode("utf-8")) except FileNotFoundError: print("mpv socket not found. Is mpv running?") except ConnectionRefusedError: print("mpv connection refused.") def load_audio(audio_url): send_mpv(["loadfile", audio_url, "replace"]) def play_pause_pressed(): print("PLAY / PAUSE") send_mpv(["cycle", "pause"]) def back_10_pressed(): print("BACK 10 seconds") send_mpv(["seek", -10, "relative"]) def forward_10_pressed(): print("FORWARD 10 seconds") send_mpv(["seek", 10, "relative"]) play_pause = Button(17, pull_up=True, bounce_time=0.08) back_10 = Button(27, pull_up=True, bounce_time=0.08) forward_10 = Button(22, pull_up=True, bounce_time=0.08) play_pause.when_pressed = play_pause_pressed back_10.when_pressed = back_10_pressed forward_10.when_pressed = forward_10_pressed audio_url = get_latest_audio_url() start_mpv() load_audio(audio_url) print("TanaRadio mpv 3 buttons are ready.") print("GPIO17: play/pause") print("GPIO27: back 10 seconds") print("GPIO22: forward 10 seconds") pause() 保存します。 Ctrl + O Enter Ctrl + X gpiozero.Button は pull_up=True を指定すると、GPIOをHigh側へ引っ張り、ボタンの反対側をGNDへつなぐ使い方になります。これは今の配線方針と合っています。 ステップ7:3ボタンmpv版を実行する 念のため、mpvが残っていたら止めます。 pkill mpv 実行します。 python3 ~/tanaradio/buttons3_mpv.py うまくいくと、ターミナルに次のような表示が出ます。 Latest episode: ... Audio URL: ... mpv is ready. TanaRadio mpv 3 buttons are ready. GPIO17: play/pause GPIO27: back 10 seconds GPIO22: forward 10 seconds そして音声が流れます。 その状態でボタンを押します。 GPIO17 → 再生/一時停止 GPIO27 → 10秒戻る GPIO22 → 10秒進む 終了するときは、 Ctrl + C です。 そのあとmpvが残っていたら、 pkill mpv で止めます。 ステップ8:うまくいかないときの確認 1. RSSからURLが取れない まずこれを確認します。 python3 ~/tanaradio/get_latest_audio.py ここでURLが出なければ、RSS URLの貼り間違いの可能性があります。 確認点はこれです。 RSS_FEED_URL の引用符が消えていないか URLの前後に余計な空白がないか LISTENのページURLではなくRSS URLを入れているか 2. mpv単体で音が出ない これを確認します。 AUDIO_URL=$(python3 ~/tanaradio/get_latest_audio.py) echo "$AUDIO_URL" mpv --no-video "$AUDIO_URL" echo でURLが表示され、mpv で音が出なければ、音声出力設定の問題か、URLがmpvから直接再生できない可能性があります。 3. mpvは鳴るがボタンが効かない まず、前に成功したGPIOテストに戻ります。 python3 ~/tanaradio/buttons3_test.py 3ボタンが反応すれば、配線はOKです。 その場合は、mpv制御スクリプト側の問題です。 4. 1回押しただけなのに何回も反応する この値を少し増やします。 bounce_time=0.08 たとえば、 bounce_time=0.15 にします。 今日の進行順まとめ 今日は、この順番で進めるのがよいです。 1. Chromium版成功スクリプトをバックアップ 2. mpvとfeedparserをインストール 3. RSS URLを用意する 4. get_latest_audio.py で音声URLを取り出す 5. mpv単体で音声を再生する 6. mpvのIPC制御を試す 7. buttons3_mpv.py を作る 8. 3ボタンでmpvを制御する 今日の一番大事な通過点はこれです。 mpv --no-video "音声ファイルURL" で音が出ること。 ここさえ成功すれば、あとはPythonから命令を送るだけです。 今日は「ブラウザの中で鳴らす」から「TanaRadio Pi自身が直接鳴らす」への移行です。これはフェーズ4の仕上げにふさわしい作業です。#声日記 #TanaRadioPi

367 ブログ | TanaRadio Piは「ほどよい」ラジオなのかもしれない

367 ブログ | TanaRadio Piは「ほどよい」ラジオなのかもしれない

Jun 26, 2026 19:48 たな

私がTanaRadio Piを作る意味をさらに考えてみました(チャッピーが書いた原稿を読んでいます)。#TanaRadioPi

366 日記 | 3ボタンの実験

366 日記 | 3ボタンの実験

Jun 25, 2026 37:37 たな

フェーズ4の3ボタンの実験です。ボタンを押すことで,ブラウザのプレーヤーをコントロールできるところまでいきました。9. ステップ5:3ボタンへ増やす 1ボタンが成功したら、いったんシャットダウンします。 sudo shutdown -h now 電源を抜いてから、3ボタンに増やします。 配線はこれです。 GPIO17 ─ 1kΩ抵抗 ─ ボタン ─ GND GPIO27 ─ 1kΩ抵抗 ─ ボタン ─ GND GPIO22 ─ 1kΩ抵抗 ─ ボタン ─ GND GNDは共通でかまいません。 ブレッドボード上では、GNDレールを作って、各ボタンをそこへ戻すとわかりやすいです。 GPIO17 → 抵抗 → ボタン → GNDレール GPIO27 → 抵抗 → ボタン → GNDレール GPIO22 → 抵抗 → ボタン → GNDレール GPIO23は、今回は配線しません。 10. ステップ6:Pythonで3ボタンをテストする 電源を入れ、ターミナルを開きます。 3ボタンテスト用スクリプトを作ります。 nano ~/tanaradio/buttons3_test.py 中身はこれです。 from gpiozero import Button from signal import pause play_pause = Button(17, pull_up=True, bounce_time=0.08) back_10 = Button(27, pull_up=True, bounce_time=0.08) forward_10 = Button(22, pull_up=True, bounce_time=0.08) def play_pause_pressed(): print("PLAY / PAUSE button pressed") def back_10_pressed(): print("BACK 10 seconds button pressed") def forward_10_pressed(): print("FORWARD 10 seconds button pressed") play_pause.when_pressed = play_pause_pressed back_10.when_pressed = back_10_pressed forward_10.when_pressed = forward_10_pressed print("3 button test is ready.") pause() 実行します。 python3 ~/tanaradio/buttons3_test.py それぞれのボタンを押して、次のように別々の表示が出れば成功です。 PLAY / PAUSE button pressed BACK 10 seconds button pressed FORWARD 10 seconds button pressed ここまでできれば、GPIO入力実験は成功です。 フェーズ4の核心はかなり越えています。 11. うまくいかないときの確認 何も表示されない場合 確認することはこれです。 GPIO番号を間違えていないか GNDにつながっているか ボタンの向きが合っているか 抵抗が同じ列に刺さっていてショートしていないか ブレッドボードの列を勘違いしていないか まずはGPIO17の1ボタンに戻って確認してください。 3つ同時に直そうとすると、原因が見えにくくなります。 1回押しただけなのに何回も表示される場合 bounce_time を少し大きくします。 bounce_time=0.15 たとえば、3か所すべてを 0.15 にして試します。 押していないのに反応する場合 タクトスイッチの向きが怪しいです。 ブレッドボードの中央の溝をまたいでいるかを確認してください。 12. ステップ7:playerctlでChromium再生を操作する 次に、Chromium上のTanaRadio再生をコマンドで操作できるか試します。 これは最終形ではありません。 Chromiumなしのmpv版へ行く前の足場です。 まずインストールします。 sudo apt install -y playerctl playerctl はMPRIS対応メディアプレイヤーをコマンドラインから制御するツールで、再生、一時停止、停止、前後トラックなどの操作ができます。 ChromiumでTanaRadioを開き、音声を再生します。 その状態でターミナルから試します。 playerctl status 再生中なら、 Playing のように表示されます。 次に、 playerctl play-pause これで再生/一時停止が切り替われば成功です。 10秒戻る/進むは、環境によって効き方が違う場合があります。まず試します。 playerctl position 10- playerctl position 10+ 効けば、そのまま使えます。 効かなければ、フェーズ4前半では「再生/一時停止だけ成功」と考えてよいです。 13. ステップ8:3ボタンでChromium再生を操作する 3ボタン操作用スクリプトを作ります。 nano ~/tanaradio/buttons3_playerctl.py 中身はこれです。 #!/usr/bin/env python3 from gpiozero import Button from signal import pause import subprocess def run(command): print(">", " ".join(command)) subprocess.run(command, check=False) play_pause = Button(17, pull_up=True, bounce_time=0.08) back_10 = Button(27, pull_up=True, bounce_time=0.08) forward_10 = Button(22, pull_up=True, bounce_time=0.08) def play_pause_pressed(): run(["playerctl", "play-pause"]) def back_10_pressed(): run(["playerctl", "position", "10-"]) def forward_10_pressed(): run(["playerctl", "position", "10+"]) play_pause.when_pressed = play_pause_pressed back_10.when_pressed = back_10_pressed forward_10.when_pressed = forward_10_pressed print("TanaRadio 3 physical buttons are ready.") pause() 実行します。 python3 ~/tanaradio/buttons3_playerctl.py この状態で、3つのボタンを押します。 期待する動作はこれです。 GPIO17:再生/一時停止 GPIO27:10秒戻る GPIO22:10秒進む ここまでできれば、フェーズ4前半は成功です。#声日記 #TanaRadioPi

365 日記 | 1ボタンの実験

365 日記 | 1ボタンの実験

Jun 24, 2026 32:21 たな

いよいよフェーズ4。ボタンやつまみでTanaRadio Piを操作する第一歩を踏み出します。まずはボタン1つから。4. ステップ1:Raspberry Piをシャットダウンする 配線前に、必ずシャットダウンします。 ターミナルで次を実行します。 sudo shutdown -h now Raspberry Piの動作が止まったら、USB-C電源を抜きます。 ここで焦らないでください。 電源が入ったままGPIOを触るのは、初心者段階では避けた方がよいです。 5. ステップ2:ブレイクアウト基板を接続する 接続はこうです。 Raspberry Pi GPIO ↓ リボンケーブル ↓ ブレイクアウト基板 ↓ ブレッドボード 注意点は、1番ピンの向きです。 ブレイクアウト基板には、たいてい次のような表示があります。 3V3 5V GND GPIO17 GPIO27 GPIO22 最初に確認するのはこの3つです。 GPIO17 GND 5Vの位置 5Vは使いません。 「どこが5Vか」を確認するのは、使うためではなく、避けるためです。 6. ステップ3:GPIO17の1ボタンだけ配線する 最初は1個だけです。 GPIO17 ─ 1kΩ抵抗 ─ ボタン ─ GND ブレッドボード上では、次のような考え方です。 ブレイクアウト上のGPIO17 ↓ ジャンパー線 ↓ 1kΩ抵抗 ↓ ボタンの片側 ↓ ボタンの反対側 ↓ GND タクトスイッチは、ブレッドボードの中央の溝をまたぐように挿します。 ここは大事です。向きを間違えると、押していないのに常時ONのようになることがあります。 7. ステップ4:Pythonで1ボタンをテストする Raspberry Piの電源を入れます。 ターミナルを開いて、作業用フォルダを作ります。 mkdir -p ~/tanaradio cd ~/tanaradio 必要なものを入れます。 sudo apt update sudo apt install -y python3-gpiozero 1ボタンテスト用スクリプトを作ります。 nano ~/tanaradio/button17_test.py 中身はこれです。 from gpiozero import Button from signal import pause button = Button(17, pull_up=True, bounce_time=0.08) def pressed(): print("GPIO17 button pressed") button.when_pressed = pressed print("GPIO17 button test is ready.") pause() 保存して実行します。 python3 ~/tanaradio/button17_test.py ボタンを押して、次のように表示されれば成功です。 GPIO17 button pressed 終了するときは、 Ctrl + C です。 8. このスクリプトがしていること この1ボタンテストは、こういう意味です。 GPIO17をボタン入力として使う ↓ ボタンが押されたら ↓ 画面に文字を表示する ↓ プログラムは終了せず待ち続ける 重要なのはこの行です。 button = Button(17, pull_up=True, bounce_time=0.08) これは、 GPIO17にボタンがつながっている 内部プルアップを使う チャタリングを少し無視する という意味です。 bounce_time は、物理ボタンの接点が細かく震えて1回の押下が複数回として読まれる現象を抑えるための指定です。gpiozero の Button には bounce_time などの引数が用意されています。#声日記 #TanaRadioPi

364 日記 | 追加部品開封の儀

364 日記 | 追加部品開封の儀

Jun 23, 2026 09:08 たな

本日,秋月電子通商から追加注文した部品が届きましたので,箱を開けて中身を確認しました。タクトスイッチが足らないと思いましたが,よく確認したらちゃんと10個ありました。平たいスイッチが背中合わせに2個ずつくっついていたので5個と思ってしまいました。#声日記 #TanaRadioPi

363 日記 | TanaRadio Piを作る意味とは

363 日記 | TanaRadio Piを作る意味とは

Jun 21, 2026 19:49 たな

これの続きがあります → 367 ブログ | TanaRadio Piは「ほどよい」ラジオなのかもしれない#声日記 #TanaRadioPi

362 日記 | 自動でTanaRadio画面を表示する

362 日記 | 自動でTanaRadio画面を表示する

Jun 21, 2026 50:24 たな

電源を入れたら,自動的にLISTENのTanaRadioの画面が表示されるところ(フェーズ3)まで行きました。フェーズ3の目標は、以前の計画どおり「電源を入れるだけでTanaRadio画面が表示される」ことです。作業としては「自動ログイン」「Chromium自動起動」「TanaRadioページ自動表示」でした。 ここで大事なのは、最初から「自動再生」まで狙わないことです。まずは、 電源ON ↓ Raspberry Pi OSのデスクトップが開く ↓ Chromiumが自動で開く ↓ TanaRadioページが表示される を達成しましょう。 1. まず自動ログインを確認する Raspberry Piを起動したときに、パスワード入力なしでデスクトップまで行ける必要があります。 ターミナルを開いて、次を実行します。 sudo raspi-config メニューで次のように進みます。 1 System Options ↓ S6 Auto Login ↓ desktop に自動ログインする設定を Yes Raspberry Pi公式ドキュメントでも、raspi-config の System Options > S6 Auto Login から、デスクトップへの自動ログインを設定できると説明されています。 設定したら再起動します。 sudo reboot 再起動後、パスワードなしでデスクトップまで入れればOKです。 2. TanaRadioのURLをコピーしておく PiのChromiumでTanaRadioページを開き、URLをコピーします。 仮にここでは、 https://listen.style/p/xxxxxxxx として説明します。 実際には、たなさんのTanaRadioのページURLに置き換えてください。 3. 自動起動ファイルを作る Raspberry Pi OSの最近のデスクトップ環境では、起動時にプログラムを動かすために、 ~/.config/labwc/autostart を編集する方法が公式チュートリアルで紹介されています。Raspberry Pi公式のキオスクモード手順でも、このファイルを使ってデスクトップ読み込み後にChromiumを自動起動しています。 ターミナルで次を実行します。 mkdir -p ~/.config/labwc nano ~/.config/labwc/autostart 開いた画面に、次の1行を書きます。 chromium "https://listen.style/p/xxxxxxxx" --noerrdialogs --disable-infobars --no-first-run --start-maximized & もちろん、URLは実際のTanaRadioページに置き換えます。 書けたら保存します。 Ctrl + X ↓ Y ↓ Enter 4. 再起動して確認する 次を実行します。 sudo reboot 再起動後に、 デスクトップが開く ↓ Chromiumが自動で起動する ↓ TanaRadioページが表示される となれば、フェーズ3の基本形は成功です。今回,Unlock keyringでパスワード入力を求められることを無しにするのに手こずりました。その対応は以下の通りです。1. ターミナルを開く Raspberry Pi OS上でターミナルを開きます。 2. Seahorseを入れる sudo apt update sudo apt install seahorse 3. Seahorseを起動する seahorse またはメニューから、 Passwords and Keys を探します。 4. Loginキーリングのパスワードを変更する 画面内で、 Login または、 Default keyring のような項目を探します。 それを右クリックして、 Change Password を選びます。 5. 新しいパスワードを空欄にする 現在のパスワード:いま入力しているパスワード 新しいパスワード:空欄 確認:空欄 警告が出たら、TanaRadio Pi専用機として使う前提で、 Continue を選びます。#声日記 #TanaRadioPi

361 日記 | TanaRadio Piの部品を追加注文

361 日記 | TanaRadio Piの部品を追加注文

Jun 19, 2026 16:58 たな

小型パソコンをラジオのような機械にするための部品(ボタン・つまみ他)を追加注文しました。#声日記 #TanaRadioPi

360 日記 | Raspberry PiをLinuxパソコンにする

360 日記 | Raspberry PiをLinuxパソコンにする

Jun 18, 2026 1:09:02 たな

Raspberry PiのOSを起動し,ブラウザからLISTENにアクセスして,音声を再生させ,シャットダウンするところまで。思ったより時間がかかりましたが,これでフェーズ1(開封確認から音出しまで)が無事終わりました。7. ケースへ仮組みする ケースにRaspberry Piを入れます。 この段階では、できれば「完全固定」より「確認しながら仮組み」がよいです。 1. スペーサーを取り付ける 2. Raspberry Piを置く 3. ネジ位置が合うか確認 4. ファンやヒートシンクの位置を確認 5. ケーブル類が挿せるか確認 6. microSDカードが抜き差しできるか確認 ファンのケーブルがある場合は、説明書通りに接続します。 向きを間違えないように、ここは慎重に。 8. 周辺機器を接続する 電源はまだ挿しません。 まず周辺機器を先につなぎます。 1. 小型液晶モニタとRaspberry PiをHDMIケーブルで接続 2. USBキーボードを接続 3. USBマウスを接続 4. USBスピーカーを接続 Raspberry Pi 5側はmicroHDMI、モニタ側がminiHDMIなら、今回買ったmicroHDMI-miniHDMIケーブルで合っています。 9. 最後に電源を挿す ここで初めてUSB-C電源を挿します。 電源を挿す ↓ Raspberry Piが起動する ↓ 画面にロゴや起動画面が出る ↓ しばらく待つ Raspberry Piは、電源を挿すと起動します。 途中で焦って抜かないでください。初回起動は少し時間がかかることがあります。 10. 初回起動を確認する 画面が出たら、次を確認します。 デスクトップ画面が表示される マウスが動く キーボード入力できる 時刻が日本時間になっている Wi-Fiがつながっている Wi-Fiがつながっていなければ、画面右上のネットワークアイコンから接続します。 Raspberry Pi OSでは、近くのWi-Fiネットワークを表示して接続できます。 11. ブラウザでWeb確認 Chromiumブラウザを開いて、Webページが見られるか確認します。 まずは軽いページでよいです。 Raspberry Pi公式サイト LISTEN YouTube ここでインターネット接続が確認できます。 12. 音が出るか確認 次にUSBスピーカーを確認します。 1. USBスピーカーを接続 2. 画面右上の音量アイコンを確認 3. 出力先がUSBスピーカーになっているか見る 4. YouTubeなどを再生 5. 音が出るか確認 音が出ない場合は、まず音量アイコンから出力先を確認します。 HDMI側に音が出ている場合があります。 13. シャットダウンの練習 フェーズ1でかなり大事なのが、正しい終了方法です。 Raspberry Piは動作中にいきなり電源を抜かない方がよいです。 microSDカードのデータが壊れる可能性があります。 終了するときは、画面のメニューから、 Shutdown を選びます。 画面が消えて、アクセスランプの点滅が落ち着いてから電源を抜きます。 14. 2回目の起動確認 一度シャットダウンしたら、もう一度電源を入れてみます。 電源を挿す ↓ 起動する ↓ Wi-Fiにつながる ↓ ブラウザが開く ↓ 音が出る ここまで再現できれば、かなり安心です。 15. Macから接続する準備 ここまで成功したら、次に遠隔操作の準備です。 まず、Raspberry Piのホスト名を確認します。 Imagerで xxxxxxxx にしていれば、Macのターミナルから次のように試せます。 ssh ユーザー名@xxxxxxxx.local 初回は確認メッセージが出るので、yes と入力します。 その後、パスワードを入力します。 入れたら成功です。 MacからRaspberry Piに入れる これは後のフェーズでかなり便利です。 16. Raspberry Pi Connectはその次でよい Raspberry Pi Connectを使うと、ブラウザからPiの画面やシェルにアクセスできます。公式ドキュメントでは、Connectアイコンから有効化し、Raspberry Pi IDで紐づける手順が説明されています。 ただ、フェーズ1では急がなくてよいです。 順番としては、 まず画面ありで成功 次にSSH その後にRaspberry Pi Connect で十分です。 フェーズ1の完了条件 次が全部できたら、フェーズ1は完了です。 □ Raspberry Pi 5が起動した □ Wi-Fiにつながった □ ブラウザでWebページを開けた □ USBスピーカーから音が出た □ 正しくシャットダウンできた □ 2回目も問題なく起動できた □ 可能ならMacからSSH接続できた この最後のSSHは「できれば」で大丈夫です。 本来のフェーズ1完了条件は、まず「Linuxパソコンとして普通に使える」ことです。 最初の日は、欲張らずに 「起動・Wi-Fi・音出し」 までで十分です。 そこまで行けば、TanaRadio Piはもう「部品の山」ではなく、ちゃんと動き始めた道具になります。#声日記 #TanaRadioPi

359 日記 | OSを書き込む

359 日記 | OSを書き込む

Jun 17, 2026 37:18 たな

Raspberry Pi OSをmicroSDカードに書き込みました。2. Raspberry Pi本体の確認 Raspberry Pi 5本体を取り出して、ざっと見ます。 見るところはここです。 基板が割れていないか USB端子が曲がっていないか microHDMI端子が曲がっていないか USB-C電源端子が曲がっていないか GPIOピンが曲がっていないか microSDカードスロットが破損していないか GPIOピンは、将来スイッチやダイヤルをつなぐ大事な部分です。 ピンが少し曲がっている程度なら直せる場合もありますが、最初に見ておくと安心です。 3. ケース説明書を読む 次に、メタルケースの説明書を軽く読みます。 特に確認するのは次です。 Raspberry Pi 5の向き スペーサーの位置 ファンの向き ヒートシンクの貼り付け位置 GPIOにアクセスできるか ケースを閉じる前にmicroSDを挿す必要があるか ここで大事なのは、最初から完全にケースへ組み込まなくてもよいということです。 不安なら、最初の起動確認だけは裸のPi、またはケースを完全に閉じない状態でやっても構いません。 ただし、金属片やネジが基板に触れないようにしてください。 4. microSDカードにRaspberry Pi OSを書き込む MacまたはPCで作業します。 Raspberry Pi公式では、Raspberry Pi Imagerを使ってOSをmicroSDカードなどの起動メディアに入れる手順が案内されています。 手順はこうです。 1. Mac/PCにRaspberry Pi Imagerをインストール 2. microSDカードをカードリーダーに挿す 3. Raspberry Pi Imagerを起動 4. デバイスで「Raspberry Pi 5」を選ぶ 5. OSで「Raspberry Pi OS 64-bit」を選ぶ 6. ストレージでmicroSDカードを選ぶ 7. 設定を編集する 8. 書き込みを実行 9. 書き込み完了後、安全に取り外す 5. Imagerの設定 書き込み前に「設定を編集」またはカスタマイズ設定を開きます。 設定しておくとよいものは次です。 ホスト名: ユーザー名:任意 パスワード:任意 Wi-Fi SSID:自宅または研究室のWi-Fi名 Wi-Fiパスワード:そのパスワード Wi-Fi国:JP ロケール:日本 キーボード:Japanese または使うキーボードに合わせる タイムゾーン:Asia/Tokyo SSH:有効にしておく 公式ドキュメントでも、Imagerのカスタマイズ設定でホスト名、ユーザーアカウント、ネットワーク接続、SSHなどを設定できると説明されています。 初回はモニタをつなぎますが、SSHを有効にしておくと後でMacから入りやすくなります。#声日記 #TanaRadioPi

358 日記 | TanaRadio Pi 部品開封の儀

358 日記 | TanaRadio Pi 部品開封の儀

Jun 16, 2026 17:34 たな

Raspberry Piによるインターネットラジオ受信機 (TanaRadio Pi) を作るシリーズ。今回は,購入部品の開封の儀。Raspberry Pi 5 4GBACアダプター 5.1V / 5.0Ainnomaker Raspberry Pi 5用アルミケースKIOXIA microSDカード 64GBmicroHDMI - miniHDMI ケーブルフェーズ1 手順書:開封確認から音出しまで 0. 作業前に準備するもの 購入した5点に加えて、手元のものを準備します。 購入品: 1. Raspberry Pi 5 4GB本体 2. 27W USB-C電源 3. microSDカード 64GB 4. メタルケース 5. microHDMI - miniHDMIケーブル 手元のもの: 6. microSDカードリーダー 7. 小型液晶モニタ 8. USBキーボード 9. USBマウス 10. USBスピーカー 11. MacまたはPC 12. Wi-FiのSSIDとパスワード 1. 開封確認 届いたら、まず机の上に全部並べて確認します。 ここで焦って組み立てない方がいいです。 確認するものは次の通りです。 Raspberry Pi 5本体 27W USB-C電源 microSDカード 64GB メタルケース本体 ケース付属のネジ・スペーサー・ファン・ヒートシンク microHDMI - miniHDMIケーブル 説明書 特にケース付属品は小さいので、袋をすぐ捨てないでください。 ネジが一つ行方不明になるだけで、作業が急に宝探しになります。しかも全然楽しくないタイプの宝探しです。#声日記 #TanaRadioPi

357 日記 | ラジオを作りたい

357 日記 | ラジオを作りたい

Jun 14, 2026 16:59 たな

インターネットラジオ受信機 (TanaRadio Pi) を作りたいと思い,部品を注文しました:・Raspberry Pi 5 4GB・ACアダブター(5.1V/5A, 27W)・microSD 64GB・ケース・microHDMI-miniHDMIケーブル#声日記 #ラジオ #RaspberryPi #TanaRadioPi

356 トランシーバー声日記

356 トランシーバー声日記

Jun 9, 2026 00:18 たな

マダナイというポッドキャストが始まったようです。LISTENとは相性が良さそうです。#トランシーバー声日記 #声日記

355 日記 | TanaRadioの用語集を作ってみました

355 日記 | TanaRadioの用語集を作ってみました

May 31, 2026 10:18 たな

TanaRadio用語集(試作版)を作ってみました。→ TanaLexicon 2026.6.7版#声日記

354 日記 | 朗読劇台本課題は結構面白い

354 日記 | 朗読劇台本課題は結構面白い

May 29, 2026 14:47 たな

参考:323 メモ | 朗読劇台本をAIと共に書く授業#声日記

353 ポッドキャストの書籍化その後 | テックLTポッドキャストカレンダー

353 ポッドキャストの書籍化その後 | テックLTポッドキャストカレンダー

May 6, 2026 03:04 たな

現在制作中の書籍の書評です。評者はClaudeです。書評 『声で考える』著者は私立工科大学の教員で,科学史を専門とする。2023年秋,職場でも学会でもない場所で,ふと「ラジオをやりたい」と口に出した。その一言から,370回を超えるポッドキャスト配信が始まり,本書はその記録から生まれた。「声には,書かれた言葉とは異なる力がある」本書を貫く命題は,一見単純に見える。しかし著者はこれを,自己啓発書の決め台詞としてではなく,自らの体験的実証として差し出す。声で語ることは「探索」であり,書くことは「整理」である。この区別は粗っぽいようで,読み進むうちに思いのほか深い射程を持つことがわかる。本書の発見のひとつは,「語り本」と「読み本」という概念の導入である。平家物語の文献学から借用したこの区分──語られた言葉がそのまま文字になったものと,読むために書かれた言葉──を,著者はポッドキャストとテキストの関係に重ねる。声日記の文字起こしを読むとき,その人の声が脳内で自動再生される。しかし同じ人の学術論文を読んでもそうはならない。この素朴な観察が,「整った文章は個性を消す」という論点へと転がっていく。第1部でこの問いを立てた著者は,第2部の教育論へと向かう。その転換を橋渡しするのが,第3章の末尾に置かれた一節だ。授業への手応えのなさ,学生の主体性のなさ,30年分のモヤモヤを語り続けた末に著者が気づいたのは,個人的な不満の背後にある,より根の深い問題だった。「今日の学校教育が長年にわたって軽視してきたものの正体」——それは,声が担っている逡巡,身体的なリズム,整理される前の曖昧さ,そのすべてである。頭だけで考え,頭だけで答える人間を育てることに,学校教育は最適化されてきた。この見立てによって,著者個人のモヤモヤと制度批判が,一本の論理で結ばれる。第2部の教育論は,その軸の上に乗っている。学級制が子どもと教員の双方を無力化するという教育学者・柳治男の分析,不登校を「自由学習」として積極的に評価する視座,「答えようとするな,むしろ問え」という孫泰蔵の言葉の再解釈。そして「AIが書いたような感想文を学生が書き,クラスメートがいいねをつける」という授業の現場の描写。12年間の学校教育に適応することで,人はある意味でAIのように振る舞うことを学んでしまう——この一点において,第1部の「声の固有の力」と第2部の教育批判は,たしかにつながっている。第3部では,AIとの協働体験が報告される。バイブコーディングの挫折と再挑戦,一ヶ月でウェブアプリを完成させた驚き,「AIとの対話を読み返すとき,AIの声は聞こえないが,自分が投げかけた問いの声は聞こえる」という気づき。ここは本書でもっとも読み物として勢いがある箇所で,著者の知的体力を感じる。本書には,きわめて変わった出版構造がある。この読み本の背後に,370回の語り本──すべてLISTEN上で公開されているポッドキャスト配信──が実際に存在している。読者はこの本を読みながら,著者の肉声に戻ることができる。書くことと語ることの「補完関係」を,著者は主張するだけでなく,本の構造そのものに埋め込んだ。この仕掛けの誠実さを,評者は買う。声は消える。しかし,考えた声の痕跡は残る。著者はその痕跡を,読み本という形式に定着させることで,語り本には回収できない何かを書いた。その「何か」の正体を確かめるために,本書を読み,そしてLISTENに向かってほしい。 参考:345 日記 | ポッドキャストの書籍化 #テックLTポッドキャストカレンダー

352 odajinさんのライブ配信に参加しました | トランシーバー声日記

352 odajinさんのライブ配信に参加しました | トランシーバー声日記

May 4, 2026 01:19 たな

#トランシーバー声日記

将棋指せるかな?

将棋指せるかな?

将棋指せるかな?は、将棋がしたい!という有名ポッドキャストを配信されているだまさんのお嬢様が5歳になったら対決させていただくのを目標に、おばちゃんポッドキャスターのMoが将棋を学んでいく様子をお伝えする番組です。木曜日が好きなので、毎週木曜日に配信(予定笑)

TanaRadio 2

TanaRadio 2

私立工科系大学で科学史を教えている教員がお送りする有料配信チャンネル。(現在,休止中)

TanaRadio Magazine

TanaRadio Magazine

TanaRadioの配信をテーマごとにまとめたマガジンです。このマガジンのメインコンテンツである各エピソードは,この概要欄に掲載されたプレーヤー(あるいはプレーヤーの見出しリンク)から再生してください。 関連: TanaRadio ( https://listen.style/p/tanaradio/ ) TanaRadio 2 ( https://listen.style/p/tanaradio2/ )

LISTEN_staff

LISTEN_staff

テスト用アカウントです。 ポッドキャストの書き起こしサービス「LISTEN」はこちら https://listen.style/p/staff_test?uT1WThX6

はや通

はや通

メディアごっこをしながら、「メディア」について考えたいと思います。 いつか本当のメディアになれる日を夢見て。 めも - VREW - AIボイス「カズハ」 - 効果音:リン!集中させる音 - BGM:些細な希望

【ショート】STEAM NEWSまとめ

【ショート】STEAM NEWSまとめ

配信テスト中です. https://listen.style/p/steamnews?461WWtmZ