mirror of
https://github.com/yattee/yattee.git
synced 2026-11-03 18:37:49 +00:00
Play direct media links without Yattee Server by probing the URL first
Debrid and CDN download links (TorBox, Real-Debrid, presigned S3) hide the file behind an opaque path, so the extension-based direct media check missed them and every one was sent to Yattee Server for yt-dlp extraction, failing outright when no server is configured. Add DirectMediaProbe: a HEAD request classifies the response by Content-Type and Content-Disposition, and when the type is generic or HEAD is refused, a ranged GET sniffs the first bytes for container signatures (Matroska/WebM, ISO BMFF, Ogg, FLAC, MP3, RIFF, FLV, ASF, MPEG-PS/TS, HLS and DASH manifests). Anything playable goes straight to mpv with the server-reported filename as the title; everything else falls back to extraction as before. The probe runs ahead of the Yattee Server path in ExternalVideoView, both OpenLinkSheet flows and the deep-link download path, and PlayerService rebuilds direct_media streams itself so replays from history no longer depend on a server either.
This commit is contained in:
@@ -2181,6 +2181,16 @@ final class PlayerService {
|
||||
let stream = try await createStreamForMediaSource(video: video, url: originalURL, extractor: extractor)
|
||||
return (video, [stream], [], [])
|
||||
}
|
||||
|
||||
// Direct media (a file mpv plays as-is): rebuild the stream from the
|
||||
// URL. A probe fills in the format/size for opaque CDN links; if it
|
||||
// fails (offline, expired token) still hand mpv the URL and let it
|
||||
// report the real error.
|
||||
if extractor == DirectMediaHelper.provider {
|
||||
let probe = await DirectMediaProbe.probe(originalURL)
|
||||
let stream = DirectMediaHelper.createStream(from: originalURL, probe: probe)
|
||||
return (video, [stream], [], [])
|
||||
}
|
||||
}
|
||||
|
||||
guard let instance = try await findInstance(for: video) else {
|
||||
|
||||
Reference in New Issue
Block a user