feat(stream)!: retire WebRTC, HLS-only, bump 0.9.4
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.
This commit is contained in:
parent
9176e877eb
commit
ca7de23a56
33 changed files with 207 additions and 2854 deletions
64
internal/engine/transcode_quality.go
Normal file
64
internal/engine/transcode_quality.go
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
package engine
|
||||
|
||||
// TranscodeRuntime carries the resolved ffmpeg/ffprobe paths + tunables so
|
||||
// each session can decide whether to passthrough or pipe through ffmpeg.
|
||||
type TranscodeRuntime struct {
|
||||
FFmpegPath string
|
||||
FFprobePath string
|
||||
HWAccel HWAccel
|
||||
Preset string
|
||||
VideoBitrate string
|
||||
AudioBitrate string
|
||||
MaxHeight int
|
||||
// Disabled forces passthrough for every file even when codecs are not
|
||||
// browser-friendly. Useful when the user explicitly turns transcoding
|
||||
// off in config.
|
||||
Disabled bool
|
||||
}
|
||||
|
||||
// qualityCap maps a session's Quality label to a (MaxHeight, VideoBitrate)
|
||||
// pair. An empty label or "original" returns zero-values, signalling "no
|
||||
// override" to the caller.
|
||||
type qualityCap struct {
|
||||
MaxHeight int
|
||||
VideoBitrate string // ffmpeg -b:v string, e.g. "3500k"
|
||||
}
|
||||
|
||||
func resolveQualityCap(label string) qualityCap {
|
||||
switch label {
|
||||
case "2160p":
|
||||
return qualityCap{MaxHeight: 2160, VideoBitrate: "25000k"}
|
||||
case "1080p":
|
||||
return qualityCap{MaxHeight: 1080, VideoBitrate: "6000k"}
|
||||
case "720p":
|
||||
return qualityCap{MaxHeight: 720, VideoBitrate: "3500k"}
|
||||
case "480p":
|
||||
return qualityCap{MaxHeight: 480, VideoBitrate: "1500k"}
|
||||
default:
|
||||
// "original", "auto", "" → defer to config.
|
||||
return qualityCap{}
|
||||
}
|
||||
}
|
||||
|
||||
// capForHeight returns the bitrate-cap pair appropriate for an effective
|
||||
// output height. Used after clamping outputHeight to the source's resolution:
|
||||
// asking ffmpeg for "2160p" bitrate (25 Mbps) on a 1080p source overshoots
|
||||
// the H.264 level we derived from the EFFECTIVE height (4.0, max 20 Mbps) and
|
||||
// makes libx264 refuse with "VBV bitrate > level limit". This helper picks
|
||||
// the bitrate that matches the level libx264 will actually accept.
|
||||
func capForHeight(height int) qualityCap {
|
||||
switch {
|
||||
case height <= 0:
|
||||
return qualityCap{}
|
||||
case height <= 480:
|
||||
return qualityCap{MaxHeight: 480, VideoBitrate: "1500k"}
|
||||
case height <= 720:
|
||||
return qualityCap{MaxHeight: 720, VideoBitrate: "3500k"}
|
||||
case height <= 1080:
|
||||
return qualityCap{MaxHeight: 1080, VideoBitrate: "6000k"}
|
||||
case height <= 1440:
|
||||
return qualityCap{MaxHeight: 1440, VideoBitrate: "12000k"}
|
||||
default:
|
||||
return qualityCap{MaxHeight: 2160, VideoBitrate: "25000k"}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue