PIX-SMB400(HiSilicon Hi3798CV200 搭載 Android TV)上で Mirakurun を実行し、BS4K(ISDB-S3)を受信するためのプロジェクトです。
本プロジェクトのファイル・スクリプト・ドキュメントは、技術的な調査・学習を目的としています。 利用はすべて自己責任で行ってください。
- 本手順はメーカー非公式・非サポートの改造であり、実行した時点でメーカー保証は失われます。
- ブートローダや init への介入を伴うため、デバイスが文鎮化(起動不能)する可能性があります。 実際に過去、特定の操作でデバイスが起動不能になった事例があります。
- 作者は、本プロジェクトの利用によって生じたいかなる損害(デバイスの故障・データ消失・経済的損失・第三者への損害等を含むがこれに限らない)についても、 一切の責任を負いません。
- 放送の受信・録画・復号は、利用者自身が正規に契約・受信権を持つ範囲で、私的利用の目的に限り行ってください。 関係する法令・契約・利用規約は各自の責任で遵守してください。
Part 1: USB ブートで root を取る
Step 1 ブートファイルをビルドして USB メモリを準備する
Step 2 PIX-SMB400 を USB ブートで起動する
Step 3 ADB で接続確認する
Part 2: Mirakurun のセットアップ
Step 4 Alpine Linux + Node.js をセットアップする
Step 5 Mirakurun をデプロイする
Step 6 バイナリをビルドしてデプロイする
Step 7 ACAS マスターキーを設定する
Part 3: 起動・確認
Step 8 Mirakurun を起動する
Step 9 BS4K ストリームを確認する
| 項目 | 内容 |
|---|---|
| PIX-SMB400 本体 | USB ブートピンにアクセスできる状態 |
| USB メモリ | FAT32 フォーマット、1 GB 以上 |
| kernel.img | ファームウェアから抽出した PIX-SMB400 のカーネルイメージ。ブートファイルのビルドに使用 |
| ビルド環境 | Docker(ブートファイル用)、gcc-arm-linux-gnueabi + libssl-dev(バイナリのビルド用) |
| ACAS マスターキー | 64 文字の hex |
. (リポジトリのルート)
├── README.md このファイル
├── BOOT.md USB ブートイメージの仕組みと再ビルド手順
├── Makefile デプロイ・運用コマンド集
├── boot/ USB ブート用ファイル(ビルド手順は BOOT.md)
│ ├── make_usb_boot.py bootargs.bin / root_rsa_pub_crc.bin 生成スクリプト
│ ├── patch_init.py init バイナリパッチスクリプト(SELinux bypass 等)
│ ├── build_initramfs.sh initramfs_patched.uimg ビルドスクリプト
│ └── initramfs_overlay/ initramfs オーバーレイファイル
├── bin/ ビルドしたバイナリの出力先(make build-bins で生成)
├── include/openssl/ b61dec ビルド用 OpenSSL 設定ヘッダ
├── patches/ デプロイ時に適用するパッチ(@node-rs/crc32 の JS シム)
├── scripts/
│ ├── smb400-tuner.sh Mirakurun チューナーコマンドラッパー
│ ├── start_mirakurun.sh Mirakurun 起動スクリプト(手動実行用)
│ ├── stop_android_tv.sh Android TV 不要プロセス停止
│ ├── crash_guard.sh クラッシュ監視ウォッチドッグ
│ └── setup_proot.sh Alpine + Node.js 初回セットアップ
├── config/
│ ├── tuners.yml Mirakurun チューナー設定
│ ├── channels.yml BS4K チャンネル一覧(8ch)
│ └── server.yml Mirakurun サーバー設定
└── src/ バイナリの C ソースコード(make build-bins でビルド)
├── b61dec.c ACAS BS4K デスクランブラー
├── tuner-stream-bs-ng.c BS4K(ISDB-S3)チューナー
└── startup.c Android PIE 用 _start エントリポイント
仕組みの詳細・各ファイルのビルド方法は BOOT.md を参照してください。
1-1. ブートファイルをビルドする
USB メモリに必要な 3 ファイル(bootargs.bin / root_rsa_pub_crc.bin / initramfs_patched.uimg)を boot/ のスクリプトで生成します。
initramfs_patched.uimg のビルドには、用意した kernel.img から取り出した initramfs を使用します。
# 1) bootargs.bin / root_rsa_pub_crc.bin を生成
cd boot
docker run --rm -v "$(pwd):/usb_boot" python:3.11-slim bash -c "
pip install pycryptodome -q
cd /usb_boot && python3 make_usb_boot.py
"
# 2) kernel.img から initramfs を取り出して initramfs_patched.uimg をビルド
cd ..
binwalk -e kernel.img
bash boot/build_initramfs.sh /path/to/_kernel.img.extracted/9880001-2. FAT32 でフォーマットする
sudo mkfs.fat -F 32 -n PIXBOOT /dev/sdX11-3. USB メモリをマウントする
sudo mkdir -p /mnt/PIXBOOT
sudo mount -o uid=$(id -u),gid=$(id -g) /dev/sdX1 /mnt/PIXBOOT
sudo chown $USER:$USER /mnt/PIXBOOT1-4. ブートファイルを USB メモリにコピーする
# 手動でコピー
cp boot/bootargs.bin /mnt/PIXBOOT/
cp boot/root_rsa_pub_crc.bin /mnt/PIXBOOT/
cp boot/initramfs_patched.uimg /mnt/PIXBOOT/USB メモリのルートに以下の 3 ファイルが置かれていれば OK です:
PIXBOOT/
├── bootargs.bin
├── root_rsa_pub_crc.bin
└── initramfs_patched.uimg
アンマウントして USB メモリを取り出します。
sudo umount /mnt/PIXBOOT2-1. 事前準備
- PIX-SMB400 の電源を切る
- USB Boot ピン(基板上)にアクセスできる状態にする
- USB メモリを PIX-SMB400 の USB ポートに挿入する
- LAN ケーブルを接続する
2-2. USB ブートピンをショートしながら電源を投入する
起動後 30 秒ほど待ってから接続します。
3-1. デバイスの IP アドレスを確認する
デバイスが DHCP で取得した IP アドレスをシリアルコンソールまたは arp-scan 等で確認します。
シリアルコンソールで確認する場合、 init_pix_netdbg.sh が PIXDBG: *** ADB: adb connect <デバイスのIPアドレス>:5555 *** をカーネルログに出力しています。
3-2. ADB 接続
adb connect <デバイスのIPアドレス>:5555
adb -s <デバイスのIPアドレス>:5555 shell id
# → uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc) context=u:r:su:s0uid=2000(shell) と表示された場合は eMMC から通常ブートしています(USB ブートを再確認)。
セットアップ以降は USB メモリを挿入して電源を入れるだけで、
mirakurun_proxyサービスが起動時に Mirakurun を自動起動します(make startは不要)。 ただし、安全のためクラッシュ時の自動再起動はしません。停止した場合はmake startか再起動で復帰してください。
デバイスにインターネット接続が必要です。コマンドはリポジトリのルートで実行します。
make setup-runtime ADB_TARGET=<デバイスのIPアドレス>:5555Alpine ARM32 minirootfs のダウンロードと Node.js のインストールを自動で行います。 完了まで 3〜5 分かかります。
完了確認:
adb -s <デバイスのIPアドレス>:5555 shell \
"chroot /data/local/tmp/mirakurun-root /bin/sh -c \
'export PATH=/usr/sbin:/usr/bin:/sbin:/bin; node --version'"
# → v20.x.x などが返ることPC 側で Mirakurun をビルドしてからデバイスに転送します。
# リポジトリのルートに tmp/ を作ってクローン・ビルド
git clone https://github.com/tsuyopon123/Mirakurun-BS4K.git tmp/Mirakurun-BS4K
cd tmp/Mirakurun-BS4K && npm install && npm run build && cd ../..
# デバイスにデプロイ
make deploy-mirakurun ADB_TARGET=<デバイスのIPアドレス>:5555Mirakurun のコードと設定ファイルがデバイスの /data/local/tmp/mirakurun/ にコピーされます。
6-1. バイナリをビルドする
src/ の C ソースからバイナリ(tuner-stream-bs-ng / b61dec)をビルドします。
リンクには実機の Android システムライブラリが必要なため、 make build-bins が ADB 経由で自動取得します(デバイスが USB ブート中であること)。
# 要件: sudo apt install gcc-arm-linux-gnueabi libssl-dev
make build-bins ADB_TARGET=<デバイスのIPアドレス>:55556-2. バイナリ・スクリプト・設定をデプロイする
make push-all ADB_TARGET=<デバイスのIPアドレス>:5555以下をデバイスにコピーします:
bin/tuner-stream-bs-ng— BS4K チューナーbin/b61dec— デスクランブラーscripts/*.sh— 各種スクリプトconfig/*.yml— Mirakurun 設定
設定やスクリプトを更新した場合は
make push-allだけ再実行します。 バイナリ自体を変更した場合はmake build-binsから実行します。
BS4K デスクランブルには ACAS マスターキー(64 文字 hex)が必要です。
# デバイスのシェルで実行(64HEX_KEY を実際のキーに置き換える)
adb -s <デバイスのIPアドレス>:5555 shell
echo '64HEX_KEY' > /data/local/tmp/.acas_key
chmod 600 /data/local/tmp/.acas_key
# 確認(65 = 64 文字 + 改行)
wc -c /data/local/tmp/.acas_keymake start ADB_TARGET=<デバイスのIPアドレス>:5555正常起動時:
{"current":"4.0.0-...","latest":"..."}
make test ADB_TARGET=<デバイスのIPアドレス>:5555出力例(正常):
Streaming BS4K 45168 for 5s...
0000000 7f 02 00 60 60 00 00 00 ...
7f 02 ...または7f 03 ...→ 正常(IPv4 / IPv6 TLV コンテンツ)7f ff 00 00 ...→ 未復号(b61dec の ACAS 認証失敗)→ Step 7 を確認- 出力なし → チューナーが応答していない →
make logでログを確認
再生にはmmt/tlvに対応した FFmpeg が必要です。
ffplay http://<デバイスのIPアドレス>:40772/api/channels/BS4K/45168/streamBS4K に対応した EPGStation フォークを使うと、Web UI から録画予約・視聴が行えます。
- リポジトリ: tsuyopon123/EPGStation
EPGStation をセットアップする際に mirakurunPath を http://<デバイスのIPアドレス>:40772/ に設定してください。
初回起動後、Mirakurun は channels.yml で serviceId を指定した各チャンネルを
順次チューニングしてサービスを自動登録します。全チャンネルが揃うまで数分かかります
(1 チューナーで順番にチューニングするため)。
# 登録されたサービスを確認
curl -s http://<デバイスのIPアドレス>:40772/api/services | python3 -m json.tool- サービスが登録されると、それを対象に EPG Gatherer / Service Updater が動き出します (登録サービスが 0 件のうちは、これらのジョブは対象が無いため即終了します)。
- トランスポンダの初回チューニング時、ウォームアップで稀にサービスを取り逃すことがあります
(ストリーム先頭の
7f ff)。その場合はmake startで再起動すれば取得されます (登録済みサービスは DB から復元されるため再チューニングされません)。
再起動について: Web UI の Restart ボタンはこの構成(pm2/Docker なし)では使えず 500 を返します。再起動はホストから
make restartを使ってください。
make start # Mirakurun 起動
make stop # 停止(チューナー・デスクランブラーも含む)
make restart # 再起動
make log # ログ確認(最新 50 行)
make test # BS4K 疎通テスト
make push-all # バイナリ・スクリプト・設定を更新
# デバイスの IP アドレスを指定する場合
make start ADB_TARGET=192.168.1.100:5555OEM チューナーサービス(pix_airtuner)が起動中は ACAS を占有するため、
b61dec が失敗します(GetCkc failed: -4)。
start_mirakurun.sh は起動時に自動で停止します。
再起動後に OEM サービスが復帰した場合は手動で停止:
adb -s <デバイスのIPアドレス>:5555 shell "stop pix_airtuner; stop airtuner; stop airtuner_4k"crash_guard.sh が自動起動し以下を監視します:
crash_dump32フォーク爆弾(Android 8 のクラッシュダンプ暴走)- MemAvailable < 600 MB →
stop_android_tv.shで Android TV アプリを回収(2 分クールダウン) - MemAvailable < 350 MB → Node.js を強制終了(最終手段)
Node.js のヒープは --max-old-space-size=256 で制限されています。
bootargs.bin / root_rsa_pub_crc.bin / initramfs_patched.uimg のビルド手順・
オーバーレイのカスタマイズ方法は BOOT.md を参照してください。
# ログ確認
make log ADB_TARGET=<デバイスのIPアドレス>:5555
# crash_guard ログ
adb -s <デバイスのIPアドレス>:5555 shell "tail -20 /data/local/tmp/crash_guard.log"
# メモリ確認
adb -s <デバイスのIPアドレス>:5555 shell "grep MemAvailable /proc/meminfo"