Skip to content

現在放送中のチャンネルをライブ視聴できるようにする(mpegts直送 / HLS) - #32

Merged
daig0rian merged 10 commits into
daig0rian:masterfrom
imaiworks:upstream-pr/live-viewing
Jul 15, 2026
Merged

現在放送中のチャンネルをライブ視聴できるようにする(mpegts直送 / HLS)#32
daig0rian merged 10 commits into
daig0rian:masterfrom
imaiworks:upstream-pr/live-viewing

Conversation

@imaiworks

@imaiworks imaiworks commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

概要(ライブ視聴関連PR)

現在放送中のチャンネルをそのまま視聴できるようにしました。

  • メイン画面に「現在放送中」行を新設。チャンネルを選ぶとすぐ再生開始します
  • 単押し = mpegts直送再生(低遅延。EPGStationサーバーのconfig.yml設定次第でほぼ即再生・高画質も可能。字幕は非対応)
  • 長押し = HLS再生(mpegts側が不安定なチャンネル向けのフォールバック。こちらも字幕は非対応)
  • 視聴中に「REC」ボタンでその場から録画予約(EPGStationの手動予約API使用)
  • 視聴中に「ℹ」ボタンで現在の番組情報(ジャンル・時刻・概要)をダイアログ表示
  • 「番組名更新」ボタンでチャンネルカードに現在放送中の番組名を表示(自動更新は実装していません)

実装のポイント

  • EPGStationのライブmpegts配信 (GET/streams/live/{channelId}/m2ts)は、HLSと違って開始APIが不要でした。プレイヤーが直接このURLに接続するだけで配信が始まり、切断で自動終了するシンプルな仕組みなので、streamId管理(開始・keep-alive・停止)が一切要りません。既存の「録画TS直再生」の仕組み(ProgressiveMediaSource + OkHttpDataSource)をほぼそのまま流用しています。
  • ライブHLS側は既存の「録画の追いかけ再生」の仕組みを流用。開始直後のウォームアップ中に発生する読み込みエラーのリトライを種別問わず広げることで安定性を上げています(ただまだ改善の余地あり)。

既知の制約

  • ライブ視聴はHLS・mpegtsどちらもARIB字幕・文字スーパー表示は未実装です
  • mpegts直送では、生のライブTSに対して TsReadexDataSource/ARIB字幕のネイティブ処理を通すとクラッシュすることが実機検証で判明したため、字幕処理自体を無効化しています。録画ファイルと違い生放送のTSは複数サービス多重化やPAT/PMTのタイミングが異なるためではないかと推測しています。
  • HLS側もこのPRでは字幕抽出を行っていません(今回のcmd例は-snで字幕ストリームを除外している設定なので、そもそもサーバー側で字幕データを送っていません)。
  • 画質・起動速度はサーバー側の config.ymlstream.live.ts.m2ts mode=0 の設定次第です。無変換(パススルー)が最速・最高画質ですが帯域を多く使います(地上デジタル1080iで15〜18Mbps程度)。

当方はEPGStation config.ymlのmode=0を以下の設定で開発・運用しています。

stream:
    live:
        ts:
            m2ts:
                - name: 無変換

            hls:
                - name: 1080p
                  cmd:
                      '%FFMPEG% -re -dual_mono_mode main -i pipe:0 -sn -map 0 -threads 0 -ignore_unknown
                      -max_muxing_queue_size 1024 -f hls -hls_time 3 -hls_list_size 17 -hls_allow_cache 1
                      -hls_segment_filename %streamFileDir%/stream%streamNum%-%09d.ts -hls_flags delete_segments -c:aaac -ar 48000 -b:a 192k -ac 2 -c:v libx264 -vf yadif,scale=-2:1080 -b:v 10000k -preset veryfast
                      -flags +loop-global_header %OUTPUT%'

コメントで伺った tsreadex + libaribcaption を使った字幕対応の土台があるとのこと、もし差し支えなければ知見を伺えると、mpegts版の字幕対応に活かせるかもしれません。

テスト環境

  • J:COM セットトップボックス XA401 / Android TV

  • EPGStation Version 2.10.0

    Test plan

  • チャンネル一覧行の表示確認

  • 単押しでmpegts直送再生が始まることの確認

  • 長押しでHLS再生が始まることの確認

  • 「REC」ボタンでの録画予約確認

  • 「ℹ」ボタンでの番組情報表示確認

  • 視聴画面から戻った際にストリームが解放されることの確認

TakeshiImai and others added 10 commits July 14, 2026 13:45
録画済み番組の視聴のみだったところに、EPGStationのライブHLS配信APIを使った
チャンネル視聴機能を追加。トップ画面に「現在放送中」行を新設し、選局すると
詳細画面を経由せず直接再生を開始する。録画の追いかけ再生と同じstreamId管理
(開始・keep-alive・停止)の仕組みを流用している。
「番組名更新」行を「現在放送中」の下に新設。EPGStationの/schedules/broadcasting
から全チャンネルの放映中番組をまとめて取得し、チャンネルカードに番組名を反映する。
自動更新ではなく手動更新(ボタン押下時のみ)とすることでシンプルに保っている。
- 視聴画面に「REC」ボタンを追加。現在放送中の番組をEPGStationの手動予約API
  (POST /reserves) でワンタッチ録画予約できるようにした。録画は予約した瞬間からの
  開始になる(生放送は巻き戻せないため)。
- addReserve() は当初 Call<Long> でレスポンスボディをパースしようとしていたが、
  実際のレスポンス形と一致せずGson例外でonFailureに落ちていた(EPGStation側では
  予約自体は成立していた)。Call<ResponseBody> に変更しHTTPステータスのみで
  成功判定するよう修正。
