VMの場合、チューナーはパススルーしてゲスト側で認識するため、ドライバはホスト側には不要でゲスト側でインストールすればよかったのですが、コンテナの場合はホストのリソースを共有するため、ホスト側で認識している必要があります。
| コンテナ | VM | |
|---|---|---|
| カーネル | ホストと共有 | 独立 |
| ドライバ | ホスト側に必要 | VM側に必要 |
| オーバーヘッド | 軽量 | 重い |
| 独立性 | 低い | 高い |
ホストにドライバを適用したら、認識しているか確認します。
sudo dmesg | grep -i dvb
sudo dmesg | grep -i isdbt
sudo dmesg | grep -i digibest
このチューナーデバイスをコンテナ側にパススルーする必要があります。今回はpx4_drvなどの専用ドライバ特有の形式デバイスの例です。まずホスト側で確認します。
ls /dev/isdb2056*
確認できたデバイスを、コンテナに対して追加します。
lsusb -v 2>/dev/null | grep -A2 "ISDBT2056"
または
ls /dev/bus/usb/001/002
LXDコンテナにUSBデバイスを追加
lxc config device add コンテナ名 usb-tuner usb \
vendorid=<vendorid> \
productid=<productid>
vendoridとproductidは以下で確認できます。
lsusb
# 例: Bus 001 Device 002: ID 0511:0045 N'Able Technologies ISDBT2056
# ^^^^:^^^^
# vendorid:productid
lxc config device add コンテナ名 isdb2056 unix-char \
source=/dev/isdb2056video0 \
path=/dev/isdb2056video0
dvbデバイスノードも追加(チューナーに必要)
# まずホスト側でdvbデバイスを確認
ls /dev/dvb/
dvbデバイスが見えた場合、コンテナに追加します。
lxc config device add コンテナ名 dvb unix-char \
source=/dev/dvb/adapter0/frontend0 \
path=/dev/dvb/adapter0/frontend0
adapter0以外にも複数あれば同様に追加が必要です。これはWeb画面でも設定出来ます。

| フィールド | 値 |
|---|---|
| Type | USB |
| Bus number | 001 |
| Device number | 002 |
| GID | 0のまま |
| Mode | 0660のまま |
| Product ID | 004b |
先ほどのCustom deviceと同じ画面で、今度は以下のように設定します。

