Drops the custom WebRTC DataChannel pipeline + pion deps + WSS signaling
client + wire framing. Every in-browser playback now uses HLS over HTTP
from the daemon (Tailscale/LAN/UPnP). Browser P2P never re-enabled.
Wire renames (incompatible with web < 2026-05-26): agent.WebRTCSession
=> agent.StreamSession, SyncResponse.WebRTCSessions (JSON: webrtcSessions)
=> StreamSessions (JSON: streamSessions). MIN_AGENT_VERSION is bumped
to 0.9.4 on the web side so older agents see an upgrade card.
Also fixes the libx264 'VBV bitrate > level limit' abort by clamping
the encoder bitrate to the effective output height instead of the
requested label (carried over from the prior 0.9.3 unreleased work).
The seed_file vertical (mode=seed_file handler + engine.SeedFile) was
retired with the in-browser P2P player. [downloads.webrtc] config block
deleted; existing TOML files with the section still parse fine.
Introduces an HLS-over-HTTP path as Plan B for in-browser streaming. The
WebRTC + MSE pipeline keeps working untouched; the new path is selected
when the backend sets transport="hls" on a streaming session.
Daemon scope:
- engine/hls.go: HLSSession + HLSSessionRegistry. Spawns ffmpeg with
-f hls -hls_segment_type fmp4 + force_key_frames aligned with 4 s
segments. Pre-renders master + media playlists from the probe duration
so the browser knows the total timeline before any segment exists,
fixing seek/duration/pause/multi-track issues seen with the live fMP4
pipe.
- engine/probe.go: enumerate every audio + subtitle track instead of
collapsing to a single default audio track.
- engine/stream_server.go: route /hls/<id>/{master.m3u8,video/...,
subs/...} to the matching session. Emit a synthesised single-VTT
subtitle playlist per text track; bitmap subs (PGS/DVB) skip silently.
- cmd/daemon.go: branch on WebRTCSession.Transport == "hls" to register
an HLS session instead of running the legacy DataChannel pump.
- agent/types.go: WebRTCSession.Transport + AudioIndex fields.
Backend + web sides land in a follow-up commit.