観る
ライブ・追っかけ・録画をブラウザで観るときの使い方です。録画の観る画面 (/watch/<id>) とテレビのアプリは
library.md、画面の作りは player.md にあります。
放送中のものもブラウザで観られます (/live)。WebSocket + MSE で放送に追いつき続けます (作りは stream.md)。
局は右の一覧から切り替えます。止めれば追っかけ再生になり (速さを選べ、追いついたら自分でライブに戻る)、
二カ国語・解説放送の音声も選べます (⚙ の「音声」)。
触らないでいると 2.5 秒で引っ込み、マウスを動かすか指で押せば戻ります (止めていても同じ)。
キーボードでは 空白・k で再生、← → で 10秒、c で字幕、s で切り抜き、f で全画面、< > で速さ、m で消音です (観る画面と追っかけ)。
端末ごとに決めておくものは操作バーの ⚙ (再生の設定) にまとめてあります: CMスキップ・アンビエントモード・ バックグラウンド再生・互換モード・字幕 (オフと言語)・音声 (二カ国語・解説放送)・コーデック。
切れたら繋ぎ直します
Section titled “切れたら繋ぎ直します”サーバを入れ替えると(デプロイ)、観ている最中に配信が切れます。 コンテナごと作り直すので 数十秒戻りませんが、戻ることは分かっているので、すぐには諦めません。
| 切れたあと | |
|---|---|
| ライブ | WebSocket を張り直して同じ局を選び直す(1秒→2秒→…10秒で頭打ち)。回数の上限は無い |
| 観る画面 | 同じファイルを読み直して切れた瞬間の位置へ戻す(15秒おきの続きではなく)。待ちは同じく倍々で10秒が頭打ち。続けて8回(約1分)で諦めて、観られる先 (Chrome・Edge かテレビのアプリ) を案内する。その場で流しているもの (remux-player.ts) と互換モードで canvas に描いているもの (canvas-player.ts) は、観ていた位置からリクエストし直す (数は同じ) |
どちらも待っている間は「繋ぎ直しています」と出します。読めない形式や壊れたファイルは 読み直しません。 何度やっても同じなので、すぐ観られる先を案内します。
裏に回したら止めます
Section titled “裏に回したら止めます”バックグラウンド再生は既定でオフです。 ホームへ戻る・別のアプリやタブへ移ると止め、戻ってきたら
続きから再開します(ライブで放送の今に張り付いていたなら、放送の今へ戻る)。オン/オフは再生画面の
⚙ の「バックグラウンド再生」で、端末ごとに覚えます(速さ・CM スキップと同じ localStorage)。
| オフ(既定) | オン | |
|---|---|---|
| 裏に回したとき | 止める | 止めない |
| OS・ブラウザが自分で小窓にする(全画面からホームへ戻った iPhone など) | させない(disablePictureInPicture) |
任せる |
| 放送のままの MPEG-2 の音(Safari) | Audio Session は auto のまま |
playback(裏でも鳴らす) |
| 放送のままの MPEG-2 の音(Safari 以外) | ページ(Web Audio)から直に鳴らす | <audio> を通して鳴らす(メディアの再生として扱わせる) |
押して開いた小窓(pip.svelte.ts)はオフでも使えます。 出している間は裏に回しても止めず、
MPEG-2 の音もオンと同じ鳴らし方にします。閉じた時点でまだ裏なら、そこで止めます。
MPEG-2 の音を <audio> に通すのは、Web Audio の音を効果音と同じに扱って裏で止めるブラウザが
あるからです(テスラの車載ブラウザ)。<audio> を通すと「メディアの再生」になり、ロック画面・車の操作・
ブラウザの再生中の通知にも出て、そこで押した止める・再開は操作バーに反映します(RawEngine の remote)。
Media Session のタイトルはまだ出していません(ページのタイトルが出る)。
全画面にする方法は端末で変えます
Section titled “全画面にする方法は端末で変えます”全画面にするのは枠ごとです(映像だけでなく字幕・データ放送・操作列も一緒に大きくする)。 ボタンのアイコン(広げる/縮める)はどの方法でも今の状態を映します。
| 端末 | 全画面にする | 戻す |
|---|---|---|
| PC・Android・iPadOS 16.4 以降 | requestFullscreen() |
ボタン・f・Esc・端末の戻る(UA が持つ) |
| それより前の iPadOS | webkitRequestFullscreen() |
同上 |
| iPhone の Safari | 枠を画面いっぱいに広げる(position: fixed。後ろのページは止めて黒く) |
ボタン・f・Esc・戻る(広げたときに履歴を1段積む。もう一度戻ると前の画面へ) |
iPhone は要素の全画面を持たず、あるのは <video> だけの webkitEnterFullscreen です。
あれは映像だけを OS の再生画面に渡すので字幕・データ放送・操作列が置いていかれ、使いません。
広げたときの向きは固定できません(iPhone の Safari は screen.orientation.lock を持たない)。
横に持てば横いっぱいになります。別の画面へ移ると畳みます。
ホーム画面に置く
Section titled “ホーム画面に置く”denpa は PWA なので、ブラウザの「ホーム画面に追加」でアプリのように開けます (アドレス欄もタブも出ません)。
名前が2つあると、置いたアイコンが見分けられません (どちらも「denpa」でアイコンも同じ)。
そこで、どの名前で来たかで表示名を変えられます (PWA_NAMES)。
PWA_NAMES='tv.example.com=denpa,tv.lan.example.com=denpa 宅内'書き方は ホスト名=表示名 のカンマ区切りで、載っていない名前で来たら denpa。
name と short_name に同じものが入ります(アイコンの下に出るのは short_name で、
端末によっては十数文字で切られる)。
同じ端末に2つ置けます。 名前が違えば別のサイトで、マニフェストの id も名前ごとに
分けてある(/?host=<名前>)ので、片方がもう片方の入れ直しと見なされません。
マニフェストは static/ ではなく /manifest.webmanifest のエンドポイントで組み立てます
(src/lib/server/manifest.ts)。認証は掛けていません。 ブラウザが資格情報を付けずに
取りに来るためで(auth.md)、出しているのは名前・色・アイコンの場所だけです。
開き直したら読み直します
Section titled “開き直したら読み直します”ホーム画面から開いたアプリは、閉じても捨てられません。 端末が凍らせて残し、次に
開くとそのまま見せるので、前に閉じたときの一覧がリロードするまで出ていました。
見えるようになったところで1回読み直します(+layout.svelte)。通知(SSE)は
凍っている間に切られて自分では戻らず、繋ぎ直しても間に起きたことは流れてこない
(溜めていない)ので、それだけでは足りません。繋ぎも同じところで張り直します(live-updates.svelte.ts)。
端末に保存して観る (オフライン)
Section titled “端末に保存して観る (オフライン)”端末に保存したものは denpa の中だけで観ます。 ブラウザの保存領域 (IndexedDB) に置き、 ファイルとして外へは出しません (持ち出すダウンロードが無い理由は library.md)。 作りは offline.md。
電波の無いときは /offline で観ます。 /watch/<id> はサーバが組む画面なので開けず、
ナビゲーションが繋がらないとサービスワーカーが /offline へ落とします。
/offline はナビに並べません。保存・進み具合 (行の3段目に割合、下端にバー)・視聴は
ふだんの一覧と観る画面でできます (オンラインの /watch は端末のコピーがあればそちらを使う)。
「サーバからも消す」予約 (outbox) を積むのは /offline の削除だけです。一覧の行の削除は
その場でサーバから消し (端末のコピーも片付ける)、詳細の「端末から消す」はサーバに触りません。