| フィールド | 値 |
|---|---|
| Type | Unix Char |
| Path | /dev/isdb2056video0 |
| Source | /dev/isdb2056video0 |
また、GPUをパススルーするには、GPU項目で「Attach GPU」をクリックして追加します。
Mirakurun、EDCB、KonomiTVをインストール
インストールスクリプトは、コンテナ内でrootとして実行してください。install_dtv.shとして保存し、実行権限を付けて実行します。
nano install_dtv.sh
chmod +x install_dtv.sh
sudo ./install_dtv.sh
#!/bin/bash
# =============================================================
# DTV環境セットアップスクリプト
# 対応環境: Ubuntu Desktop / LXDコンテナ (Ubuntu 25.10)
# 実行方法: sudo bash install_dtv.sh
# =============================================================
set -e
# root チェック
if [ "$(id -u)" -ne 0 ]; then
echo "エラー: このスクリプトは root で実行してください。"
echo " sudo bash $0"
exit 1
fi
# -------------------------------------------------------
# 実行環境の判定(LXD コンテナ / 通常 Ubuntu Desktop)
# -------------------------------------------------------
IS_LXD=false
if systemd-detect-virt --container 2>/dev/null | grep -qi lxc; then
IS_LXD=true
fi
echo "実行環境: $([ "$IS_LXD" = true ] && echo 'LXDコンテナ' || echo 'Ubuntu Desktop/VM')"
# 作業ユーザーの特定
REAL_USER="${SUDO_USER:-$(logname 2>/dev/null || id -un)}"
REAL_HOME=$(getent passwd "$REAL_USER" | cut -d: -f6)
DTV_DIR="$REAL_HOME/dtv"
echo "作業ユーザー: $REAL_USER ホーム: $REAL_HOME"
# ============================================================
# 0. キー入力
# ============================================================
echo "=== 1/8: キー設定 ==="
echo "キーの内容を貼り付けてください(入力後、Enter を 2 回押すと確定します):"
BCAS_CONTENT=$(sed '/^$/q')
# ============================================================
# 1. 依存パッケージのインストール
# ============================================================
echo "=== 2/8: 依存パッケージをインストール中 ==="
apt update
apt install -y \
autoconf automake cmake libtool libpcsclite-dev \
git build-essential pkg-config curl wget \
libclang-dev libdvbv5-dev libudev-dev \
nodejs npm ffmpeg liblua5.2-dev lua-zlib g++ make gcc
# ============================================================
# Node.js 18 のセットアップ (nvm / root 用)
# ============================================================
# LXDコンテナでは sudo 経由だと nvm PATH が引き継がれないため
# root の nvm として直接インストールする
export NVM_DIR="/root/.nvm"
if [ ! -d "$NVM_DIR" ]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
fi
# shellcheck source=/dev/null
source "$NVM_DIR/nvm.sh"
nvm install 18
nvm use 18
nvm alias default 18
NODE18_BIN=$(dirname "$(nvm which 18)")
export PATH="$NODE18_BIN:$PATH"
echo "Node.js バージョン確認: $(node -v) npm: $(npm -v)"
npm install -g pm2 || true
# ============================================================
# 2. TVチューナードライバ (px4_drv / isdb2056)
# ============================================================
echo "=== 3/8: ドライバをセットアップ中 ==="
mkdir -p "$DTV_DIR" && cd "$DTV_DIR"
DRIVER_VERSION="0.5.5"
DRIVER_DEB="px4-drv-dkms_${DRIVER_VERSION}_all.deb"
[ ! -f "$DRIVER_DEB" ] && curl -L -o "$DRIVER_DEB" \
"https://github.com/tsukumijima/px4_drv/releases/download/v${DRIVER_VERSION}/${DRIVER_DEB}"
# Desktop/VM: dkms でカーネルモジュールをビルド
# LXD: ホストからパススルーされるためインストール失敗しても正常
apt install -y "./${DRIVER_DEB}" || echo "警告: px4_drv dkms インストール失敗(LXDでは正常)"
modprobe px4_drv 2>/dev/null || echo "警告: px4_drv modprobe スキップ(LXDでは正常)"
# デバイスパーミッションを設定
echo "デバイスパーミッションを設定中..."
if [ "$IS_LXD" = true ]; then
# LXD: udev が使えないため chmod を直接適用
chmod 666 /dev/isdb2056video* 2>/dev/null && echo "isdb2056: OK" || echo "isdb2056: デバイスなし"
chmod 666 /dev/px4video* 2>/dev/null && echo "px4video: OK" || echo "px4video: デバイスなし"
else
# Ubuntu Desktop/VM: udev ルールで永続化 + 即時反映
tee /etc/udev/rules.d/99-dtv.rules > /dev/null <<'UDEV'
SUBSYSTEM=="usb", ATTRS{idVendor}=="0511", MODE="0666"
KERNEL=="isdb2056video*", MODE="0666", GROUP="video"
KERNEL=="px4video*", MODE="0666", GROUP="video"
UDEV
udevadm control --reload-rules
udevadm trigger
sleep 2
chmod 666 /dev/isdb2056video* 2>/dev/null && echo "isdb2056: OK" || echo "isdb2056: デバイスなし"
chmod 666 /dev/px4video* 2>/dev/null && echo "px4video: OK" || echo "px4video: デバイスなし"
# video グループに追加(次回ログイン以降に有効)
usermod -aG video "$REAL_USER" || true
fi
# デバイスが1つも見つからない場合は警告(続行はする)
if ! ls /dev/isdb2056video* /dev/px4video* 2>/dev/null | grep -q .; then
echo "警告: TVチューナーデバイスが見つかりません。"
if [ "$IS_LXD" = true ]; then
echo " LXDのプロファイルでデバイスパススルーが設定されているか確認してください。"
echo " 例: lxc config device add <container> isdb2056video0 unix-char path=/dev/isdb2056video0"
else
echo " チューナーが正しく接続・認識されているか確認してください。"
fi
fi
# ============================================================
# 3. libyakisoba / libsobacas のビルド
# ============================================================
echo "=== 4/8: 復号ライブラリのビルド ==="
cd "$DTV_DIR"
for repo in libyakisoba libsobacas; do
[ ! -d "$repo" ] && git clone "https://github.com/tsunoda14/${repo}.git"
cd "$repo"
autoreconf -i
mkdir -p build && cd build
[ "$repo" = "libyakisoba" ] && ../configure --sysconfdir=/usr/local/etc || ../configure
make -j"$(nproc)"
make install
cd "$DTV_DIR"
done
ldconfig
# ============================================================
# 4. recisdb のビルド
# ============================================================
echo "=== 5/8: Rust と recisdb のビルド ==="
# root の cargo 環境
export CARGO_HOME="/root/.cargo"
export RUSTUP_HOME="/root/.rustup"
if ! command -v cargo &>/dev/null; then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path
fi
source "$CARGO_HOME/env" 2>/dev/null || export PATH="$CARGO_HOME/bin:$PATH"
mkdir -p /usr/local/lib/pkgconfig
tee /usr/local/lib/pkgconfig/libsobacas.pc > /dev/null <<'EOF'
prefix=/usr/local
libdir=/usr/local/lib
includedir=/usr/include
Name: libsobacas
Description: PCSC compatible ECM decoder library
Version: 0.0.0
Libs: -L${libdir} -lsobacas
Cflags: -I${includedir}/PCSC
EOF
cd "$DTV_DIR"
[ ! -d recisdb-rs ] && git clone --recursive https://github.com/kazuki0824/recisdb-rs.git
cd recisdb-rs
sed -i 's/pcsclite/sobacas/g' b25-sys/build.rs
cargo build -F dvb --release
cp target/release/recisdb /usr/local/bin/
# ============================================================
# 5. B-CAS キーの配置
# ============================================================
mkdir -p /usr/local/etc
echo "$BCAS_CONTENT" | tee /usr/local/etc/bcas_keys > /dev/null
# ============================================================
# 6. チャンネルスキャンと Mirakurun 設定
# ============================================================
echo "=== 6/8: チャンネルスキャンと Mirakurun 設定 ==="
wget -q https://github.com/tsukumijima/ISDBScanner/releases/download/v1.3.3/isdb-scanner \
-O /usr/local/bin/isdb-scanner
chmod +x /usr/local/bin/isdb-scanner
# mirakurun インストール(root + Node 18 環境)
npm install -g \
--unsafe-perm \
--foreground-scripts \
--production \
--ignore-engines \
mirakurun@3.9.0-rc.4
# 設定ディレクトリを確実に作成
mkdir -p /usr/local/etc/mirakurun
mirakurun start || true
sleep 5
mirakurun stop || true
# チャンネルスキャン(root 実行のためパーミッション問題なし)
mkdir -p "$DTV_DIR/scanned"
if [ -z "$(ls -A "$DTV_DIR/scanned/" 2>/dev/null)" ]; then
isdb-scanner "$DTV_DIR/scanned/"
fi
# スキャン結果の確認
if [ ! -f "$DTV_DIR/scanned/Mirakurun/channels.yml" ]; then
echo "エラー: チャンネルスキャンが完了しませんでした。"
echo "デバイスのパススルー設定を確認してから再実行してください。"
exit 1
fi
cp -a "$DTV_DIR/scanned/Mirakurun/channels.yml" /usr/local/etc/mirakurun/channels.yml
cp -a "$DTV_DIR/scanned/Mirakurun/tuners.yml" /usr/local/etc/mirakurun/tuners.yml
chown -R root:root /usr/local/etc/mirakurun/
mirakurun start
# ============================================================
# 7. EDCB (EpgTimerSrv) のセットアップ
# ============================================================
echo "=== 7/8: EDCB セットアップ ==="
cd "$DTV_DIR"
[ ! -d EDCB ] && git clone https://github.com/xtne6f/EDCB
cd EDCB/Document/Unix
make -j"$(nproc)"
make install
make extra
make install_extra
mkdir -p /var/local/edcb
chown -R "$REAL_USER:$REAL_USER" /var/local/edcb
make setup_ini
# EMWUI
cd "$DTV_DIR"
[ ! -d EDCB_Material_WebUI ] && git clone https://github.com/EMWUI/EDCB_Material_WebUI
cp -r EDCB_Material_WebUI/HttpPublic /var/local/edcb/
cp -r EDCB_Material_WebUI/Setting /var/local/edcb/
# BonDriver
[ ! -d BonDriver_LinuxMirakc ] && \
git clone https://github.com/matching/BonDriver_LinuxMirakc.git --recurse-submodules
cd BonDriver_LinuxMirakc
make -j"$(nproc)"
cp BonDriver_LinuxMirakc.so /usr/local/lib/edcb/
cp BonDriver_LinuxMirakc.so.ini_sample /usr/local/lib/edcb/BonDriver_LinuxMirakc.so.ini
# チャンネル設定をコピー
cp "$DTV_DIR/scanned/EDCB-Wine/ChSet5.txt" /var/local/edcb/Setting/
cp "$DTV_DIR/scanned/EDCB-Wine/BonDriver_mirakc(BonDriver_mirakc).ChSet4.txt" \
'/var/local/edcb/Setting/BonDriver_LinuxMirakc(LinuxMirakc).ChSet4.txt'
# WebUI 設定
sed -i 's/^ALLOW_SETTING=.*/ALLOW_SETTING=true/' /var/local/edcb/HttpPublic/legacy/util.lua
mkdir -p /var/local/edcb/HttpPublic/video
# チューナー数を自動検出
ISDB_DEV_COUNT=$(ls /dev/isdb2056video* 2>/dev/null | wc -l)
PX4_DEV_COUNT=$(ls /dev/px4video* 2>/dev/null | wc -l)
if [ "$ISDB_DEV_COUNT" -gt 0 ]; then
# e-better DTV02A-1T1S-U: 1デバイス = 1チューナー
TUNER_COUNT=$ISDB_DEV_COUNT
elif [ "$PX4_DEV_COUNT" -gt 0 ]; then
# px4_drv: 物理1チューナーにつき4デバイス
TUNER_COUNT=$(( PX4_DEV_COUNT / 4 ))
[ "$TUNER_COUNT" -eq 0 ] && TUNER_COUNT=1
else
TUNER_COUNT=$(grep -c '^ *- name:' /usr/local/etc/mirakurun/tuners.yml 2>/dev/null || echo 1)
[ "$TUNER_COUNT" -eq 0 ] && TUNER_COUNT=1
fi
echo "検出チューナー数: ${TUNER_COUNT}"
# EpgTimerSrv.ini
tee /var/local/edcb/EpgTimerSrv.ini > /dev/null <<EOT
[SET]
EnableHttpSrv=1
EnableTCPSrv=1
RecEndMode=0
Data=1
HttpAccessControlList=+127.0.0.0/8,+10.0.0.0/8,+172.16.0.0/12,+192.168.0.0/16,+169.254.0.0/16,+100.64.0.0/10
[TunerNum]
BonDriver_LinuxMirakc(LinuxMirakc).so=${TUNER_COUNT}
[BonDriver_LinuxMirakc.so]
Count=${TUNER_COUNT}
GetEpg=1
EPGCount=0
Priority=0
EOT
# Common.ini
tee /var/local/edcb/Common.ini > /dev/null <<'EOT'
[SET]
RecFolderPath0=/var/local/edcb/HttpPublic/video
RecFolderNum=1
EOT
# systemd 登録
tee /etc/systemd/system/edcb.service > /dev/null <<EOT
[Unit]
Description=EpgTimerSrv
After=network-online.target
[Service]
Type=simple
User=$REAL_USER
ExecStart=/usr/local/bin/EpgTimerSrv
Restart=always
[Install]
WantedBy=default.target
EOT
systemctl daemon-reload
systemctl enable edcb
systemctl start edcb
# ============================================================
# 8. KonomiTV インストール
# ============================================================
echo "=== 8/8: KonomiTV インストール ==="
cd "$DTV_DIR"
curl -LO https://github.com/tsukumijima/KonomiTV/releases/latest/download/KonomiTV-Installer.elf
chmod +x KonomiTV-Installer.elf
./KonomiTV-Installer.elf
KONOMI_CONFIG=$(find /opt /usr/local /home -name "config.yaml" -path "*/KonomiTV/*" 2>/dev/null | head -1)
if [ -z "$KONOMI_CONFIG" ]; then
echo "警告: KonomiTV の config.yaml が見つかりませんでした。パスを確認してください。"
else
echo "KonomiTV config.yaml を更新中: $KONOMI_CONFIG"
sed -i 's/always_receive_tv_from_mirakurun: false/always_receive_tv_from_mirakurun: true/' "$KONOMI_CONFIG"
pm2 restart KonomiTV
fi
echo "=== 環境構築が完了しました! ==="
ハードウェアエンコードが利用出来るかどうか確実ではない場合はいったんFFmpegにしておいたほうが無難でしょう。TVTestやEDCBの動作を確認したら切り替えてみて、切り替え出来るようなら利用可能です。
/home/user/KonomiTV
tcp://127.0.0.1:4510/
FFmpeg
/var/local/edcb/HttpPublic/video
インストールが終了したら、KonomiTVを立ち上げてみます。番組表などはまだ受信されていないので、EDCBにアクセスして、EPGを受信します。
http://IPアドレス:5510
EPGを取得します。これにはかなり時間がかかります。tmpファイルが無くなれば受信完了
ls /var/local/edcb/Setting/EpgData
EDCBの再起動は下記コマンドです。
sudo systemctl restart edcb