- 録画ボタンのAction はアイコンなしだと実機で描画されなかったため、既存の
  ic_sidebar_rec.xml をアイコンとして使うよう変更。
- ライブHLS開始直後のウォームアップ中に404以外のロードエラーで再生が停止して
  しまう問題に対応し、startLiveHlsPlayback() のリトライ対象を種別不問・
  20回x2秒に拡大(録画の追いかけ再生側は変更なし)。
HLS視聴(既存機能、タップ)はそのまま残し、チャンネルカード長押しで
低遅延なmpegts直送再生を試せるようにした。

- EPGStationのGET /streams/live/{channelId}/m2tsは、HLSと違い開始APIが
  不要でstreamId管理も一切いらないシンプルな仕組み(TCP接続に紐づく)。
  既存の録画TS直再生の仕組み(startDirectPlayback)をそのまま流用できる。
- 実機検証の結果、生のライブTSに字幕処理のネイティブコード
  (TsReadexDataSource/ARIB字幕)を使うとクラッシュすることが判明したため、
  mpegts直送では字幕処理を無効化している(既知の制約としてWIP.mdに記録)。
- USBデバッグなしでもクラッシュを確認できるよう、未捕捉例外を保存して
  次回起動時に表示するEpgTvApplicationを追加。

実機確認済み: HLSの約25秒に対し、mpegts直送は体感5秒程度まで低遅延化。
画質はEPGStationサーバー側のm2ts用エンコードプロファイル設定に依存する。
mpegts直送の方が低遅延・高画質にできることが確認できたため、単押しの
デフォルト動作に昇格。HLSは字幕対応が必要な場合やmpegts側が不安定な
場合のフォールバックとして長押しに割り当てる。
- RECボタンの隣にℹ️アイコンを追加。押すと現在放送中の番組情報(チャンネル名・
  ジャンル・時刻・概要・詳細説明)をダイアログで見られるようにした。既存の
  録画詳細画面の「番組情報」機能(ProgramInfoDialogFragment)をそのまま流用。
- mpegts直送再生時はシーク不可の生ストリームのためシークバーを非表示にした
  (HLSは追いかけ再生のバッファ状況が見えて便利なため残す)。Leanbackに
  シークバーの表示切り替えAPIが無いため、コントロール行のビューを直接
  R.id.playback_progressで探してGONEにする方式を採用。
  androidx.leanback.widget.SeekBarへのキャストミスで実機クラッシュしたが、
  EpgTvApplicationのクラッシュログ機能で原因を特定・修正できた。
前回クラッシュ内容ダイアログのタイトル・閉じるボタンがハードコード
されていたため、プロジェクトのi18n方針(values/values-ja-rJP)に合わせて
リソース化。閉じるボタンは既存のR.string.closeを再利用。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
EPGStation の /api/channels にはフィルタ用のクエリパラメータが無く、
全チャンネルがそのまま返る。EPGStation公式Web UIのChannelModel.isAudioVideoService
と同じ基準(ARIBサービスタイプのホワイトリスト)をクライアント側に移植し、
データ放送専用サービス等をライブ視聴列から除外する。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
DefaultLoadErrorHandlingPolicyはリトライ間隔だけでなく最大リトライ回数も
デフォルト3回に制限されており、getRetryDelayMsForで間隔を2秒に伸ばしても
3回(約6秒)で致命的エラーとしてプレイヤーが停止していた。
getMinimumLoadableRetryCountも合わせてオーバーライドし、コメント通り
最大40秒(20回x2秒)のウォームアップ待機が機能するようにする。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@daig0rian

daig0rian commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Allow edits by maintainers チェックつけていただいていたので僭越ながら直接修正をpushさせていだきました。

  • デバッグ表示周りちょっとだけ修正しています。
  • PR前から内在していて今回顕著化したバグを修正させていただきました。
  • EPGStationのUIと同じようにデータ放送専用チャンネルを除外しました。

@daig0rian

daig0rian commented Jul 15, 2026

Copy link
Copy Markdown
Owner

tsreadex + libaribcaptionでクラッシュする件、issues に追加しました。
字幕出すには割とこれが必須なので原因究明したいですね。
おそらくですが、設定>再生設定>録画を再生するプレイヤー内蔵 にして生TS収録を見ると、tsreadex + libaribcaptionを使うので、同じようにクラッシュするはずです。

@daig0rian

Copy link
Copy Markdown
Owner

現行の実装は録画追いかけ再生も含めてmode=0決め打ちなので、そこをケアする issue を追加しました

@daig0rian
daig0rian merged commit 5d95d18 into daig0rian:master Jul 15, 2026
@daig0rian

daig0rian commented Jul 15, 2026

Copy link
Copy Markdown
Owner

マージしました!
素晴らしいPRありがとうございました。最初ビルド&ロードして「現在放送中」がリストされしかもスムーズに再生がされたときは思わず「おお!」っと声がでました。これからもよければPRいただければうれしいです。

@imaiworks
imaiworks deleted the upstream-pr/live-viewing branch July 16, 2026 01:41
@imaiworks

Copy link
Copy Markdown
Contributor Author

マージありがとうございました。所々やり残りのままだったこと大変失礼しました。それらもまとめていただけまして感謝しております。ありがとうございました。
とても素晴らしいアプリだったからこそ「現在放送中」機能も対応してみようというモチベーションになりました。このアプリ1つでTV環境がもっと快適にできるよう今後も進めていきたいと思います。その際はまたご指導いただけますとありがたく思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants