ubuntu
カテゴリ
モバイル端末LTE環境でTV視聴 1
2026/04/03 19時tv
外出先でWi-Fi環境があれば、Ubuntu Server Mirakurun 経由で生TSストリームTV視聴が可能で、LTE通信でも5G環境なら視聴可能だが、1時間当たり7~11GBも通信量を消費するので、使い放題契約でなければ、直ぐに契約量を枯渇してしまう。

しかもLTE通信で5G受信できる場所も少ないので、時間差は生じるが ffmpeg でエンコードしたデータ VLC で視聴してきた、ファイルの仕様は以下の通り。これならビットレート約500kbpsで、一時間当たりの通信量は約225MB程度なので、画質は悪いが途切れず視聴可能、nasune でも出来なかったことが可能となる。

TVチューナーは8chあるので、最大でも8chしか視聴できないので、外出先で視聴するチャンネルを選択する、メインはメジャーリーグの「BS NHK」「BS NHK サブ」「NHK」「NHK サブ」その他は適当に選択した。
項目設定値元のTS比
映像コーデックH.264(h264_vaapi)MPEG2→H.264
解像度854x4801440x1080→縮小
映像ビットレート400kbps約15Mbps→約1/37
音声コーデックAACAC3→AAC
音声ビットレート96kbps / 44100Hz / ステレオ圧縮
セグメント長3秒
バッファ数5セグメント(15秒分)

カスタムDockerイメージを作成するためにフォルダー作成
mkdir -p /mnt/data/docker/epgstation-custom

