feat(stream): transcode debrid sources to HLS from a URL (hueco #2/2b)
Non-browser-native debrid content (mkv/HEVC/…) can now stream: ffmpeg reads the debrid HTTPS link directly (-i <url>) and transcodes to HLS, instead of 2a's raw direct-play which only works for mp4/m4v. - HLSSessionConfig gains SourceURL + CacheID; sourceRef() feeds ffprobe, ffmpeg -i, and subtitle extraction from one place. HTTP-resilience flags (-reconnect*, -rw_timeout) are added only for a URL source; a seek-restart re-opens the URL with a Range request (-ss before -i = input seek). - Segment cache keys by CacheID (the torrent info_hash) for URL sessions so re-plays hit cache despite the debrid URL changing each resolution (KeyForID, no filepath.Abs). - OnStreamSession: the 2a direct-play branch is now gated on PlayMethod != "hls"; a new branch handles DirectURL + PlayMethod=="hls" → HLS-from-URL. The local-file and both debrid HLS paths share a startHLSPlayback helper. - ExtractMediaInfo no longer masks a URL probe failure as "file not found" (surfaces ffprobe's real stderr, e.g. "Protocol not found" on a TLS-less ffmpeg build). - Bump 0.11.0 -> 0.12.0 as the HLS-from-URL floor the web gates on. Validated e2e against real AllDebrid: a cached HEVC x265 mkv transcodes (h264_nvenc) from the debrid URL and plays 1080p in Chrome via hls.js, subtitles extracted from the remote mkv.
This commit is contained in:
parent
b8d2b90370
commit
992e16ba05
6 changed files with 270 additions and 51 deletions
|
|
@ -162,6 +162,16 @@ func (c *HLSCache) KeyFor(sourcePath, quality string, audioIndex int) string {
|
|||
return hex.EncodeToString(h[:8]) // 16 hex chars — collision-safe enough for per-host cache
|
||||
}
|
||||
|
||||
// KeyForID derives a cache key from a caller-supplied stable identity instead
|
||||
// of a filesystem path (hueco #2 / 2b). Used for debrid HLS-from-URL sessions:
|
||||
// the debrid direct URL is re-resolved per play and would never cache-hit, so
|
||||
// we key by the torrent info_hash — the same content always maps to the same
|
||||
// key across plays. NOT run through filepath.Abs (an id/URL is not a path).
|
||||
func (c *HLSCache) KeyForID(id, quality string, audioIndex int) string {
|
||||
h := sha256.Sum256([]byte(fmt.Sprintf("%s|%s|%d", id, quality, audioIndex)))
|
||||
return hex.EncodeToString(h[:8])
|
||||
}
|
||||
|
||||
// DirFor returns the on-disk directory for a cache key. Caller is responsible
|
||||
// for creating it.
|
||||
func (c *HLSCache) DirFor(key string) string {
|
||||
|
|
@ -407,4 +417,3 @@ func (c *HLSCache) StartSweeper(ctx context.Context, interval time.Duration) {
|
|||
func (c *HLSCache) Invalidate(key string) error {
|
||||
return os.RemoveAll(c.DirFor(key))
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue