# Raspberry Pi 3B で自宅のテレビをどこでも見る ── 構想編
>> はじめに - 転がっていた Pi 3B
引き出しに Raspberry Pi 3B が転がっていた.
2016年ごろの機体でメモリは 1GB.買った当時は何かに使うつもりだったはずだが,結局そのままになっていたやつだ.
これで地デジを受信して,手元のスマホから見られるようにしたら面白いのでは?と思いついてしまった.外出先からでも自宅のテレビが見られる,というやつだ.調べてみると先人がいくらでもいる.
ただ結論から言うと,この 1GB という数字が,その後の選択のほとんどを決めた.部品を選ぶたびに「それは載るのか」を問われ続けることになる.構想編ではその取捨選択を書いておく.
>> 1GB という制約
>>> Mirakurun ではなく mirakc
チューナーを管理する部分は,日本の地デジだと Mirakurun が定番.情報も一番多い.ただ Node.js 実装で,常駐がそれなりに重い.
代わりに選んだのが mirakc だ.Rust で書かれた実装で,常駐が 50MB 程度に収まる.公式のコンテナイメージに recdvb recpt1 arib-b25-stream-test mirakc-arib が最初から同梱されているのもありがたい.このあたりを自前でビルドし始めると,それだけで一晩溶ける.
>>> KonomiTV は Pi では動かせなさそう
視聴環境まで含めた全部入りとして KonomiTV がある.画面も綺麗で,これが動くなら自分で UI を書く必要もない.かなり惹かれた.
が,作者が Readme で 「ラズパイ4/5はサポート予定なし」 と明言している.対応しているエンコーダが QSVEncC / NVEncC / VCEEncC / rkmppenc の4つで,Pi の h264_v4l2m2m が入っていない.つまり Pi ではソフトウェアの x264 になり,実時間の変換に届かない.ちなみに Pi 5 はハードウェアエンコーダ自体が載っていないので,そもそも土俵に上がれない.
やるなら Intel N100 か RK3588 あたりの板を買え,という話だ.まぁそれはそうなんだが,今回は転がっていた 3B でやるのが趣旨なので見送ることに.
面白いのは,KonomiTV は mirakc をバックエンドにできること.既定の接続先が Mirakurun の URL になっているだけで,mirakc は互換の API を持っている.将来べつの機械を建てたとしても,チューナーは Pi 3B に挿したままでよいわけだ.そう考えると mirakc を選んでおくのは後々効いてくる.
>>> 番組表(EPGStation)は諦める
番組表と録画がほしいなら EPGStation を被せるのが定番だ.ただこれも Node で,200〜250MB は持っていかれる.
ここは見送ることにした.理由は容量そのものよりも切り分けの話で,最大のリスク(CPU が実時間に追いつくか)の上に第二のリスクを重ねると,転けたときにどちらが原因か分からなくなる.半日は溶ける.
外しておけば ffmpeg に回せるメモリが 400MB 超まで増える.しかも mirakc は残すので,後から被せられる.捨てる作業が発生しないなら,先に載せる理由はない.
>>> Docker ではなく Podman
コンテナで動かすのは決めていたが,dockerd + containerd は常駐だけで 100〜150MB を食う.1GB の機体では払いたくない出費だ.
Podman はデーモンレスで,常駐が 10MB 程度.そして同じ OCI イメージがそのまま動く.mirakc の公式イメージも何も変えずに使える.ここは迷わなかった.
>> JSMpeg という寄り道
映像をブラウザへ届ける方式で,途中 JSMpeg に寄り道した.Canvas に直接描画するので遅延が小さい,という触れ込みのやつだ.HLS だと6〜10秒は遅れるので,そこが縮むなら悪くない.
結論は却下.理由を図にするとこうなる.
エンコード側(Pi 3B) 伝送 デコード側(スマホ)
─────────────────────────────────────────────────────────────────────────
本構成 MPEG-2復号(SW) → H.264(HW) HLS/HTTP H.264(HW=専用回路)
HLS/H.264 ~~~~~~~~~~~~~ ^^^^^^^^^ ^^^^^^^^^^^^^^^^^
CPUはここだけ ほぼ無料 電池を食わん
JSMpeg MPEG-2復号(SW) → MPEG-1(SW) WebSocket MPEG-1(JS=CPU)
~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~~~~
CPU ★ここもCPU ★ここもCPU
HWエンコーダが遊ぶ 発熱・電池 MPEG-1 にはハードウェアエンコーダが無い.Pi 3B の bcm2835-codec は H.264 専用なので,JSMpeg に食わせる MPEG-1 を作るには CPU で符号化することになる.せっかくの専用回路が丸ごと遊ぶ.
しかも MPEG-1 は同じ画質を出すのに H.264 の2〜3倍のレートを要る.「外では通信量を軽くしたい」という目的と真逆だ.
もうひとつ,<canvas> にすると <video> が持っている機能を全部失う.PiP,AirPlay,ロック画面からの再生操作,バックグラウンド再生,進捗バー,全画面.どれも後から自分で書けるものではない.
JSMpeg が輝くのは「320x240 の監視カメラ,ローカル網,遅延が業務要件」という場面だと思う.電池で動く端末でフルセグを長時間見る用途とは真逆,というのが結論だった.
遅延が気になったときの手札は JSMpeg ではなく,セグメント長を詰めるか,go2rtc + WebRTC を足すかの2枚にしておく.後者なら H.264 のまま流せるので,Pi 3B のエンコーダもスマホのデコーダも生きたままだ.
>> 公開せず,tailnet の中だけに閉じる
最初は Tailscale の Funnel で外に公開するつもりでいた.そのほうがどの端末からでも見られる.
ただ Funnel は認証の仕組みを持たない公開経路で,守りは自分で仕込む秘密の cookie だけになる.テレビが誰でも見られる状態というのはさすがにまずい.
そこで tailscale serve に切り替えて,tailnet の中からしか到達できない形にした.こうすると守りは Tailscale の認証そのもの,つまりデバイス登録と ACL になる.自分で書いた cookie ゲートより遥かに堅い.
結果として cookie ゲートも,公開時間を絞るタイマーも,VPS を経由する案も全部要らなくなった.nginx の設定も 52行から 33行に縮んだ.機能を足すのではなく,前提を1つ変えたら周りが勝手に減った形だ.こういうのは気持ちがいい.
視聴先は https://tvpi.xxxxx.ts.net/ のような形になる.tailnet の中にいる端末からしか開けない.
>> メモリ収支を先に引いてみる
部品が決まったところで,載るかどうかを先に計算しておいた.
1024 MB
− gpu_mem 128 MB → Linux が見るのは 約 896 MB
− OS Lite 常駐 約 100 MB → 使えるのは 約 780 MB
────────────────────────────────────────────────
podman + conmon 約 10 MB
mirakc 約 50 MB
ffmpeg (視聴中のみ) 約 200 MB
nginx + 切替API 約 30 MB
────────────────────────────────────────────────
残り 約 400 MB 超 ← 余裕がある 400MB 残るなら十分だ.ここに EPGStation を載せると 150〜200MB まで落ちるので,やはり最初は外しておいて正解だった.
デスクトップは入れない.OS は Raspberry Pi OS Lite にする.Ubuntu ではなく Raspberry Pi OS を選んだのは,h264_v4l2m2m が Pi 財団のカーネルの機能だからだ.これが本構成の心臓部なので,ここを外すわけにいかない.vcgencmd で電圧や温度を見られるのも,あとで効いてくることになる.
>> まとめ
構想編でやったのは,要するに引き算だった.
| 部品 | 選んだもの | 落としたもの |
|---|---|---|
| チューナー管理 | mirakc | Mirakurun(重い) |
| 視聴環境 | 自作ページ | KonomiTV(Pi 非対応) |
| 番組表 | 載せない | EPGStation(後から被せられる) |
| コンテナ | Podman | Docker(常駐が重い) |
| 伝送 | HLS + H.264 | JSMpeg(HWエンコーダが遊ぶ) |
| 公開範囲 | tailnet 内のみ | Funnel 公開(認証が無い) |
1GB という制約は厳しいが,選択肢が減るぶん迷わないという副作用もあった.載らないものは最初から候補に入らない.
次は 構築編・前編.実際に組んでみたら,想定していなかったところで半日溶かすことになる.電源とコーデックの話だ.
📄Raspberry Pi 3B で自宅のテレビをどこでも見る ── 構想編
📄Raspberry Pi 3B で自宅のテレビをどこでも見る ── 構築編・前編
📄Raspberry Pi 3B で自宅のテレビをどこでも見る ── 構築編・後編