ffmpeg v7.0.2 をインストール Dockerfileを作成
nano /mnt/data/docker/epgstation-custom/Dockerfile
FROM l3tnun/epgstation:master-debian
RUN apt-get update && \
    apt-get install -y nkf locales && \
    echo "ja_JP.UTF-8 UTF-8" >> /etc/locale.gen && \
    locale-gen ja_JP.UTF-8 && \
    update-locale LANG=ja_JP.UTF-8 && \
    rm -rf /var/lib/apt/lists/*

VAAPIドライバー(ハードウェアエンコード)インストール
sudo apt install -y vainfo intel-media-va-driver-non-free

ユーザーをグループに追加
sudo usermod -aG video,render vafee

hls_proxy.py作成
nano /mnt/data/backup/scripts/hls_proxy.py
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler

EXTERNAL_BASE = "http://100.89.99.23:8890"
HLS_BASE = "/tmp/hls"

class Handler(BaseHTTPRequestHandler):
    def log_message(self, format, *args):
        pass

    def do_GET(self):
        parts = self.path.strip('/').split('/')
        if len(parts) < 2:
            self.send_error(404)
            return

        service_id = parts[0]
        filename = parts[1]
        filepath = f"{HLS_BASE}/{service_id}/{filename}"

        try:
            with open(filepath, 'rb') as f:
                raw = f.read()
        except FileNotFoundError:
            self.send_error(404)
            return

        if filename.endswith('.m3u8'):
            content = raw.decode('utf-8')
            lines = []
            for line in content.splitlines():
                if line and not line.startswith('#') and not line.startswith('http'):
                    line = f"{EXTERNAL_BASE}/{service_id}/{line}"
                lines.append(line)
            raw = '\n'.join(lines).encode('utf-8')
            self.send_response(200)
            self.send_header('Content-Type', 'application/vnd.apple.mpegurl')
        else:
            self.send_response(200)
            self.send_header('Content-Type', 'video/MP2T')

        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Content-Length', len(raw))
        self.end_headers()
        self.wfile.write(raw)

httpd = HTTPServer(('0.0.0.0', 8890), Handler)
print("Proxy started on port 8890")
httpd.serve_forever()

HLS(HTTP Live Streaming)起動スクリプト hls_start.sh 作成
nano /mnt/data/backup/scripts/hls_start.sh
#!/bin/bash
# HLS LTEストリーミング起動スクリプト
# 地デジ4ch + BS4ch = 計8チャンネル
# ハードウェアエンコード(Intel VAAPI)使用

HLS_BASE="/tmp/hls"
PROXY_PORT=8890
TAILSCALE_IP="100.89.99.23"
VAAPI_DEVICE="/dev/dri/renderD128"

echo "=== HLS Streaming Server 起動 (VAAPI) ==="

# 既存プロセス停止
pkill -f "ffmpeg.*api/services" 2>/dev/null
pkill -f "hls_proxy" 2>/dev/null
sleep 2

# ディレクトリ初期化
rm -rf "$HLS_BASE"

# チャンネル定義(地デジ4 + BS4)
declare -A CHANNELS=(
  ["3273601024"]="NHK総合"
  ["3273601025"]="NHKサブ"
  ["3273801040"]="日テレ"
  ["3273901048"]="TBS"
  ["400101"]="BS_NHK"
  ["400102"]="BS_NHKサブ"
  ["400141"]="BS_日テレ"
  ["400161"]="BS_TBS"
)

# ffmpeg起動(完全VAAPI使用)
for SID in "${!CHANNELS[@]}"; do
  mkdir -p "${HLS_BASE}/${SID}"
  nohup ffmpeg \
    -hwaccel vaapi \
    -hwaccel_output_format vaapi \
    -vaapi_device ${VAAPI_DEVICE} \
    -analyzeduration 10000000 \
    -probesize 10000000 \
    -fflags +discardcorrupt+genpts \
    -i "http://localhost:40772/api/services/${SID}/stream" \
    -map 0:v:0 -map 0:a:0 \
    -vf 'scale_vaapi=854:480' \
    -c:v h264_vaapi \
    -b:v 400k \
    -c:a aac -ar 44100 -b:a 96k -ac 2 \
    -sn \
    -f hls -hls_time 3 -hls_list_size 5 \
    -hls_flags delete_segments+append_list \
    -hls_segment_filename "${HLS_BASE}/${SID}/seg%03d.ts" \
    "${HLS_BASE}/${SID}/stream.m3u8" \
    > "/tmp/ffmpeg_${SID}.log" 2>&1 &
  echo "Started: ${CHANNELS[$SID]} (SID=${SID} PID=$!)"
done

# プロキシ起動
nohup python3 /mnt/data/backup/scripts/hls_proxy.py \
  > /tmp/hls_proxy.log 2>&1 &
echo "Proxy PID: $!"

# m3u8生成待機
echo "ストリーム生成待機中(30秒)..."
sleep 30

# M3U生成
cat > "${HLS_BASE}/lte.m3u" << M3UEOF
#EXTM3U
#EXTINF:-1,NHK総合(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/3273601024/stream.m3u8
#EXTINF:-1,NHKサブ(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/3273601025/stream.m3u8
#EXTINF:-1,日テレ(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/3273801040/stream.m3u8
#EXTINF:-1,TBS(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/3273901048/stream.m3u8
#EXTINF:-1,BS-NHK(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/400101/stream.m3u8
#EXTINF:-1,BS-NHKサブ(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/400102/stream.m3u8
#EXTINF:-1,BS-日テレ(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/400141/stream.m3u8
#EXTINF:-1,BS-TBS(LTE)
http://${TAILSCALE_IP}:${PROXY_PORT}/400161/stream.m3u8
M3UEOF

# 生成確認
echo ""
echo "=== 生成状況 ==="
for SID in "${!CHANNELS[@]}"; do
  if [ -f "${HLS_BASE}/${SID}/stream.m3u8" ]; then
    echo "OK: ${CHANNELS[$SID]}"
  else
    echo "NG: ${CHANNELS[$SID]}"
  fi
done

echo ""
echo "=== 完了 ==="
echo "LTE用M3U: http://${TAILSCALE_IP}:${PROXY_PORT}/lte.m3u"
sudo nano /etc/systemd/system/hls-streaming.service
[Unit]
Description=HLS Streaming Server for iPhone LTE
After=network.target docker.service
Wants=docker.service

[Service]
Type=forking
User=vafee
ExecStartPre=/bin/sleep 30
ExecStart=/mnt/data/backup/scripts/hls_start.sh
ExecStop=/usr/bin/pkill -f "ffmpeg.*api/services"
ExecStop=/usr/bin/pkill -f hls_proxy
ExecStopPost=/bin/sleep 2
ExecStopPost=/usr/bin/pkill -9 -f "ffmpeg.*api/services"
ExecStopPost=/usr/bin/pkill -9 -f hls_proxy
Restart=no

[Install]
WantedBy=multi-user.target
LTE専用のプレイリスト lte.m3u 作成
#EXTM3U
#EXTINF:-1,NHK総合(LTE)
http://100.89.99.23:8890/3273601024/stream.m3u8
#EXTINF:-1,NHKサブ(LTE)
http://100.89.99.23:8890/3273601025/stream.m3u8
#EXTINF:-1,日テレ(LTE)
http://100.89.99.23:8890/3273801040/stream.m3u8
#EXTINF:-1,TBS(LTE)
http://100.89.99.23:8890/3273901048/stream.m3u8
#EXTINF:-1,BS-NHK(LTE)
http://100.89.99.23:8890/400101/stream.m3u8
#EXTINF:-1,BS-NHKサブ(LTE)
http://100.89.99.23:8890/400102/stream.m3u8
#EXTINF:-1,BS-日テレ(LTE)
http://100.89.99.23:8890/400141/stream.m3u8
#EXTINF:-1,BS-TBS(LTE)
http://100.89.99.23:8890/400161/stream.m3u8
M3UEOF
『LTE.m3u』ファイルを以下に転送し、VLCアプリを起動しプレイリストを選択すると、チャンネル一覧が表示され、Ubuntu Server Mirakurun 経由でエンコードした映像でのTV視聴が可能となった、LTE環境が良ければ全画面表示も可能だが、画質は悪いしそれでも時々停止することもあるが、LTE環境で視聴できるのはありがたい。

Android 内部ストレージ>Movies
iPhone このiPhone内>VLC

モバイル端末LTE環境でTV視聴 2へ、続く。
記事一覧