feat: support Miruro provider tracks, proxies, and native embeds

This commit is contained in:
2026-10-22 19:04:30 +02:00
parent 80d9e705e5
commit 8df500da83
15 changed files with 1201 additions and 203 deletions
+5 -2
View File
@@ -135,16 +135,19 @@ struct ConfigurationChecks {
("video_provider = \"new-Host_2\"", "new-Host_2", ""),
("caption_provider = \"moon\"", "", "moon"),
("video_provider = \"sun\"\ncaption_provider = \"moon\"", "sun", "moon"),
("video_provider = \"sun:dub\"\ncaption_provider = \"bee:ssub\"", "sun:dub", "bee:ssub"),
("video_provider = \"new-Host_2:sub\"", "new-Host_2:sub", ""),
("video_provider = \"\"\ncaption_provider = \"\"", "", ""),
("video_provider = \"\(String(repeating: "a", count: 128))\"", String(repeating: "a", count: 128), "")
] {
try Data("[miruro]\n\(settings)\n".utf8).write(to: miruro)
try require(try PlayerConfiguration.load(from: miruro)
== PlayerConfiguration(miruroVideoProvider: video, miruroCaptionProvider: captions),
"partial Miruro settings preserve omitted defaults and accept runtime provider names")
"partial Miruro settings accept provider preferences and explicit provider:track choices")
}
for key in ["video_provider", "caption_provider"] {
for name in ["with space", " sun", "sun ", "é", "host.name", "host/name", String(repeating: "a", count: 129)] {
for name in ["with space", " sun", "sun ", "é", "host.name", "host/name", ":ssub", "sun:", "sun:auto",
"sun:DUB", "sun:ssub:sub", "sun:sub ", String(repeating: "a", count: 129)] {
try Data("[miruro]\n\(key) = \"\(name)\"\n".utf8).write(to: miruro)
try requireLoadError(at: miruro, "invalid Miruro provider")
}
+54 -5
View File
@@ -1,4 +1,5 @@
"""Local-only resolved HLS/VTT + native model smoke; no live requests."""
import base64
import http.server
import json
from pathlib import Path
@@ -6,7 +7,7 @@ import subprocess
import sys
import tempfile
import threading
from urllib.parse import urlsplit
from urllib.parse import parse_qs, urlsplit
binary = str(Path(sys.argv[1]).resolve())
fixtures = Path(sys.argv[2]).resolve()
@@ -17,7 +18,51 @@ class Handler(http.server.BaseHTTPRequestHandler):
def log_message(self, *_):
pass
def transport(self):
path = urlsplit(self.path).path
try:
encoded, suffix = path.lstrip("/").split("/", 1)
target, referer = encoded.split("~")
def decode(value):
raw = base64.urlsafe_b64decode(value + "=" * (-len(value) % 4))
return bytes(byte ^ [1, 2, 3][index % 3] for index, byte in enumerate(raw)).decode()
upstream = urlsplit(decode(target))
if not upstream.path.startswith("/transport-"):
return False
assert decode(referer) == "https://transport.example/"
assert self.headers.get("X-Secret") is None and self.headers.get("Referer") is None, "private headers leaked to proxy"
except (ValueError, UnicodeError):
return False
query = parse_qs(upstream.query)
if upstream.path.endswith(".m3u8"):
assert query == {"skip": ["fixture"]}, "provider query or token-removal rule lost"
port = self.server.server_port
if upstream.path == "/transport-master.m3u8":
def encode(value):
raw = value.encode()
return base64.urlsafe_b64encode(bytes(byte ^ [1, 2, 3][index % 3] for index, byte in enumerate(raw))).decode().rstrip("=")
nested = (f"http://localhost:{port}/" + encode(f"http://127.0.0.1:{port}/transport-variant.m3u8?token=private") +
"~" + encode("https://transport.example/") + "/pl.m3u8")
data = f"#EXTM3U\n#EXT-X-STREAM-INF:BANDWIDTH=1\n{nested}\n".encode()
elif upstream.path == "/transport-variant.m3u8":
data = (f'#EXTM3U\n#EXT-X-KEY:METHOD=AES-128,URI="http://2130706433:{port}/transport-private"\n'
'#EXTINF:1,\nhttps://foreign.invalid/transport-segment.bin\n#EXT-X-ENDLIST\n').encode()
elif upstream.path == "/transport-segment.bin":
assert upstream.hostname == "127.0.0.1", "segment origin rewrite lost"
data = bytes(range(256))
else:
errors.append("unexpected transport request")
self.send_error(403)
return True
self.send_response(200)
self.send_header("Content-Length", str(len(data)))
self.end_headers()
self.wfile.write(data)
return True
def do_GET(self):
if self.transport():
return
path = urlsplit(self.path).path
seen.append(path)
alternate = path.startswith("/alternate/")
@@ -30,13 +75,17 @@ class Handler(http.server.BaseHTTPRequestHandler):
self.send_error(403)
return
if path == "/master.m3u8":
if urlsplit(self.path).query != "token=fixture":
errors.append("master token lost")
query = parse_qs(urlsplit(self.path).query)
if query.get("token") != ["fixture"] or (alternate and query.get("rewrite") != ["1"]):
errors.append("master token or provider query lost")
data = b'#EXTM3U\n#EXT-X-STREAM-INF:BANDWIDTH=500000\nvariant.m3u8?token=variant\n'
elif path == "/variant.m3u8":
if urlsplit(self.path).query != "token=variant":
errors.append("variant token lost")
query = parse_qs(urlsplit(self.path).query)
if query.get("token") != ["variant"] or (alternate and query.get("rewrite") != ["1"]):
errors.append("variant token or provider query lost")
data = (fixtures / "resolved-vod.m3u8").read_bytes()
if alternate:
data = data.replace(b"resolved-vod-", b"https://invalid.example/alternate/resolved-vod-")
elif path == "/english.jpeg":
data = (b'WEBVTT\n\n00:00.000 --> 00:10.000\nAlternate English cue\n' if alternate else
b'WEBVTT\n\n00:00.000 --> 00:02.000\nFirst English cue\n\n00:02.000 --> 00:04.000\nSecond English cue\n')
+77 -13
View File
@@ -32,12 +32,13 @@ struct ResolvedPlaybackCheck {
NSApp.setActivationPolicy(.prohibited)
let input = CommandLine.arguments[1]
let file = URL(fileURLWithPath: input)
let preference = CommandLine.arguments.first(where: { $0.hasPrefix("--provider=") }).map { String($0.dropFirst(11)) } ?? ""
let source: ResolvedSource
if input.hasPrefix("https://") {
guard case .miruro(let mediaID, let episode) = try StreamURL.parse(input) else {
fatalError("FAIL: URL smoke requires a Miruro episode")
}
source = try await MiruroResolver.resolve(mediaID: mediaID, episode: episode).select().source
source = try await MiruroResolver.resolve(mediaID: mediaID, episode: episode).select(videoProvider: preference).source
} else {
source = try ResolvedSource.load(from: file)
}
@@ -49,7 +50,8 @@ struct ResolvedPlaybackCheck {
let defaults = UserDefaults(suiteName: suite)!
defer { defaults.removePersistentDomain(forName: suite) }
let clock = Clock()
let model = PlayerModel(defaults: defaults, progressFile: CommandLine.arguments.count > 2 ? CommandLine.arguments[2] : nil,
let report = CommandLine.arguments.count > 2 && !CommandLine.arguments[2].hasPrefix("--") ? CommandLine.arguments[2] : nil
let model = PlayerModel(defaults: defaults, configuration: .init(miruroVideoProvider: preference), progressFile: report,
miruroMetadataResolver: { id, episode in
if input.hasPrefix("https://") {
return try await MiruroMetadataResolver.resolve(mediaID: id, episode: episode)
@@ -85,7 +87,8 @@ struct ResolvedPlaybackCheck {
fatalError("FAIL: smoke requires a default subtitle")
}
let track = source.subtitles[index]
let document = try await WebVTTDocument.load(url: track.url, headers: track.headers)
let preparedTrack = try await MiruroTransport.subtitle(track)
let document = try await WebVTTDocument.load(url: preparedTrack.url, headers: preparedTrack.headers)
let playableCues = document.cues.filter { !$0.text.isEmpty && $0.start + 0.1 < model.state.duration }
require(playableCues.count >= 2, "smoke requires two visible subtitle cues")
let target = playableCues[1].start + min(0.1, (playableCues[1].end - playableCues[1].start) / 2)
@@ -105,8 +108,10 @@ struct ResolvedPlaybackCheck {
print("PASS: default VTT selected, forward/backward seek and acknowledged cue timing")
if !input.hasPrefix("https://") { try await segmentSkips(model, clock: clock, file: file) }
if !input.hasPrefix("https://") {
try await transportProtocol(source: source)
model.shutdown()
try await providerLifecycle(source: source)
try await dubOnlySelection(source: source)
try await queueMetadataLifecycle(source: source)
try await streamQueueLifecycle(source: source)
try await enqueueLifecycle(source: source)
@@ -114,7 +119,35 @@ struct ResolvedPlaybackCheck {
}
}
static func providerSources(_ source: ResolvedSource, alternate: Bool = false) throws -> MiruroSources {
static func transportProtocol(source: ResolvedSource) async throws {
let original = URLComponents(string: source.url)!
let base = "\(original.scheme!)://\(original.host!):\(original.port!)"
let deployment = MiruroProxyDeployment(base: URL(string: base.replacingOccurrences(of: "127.0.0.1", with: "localhost") + "/")!, key: [1, 2, 3])
var input = ResolvedSource(url: base + "/transport-master.m3u8?token=private", headers:
"Referer: https://transport.example/\r\nX-Secret: private\r\n",
identity: source.identity, title: source.title, subtitles: [])
input.requirements = .init(proxy: .init(rotate: false, segments: true),
segmentOrigin: base, playlistQuery: ["skip": "fixture"])
let prepared = try await MiruroTransport.prepare(input, deployment: deployment)
let (master, _) = try await URLSession.shared.data(from: URL(string: prepared.url)!)
let nested = String(data: master, encoding: .utf8)!.components(separatedBy: .newlines)
.first { $0.hasPrefix("http://") }!
let (variant, _) = try await URLSession.shared.data(from: URL(string: nested)!)
let lines = String(data: variant, encoding: .utf8)!.components(separatedBy: .newlines)
let segment = lines.first { $0.hasPrefix("http://") }!
let (body, response) = try await URLSession.shared.data(from: URL(string: segment)!)
require((response as? HTTPURLResponse)?.statusCode == 200 && body == Data((0..<256).map(UInt8.init)),
"proxied nested playlists decode once; query and segment-origin rules fetch real resource bytes")
let keyLine = lines.first { $0.hasPrefix("#EXT-X-KEY:") }!
let key = keyLine.components(separatedBy: "\"")[1]
let (_, blocked) = try await URLSession.shared.data(from: URL(string: key)!)
require((blocked as? HTTPURLResponse)?.statusCode == 502,
"manifest key cannot make the relay fetch a foreign loopback destination")
withExtendedLifetime(prepared) {}
print("PASS: proxy codec, already-proxied nested HLS, query/origin rules, credential isolation and private-destination rejection")
}
static func providerSources(_ source: ResolvedSource, alternate: Bool = false, track: String = "ssub") throws -> MiruroSources {
func headers(_ text: String) -> [String: String] {
Dictionary(uniqueKeysWithValues: text.components(separatedBy: "\r\n").filter { !$0.isEmpty }.map {
let parts = $0.split(separator: ":", maxSplits: 1)
@@ -140,11 +173,15 @@ struct ResolvedPlaybackCheck {
header: ["X-Resource": "alternate-private"],
subtitles: [["file": source.subtitles[0].url.replacingOccurrences(of: "/english.jpeg", with: "/alternate/english.jpeg"),
"format": "vtt", "language": "en", "label": "Alternate English", "default": true]]))
config["alternate"] = ["player": "native", "proxy": false]
let origin = URLComponents(string: source.url)!
let segmentOrigin = "\(origin.scheme!)://\(origin.host!):\(origin.port!)"
config["alternate"] = ["player": "native", "proxy": false,
"hls": ["query": ["enabled": true, "params": ["rewrite": "1"]],
"segments": ["enabled": true, "origin": segmentOrigin]]]
}
return try MiruroResolver.decode(JSONSerialization.data(withJSONObject: [
"episodeNumber": 1, "providerOrder": ["sun", "captions", "alternate"], "config": config,
"tracks": [["track": "ssub", "providers": providers]]
"tracks": [["track": track, "providers": providers]]
]), mediaID: "fixture-ID", episode: 1)
}
@@ -171,23 +208,29 @@ struct ResolvedPlaybackCheck {
try await until("configured missing host falls back with independent captions", model: model) {
model.canChangeMiruroProvider && model.state.position > 0.2 && !model.subtitleText.isEmpty
}
require(model.selectedMiruroVideoProvider == "sun" && model.selectedMiruroCaptionProvider == "captions",
require(model.selectedMiruroVideoProvider == "sun:ssub" && model.selectedMiruroCaptionProvider == "captions:ssub",
"startup preferences select independent providers with host fallback")
require(model.setPlayback(playing: false), "pause before provider switches")
try await until("provider pause acknowledged", model: model) { model.state.status == PLAYER_PAUSED }
let position = model.state.position
let revision = model.state.revision
model.setMiruroCaptionProvider("alternate")
model.setMiruroCaptionProvider("alternate:ssub")
try await until("alternate provider's own VTT is loaded", model: model) { model.subtitleText == "Alternate English cue" }
require(model.state.revision == revision && model.state.position == position && requests == 1,
"caption selection does not reopen video, seek or refetch sources")
model.setMiruroVideoProvider("alternate")
model.setMiruroVideoProvider("alternate:ssub")
try await until("alternate host preserves paused position", model: model) {
model.canChangeMiruroProvider && model.state.status == PLAYER_PAUSED &&
model.state.revision != revision && abs(model.state.position - position) < 0.2
}
require(model.selectedMiruroVideoProvider == "alternate" && model.selectedMiruroCaptionProvider == "alternate",
require(model.selectedMiruroVideoProvider == "alternate:ssub" && model.selectedMiruroCaptionProvider == "alternate:ssub",
"host and captions remain independently selected")
let preparedRevision = model.state.revision
model.setMiruroCaptionProvider("captions:ssub")
try await until("caption change retains prepared video transport", model: model) {
!model.subtitleText.isEmpty && model.selectedMiruroCaptionProvider == "captions:ssub"
}
require(model.state.revision == preparedRevision, "prepared video is not reopened for captions")
model.selectSubtitle(nil)
model.setMiruroCaptionProvider("")
require(model.selectedSubtitle == nil && model.subtitleText.isEmpty, "caption provider respects explicit Off")
@@ -196,15 +239,15 @@ struct ResolvedPlaybackCheck {
model.setMiruroVideoProvider("")
try await until("automatic host returns to Sun and preserves playing intent", model: model) {
model.canChangeMiruroProvider && model.state.status == PLAYER_PLAYING &&
model.selectedMiruroVideoProvider == "sun"
model.selectedMiruroVideoProvider == "sun:ssub"
}
require(model.selectedSubtitle == nil, "host changes preserve explicit subtitle Off")
model.setMiruroVideoProvider("alternate")
model.setMiruroVideoProvider("alternate:ssub")
let deadline = ContinuousClock.now.advanced(by: .seconds(5))
while (model.resolvingStream || model.state.status != PLAYER_PLAYING), ContinuousClock.now < deadline {
try await Task.sleep(for: .milliseconds(10))
}
require(model.commandError != nil && model.selectedMiruroVideoProvider == "sun" &&
require(model.commandError != nil && model.selectedMiruroVideoProvider == "sun:ssub" &&
model.state.status == PLAYER_PLAYING && model.canChangeMiruroProvider,
"failed host fetch retains previous source and resumes playback")
model.setMiruroVideoProvider("")
@@ -219,6 +262,27 @@ struct ResolvedPlaybackCheck {
print("PASS: provider config fallback, independent caption headers, in-place captions, paused/playing host switches and failure retention")
}
static func dubOnlySelection(source: ResolvedSource) async throws {
let providers = try providerSources(source, track: "dub")
let suite = "terebi.dub-check." + UUID().uuidString
let defaults = UserDefaults(suiteName: suite)!
defer { defaults.removePersistentDomain(forName: suite) }
let model = PlayerModel(defaults: defaults, miruroResolver: { _, _ in providers },
miruroMetadataResolver: { _, _ in MiruroMetadata(title: nil, intervals: []) })
defer { model.shutdown() }
model.openStream("https://barelystarted.miruro.tv/watch/fixture-ID/episode?ep=1")
let deadline = ContinuousClock.now.advanced(by: .seconds(5))
while model.resolvingStream, ContinuousClock.now < deadline { try await Task.sleep(for: .milliseconds(10)) }
require(model.commandError != nil && model.miruroVideoProviders.contains("sun:dub") && model.canChangeMiruroProvider,
"dub-only episode exposes explicit choices without automatic language fallback")
model.setMiruroVideoProvider("sun:dub")
try await until("explicit dub-only choice decodes", model: model) {
model.state.has_video && model.state.position > 0.2 && model.selectedMiruroVideoProvider == "sun:dub"
}
require(model.selectedMiruroCaptionProvider == "captions:dub", "automatic captions follow explicit dub track")
print("PASS: dub-only choices remain accessible and explicit selection plays")
}
static func queueMetadataLifecycle(source: ResolvedSource) async throws {
let suite = "terebi.queue-metadata-check." + UUID().uuidString
let defaults = UserDefaults(suiteName: suite)!
+121 -53
View File
@@ -94,90 +94,158 @@ struct StreamResolverChecks {
try require(source.subtitles.count == 2 && source.subtitles[0].isDefault, "only external VTT retained with default")
try require(source.subtitles[0].url.hasSuffix(".jpeg") && source.subtitles[1].label == "Spanish (Latin America)", "subtitle format and labels independent of file extension")
try require(source.subtitles.allSatisfy { $0.headers == source.headers }, "verified Sun subtitle headers retained")
let defaults = try MiruroResolver.decode(Data(fixture.utf8), mediaID: mediaID, episode: 1)
let defaultSelection = try defaults.select()
try require(defaults.videoProviders == ["sun"] && defaults.captionProviders == ["sun"], "menus contain usable native providers")
try require(defaultSelection.videoProvider == "sun" && defaultSelection.captionProvider == "sun", "existing Sun defaults")
let native: [String: Any] = ["player": "native", "proxy": false]
var captionOnly = provider("bun")
captionOnly["servers"] = [["headers": ["Referer": "https://bun.example/"],
"streams": [], "embed": ["url": "https://bun.example/embed"]]]
var missingVideo = provider("captions")
missingVideo["servers"] = [["headers": ["Origin": "https://captions.example"]]]
let independentCatalog = try catalog([
"episodeNumber": 1,
"config": ["sun": native, "bun": ["player": "iframe", "proxy": false]],
"tracks": [["track": "ssub", "providers": [provider("sun"), captionOnly, missingVideo]]]
])
let independentCaptions = try independentCatalog.select(captionProvider: "bun:ssub")
try require(independentCaptions.source.subtitles.first?.url == "https://bun.example/english.vtt" &&
independentCaptions.source.subtitles.first?.headers == "Referer: https://bun.example/\r\n",
"iframe-only provider captions are discovered independently of video eligibility")
let unconfiguredCaptions = try independentCatalog.select(captionProvider: "captions")
try require(unconfiguredCaptions.captionProvider == "captions:ssub" &&
unconfiguredCaptions.source.subtitles.first?.headers == "Origin: https://captions.example\r\n",
"captions without config or video streams retain their own server headers")
let embedded = try independentCatalog.select(videoProvider: "bun:ssub")
try require(independentCatalog.videoProviders == ["sun:ssub", "bun:ssub"] &&
independentCatalog.captionProviders == ["sun:ssub", "bun:ssub", "captions:ssub"] &&
embedded.source.url == "https://bun.example/embed" && embedded.source.requirements.embed,
"iframe choices retain the embed URL and require asynchronous native preparation")
let captionsOnly = try catalog([
"episodeNumber": 1, "tracks": [["track": "ssub", "providers": [missingVideo]]]
])
try require(captionsOnly.videoProviders.isEmpty && captionsOnly.captionProviders == ["captions:ssub"],
"caption discovery does not require any video candidate or config table")
try reject("caption-only catalog playback") { _ = try captionsOnly.select() }
var document: [String: Any] = [
"episodeNumber": 1, "providerOrder": ["cloud", "river", "sun", "cloud", "missing"],
"config": ["sun": native, "river": native, "cloud": native],
"tracks": [["track": "ssub", "providers": [provider("river"), provider("sun"), provider("cloud")]]]
]
let choices = try catalog(document)
try require(choices.videoProviders == ["cloud", "river", "sun"] &&
choices.captionProviders == ["cloud", "river", "sun"], "runtime names follow deduplicated provider order")
try require(choices.videoProviders == ["cloud:ssub", "river:ssub", "sun:ssub"] &&
choices.captionProviders == ["cloud:ssub", "river:ssub", "sun:ssub"],
"choices expose provider and track in deduplicated runtime provider order")
let automatic = try choices.select()
try require(automatic.videoProvider == "sun" && automatic.captionProvider == "sun", "Auto prefers usable Sun")
let independent = try choices.select(videoProvider: "river", captionProvider: "cloud")
try require(independent.videoProvider == "river" && independent.captionProvider == "cloud", "explicit independent choices")
try require(independent.source.url == "https://river.example/master.m3u8" &&
independent.source.headers == "Referer: https://river.example/\r\n", "selected host retains its URL and headers")
try require(independent.source.subtitles.first?.url == "https://cloud.example/english.vtt" &&
independent.source.subtitles.first?.headers == "Referer: https://cloud.example/\r\n", "captions retain their own provider headers")
let sameHost = try choices.select(videoProvider: "river")
try require(sameHost.captionProvider == "river", "Auto captions prefer chosen video provider")
try require(automatic.videoProvider == "sun:ssub" && automatic.captionProvider == "sun:ssub",
"Auto prefers usable Japanese Sun")
let independent = try choices.select(videoProvider: "river", captionProvider: "cloud:ssub")
try require(independent.videoProvider == "river:ssub" && independent.captionProvider == "cloud:ssub" &&
independent.source.url == "https://river.example/master.m3u8" &&
independent.source.headers == "Referer: https://river.example/\r\n" &&
independent.source.subtitles.first?.headers == "Referer: https://cloud.example/\r\n",
"bare provider preference and exact caption choice retain independent URLs and headers")
let absent = try choices.select(videoProvider: "absent", captionProvider: "unsupported")
let empty = try choices.select(videoProvider: "", captionProvider: "")
try require(absent.videoProvider == "sun" && absent.captionProvider == "sun" &&
empty.videoProvider == "sun" && empty.captionProvider == "sun", "absent and empty preferences fall back to Auto")
document["tracks"] = [["track": "ssub", "providers": [provider("river"), provider("cloud")]]]
let withoutSun = try catalog(document).select()
try require(withoutSun.videoProvider == "cloud" && withoutSun.captionProvider == "cloud", "provider order applies without Sun")
document["providerOrder"] = []
let returnedOrder = try catalog(document).select()
try require(returnedOrder.videoProvider == "river", "returned order is deterministic when no provider order applies")
try require(absent.videoProvider == "sun:ssub" && absent.captionProvider == "sun:ssub" &&
empty.videoProvider == "sun:ssub" && empty.captionProvider == "sun:ssub",
"unavailable and empty preferences fall back to Japanese Auto")
document["tracks"] = [["track": "ssub", "providers": [provider("river", captions: false), provider("cloud")]]]
let withoutSun = try catalog(document).select()
try require(withoutSun.videoProvider == "cloud:ssub" && withoutSun.captionProvider == "cloud:ssub",
"provider order applies without Sun")
document["providerOrder"] = []
let otherCaptions = try catalog(document).select()
try require(otherCaptions.videoProvider == "river" && otherCaptions.captionProvider == "cloud", "Auto captions fall back independently")
try require(otherCaptions.videoProvider == "river:ssub" && otherCaptions.captionProvider == "cloud:ssub",
"response order is retained and captions fall back independently")
document["tracks"] = [["track": "sub", "providers": [provider("river", captions: false)]]]
let noCaptions = try catalog(document)
let bare = try noCaptions.select(captionProvider: "cloud")
try require(noCaptions.captionProviders.isEmpty && bare.captionProvider == nil && bare.source.subtitles.isEmpty, "Japanese sub without captions remains playable")
var soft = provider("river")
soft["servers"] = [["streams": [["url": "https://soft.example/master.m3u8", "format": "m3u8"]]]]
document["tracks"] = [["track": "sub", "providers": [provider("river")]],
["track": "ssub", "providers": [soft]],
["track": "dub", "providers": [provider("cloud")]]]
let preferredVariant = try catalog(document)
let preferredSelection = try preferredVariant.select()
try require(preferredVariant.videoProviders == ["river"] &&
preferredSelection.source.url == "https://soft.example/master.m3u8", "ssub wins per provider without dub fallback")
var mixedConfigs: [String: Any] = ["river": native, "proxy": ["player": "native", "proxy": ["segments": true]],
"iframe": ["player": "iframe", "proxy": false], "broken": ["player": 42], "bad name": native]
mixedConfigs["rewrite"] = ["player": "native", "proxy": false, "hls": ["query": ["enabled": true]]]
document["config"] = mixedConfigs
try require(noCaptions.captionProviders.isEmpty && bare.captionProvider == nil && bare.source.subtitles.isEmpty,
"Japanese sub without captions remains playable")
document["tracks"] = [
["track": "ssub", "providers": [provider("river")]],
["track": "dub", "providers": [provider("river"), provider("sun")]],
["track": "sub", "providers": [provider("river")]]]
document["config"] = ["sun": native, "river": ["player": "native", "proxy": false,
"variantOrder": ["dub", "sub", "sub", "ssub"]]]
let variants = try catalog(document)
let preferredVariant = try variants.select(videoProvider: "river")
let dubbed = try variants.select(videoProvider: "river:dub", captionProvider: "river:dub")
try require(variants.videoProviders == ["river:dub", "river:sub", "river:ssub", "sun:dub"] &&
preferredVariant.videoProvider == "river:sub" && preferredVariant.captionProvider == "river:sub" &&
dubbed.videoProvider == "river:dub" && dubbed.captionProvider == "river:dub",
"all tracks remain selectable; bare provider uses variantOrder without implicit dub")
document["tracks"] = [["track": "dub", "providers": [provider("sun")]]]
let dubOnly = try catalog(document)
try reject("automatic dub fallback") { _ = try dubOnly.select() }
try reject("bare provider dub fallback") { _ = try dubOnly.select(videoProvider: "sun") }
let explicitDub = try dubOnly.select(videoProvider: "sun:dub")
try require(explicitDub.videoProvider == "sun:dub",
"dub-only catalog remains available for an explicit track choice")
let processed: [String: Any] = ["player": "native", "proxy": ["rotate": true, "segments": true],
"hls": ["segments": ["enabled": true, "origin": "https://segments.example"],
"query": ["enabled": true, "params": ["skip": "opaque", "token": "secret"]]]]
document["config"] = ["river": native, "bee": processed]
document["tracks"] = [["track": "ssub", "providers": [provider("river"), provider("bee")]]]
let processing = try catalog(document).select(videoProvider: "bee", captionProvider: "bee")
try require(processing.source.url == "https://bee.example/master.m3u8" &&
processing.source.requirements.proxy?.rotate == true &&
processing.source.requirements.proxy?.segments == true &&
processing.source.requirements.segmentOrigin == "https://segments.example" &&
processing.source.requirements.playlistQuery == ["skip": "opaque", "token": "secret"] &&
processing.source.subtitles.first?.proxy?.segments == true &&
!processing.source.requirements.embed,
"selection preserves native proxy/HLS requirements and caption proxy independently")
let parent = provider("bee")
var embeddedCaptions = provider("bun")
embeddedCaptions["subtitles"] = parent["subtitles"]
embeddedCaptions["servers"] = [["streams": [], "embed": ["url": "https://megaplay.buzz/videojs/stream/example"]]]
document["config"] = ["river": native, "bee": processed,
"bun": ["player": "iframe", "proxy": false, "parent": "bee"]]
document["tracks"] = [["track": "ssub", "providers": [provider("river"), parent, embeddedCaptions]]]
let sharedCaptions = try catalog(document).select(captionProvider: "bun:ssub")
try require(sharedCaptions.captionProvider == "bun:ssub" &&
sharedCaptions.source.subtitles.first?.headers == "Referer: https://bee.example/\r\n" &&
sharedCaptions.source.subtitles.first?.proxy?.segments == true,
"identical iframe caption resources use their parent's known request transport")
embeddedCaptions["subtitles"] = provider("bun")["subtitles"]
document["tracks"] = [["track": "ssub", "providers": [provider("river"), parent, embeddedCaptions]]]
let distinctCaptions = try catalog(document).select(captionProvider: "bun:ssub")
try require(distinctCaptions.source.subtitles.first?.proxy == nil &&
distinctCaptions.source.subtitles.first?.headers.isEmpty == true,
"parent credentials and routing never propagate to different caption resources")
var unsafeHLS = processed
unsafeHLS["hls"] = ["segments": ["enabled": true, "origin": "file:///secret"]]
document["config"] = ["river": native, "bee": unsafeHLS]
let captionDespiteHLS = try catalog(document).select(videoProvider: "river", captionProvider: "bee:ssub")
try require(captionDespiteHLS.captionProvider == "bee:ssub" &&
captionDespiteHLS.source.subtitles.first?.proxy?.segments == true,
"unsupported video processing does not hide valid independent captions")
var resilient = provider("river")
resilient["servers"] = [
["streams": [["url": "https://embed.example/master.m3u8", "format": "hls"]], "embed": ["url": "https://embed.example/"]],
["streams": [42, ["url": "file:///secret", "format": "hls"],
["url": "https://river.example/master.m3u8", "format": "application/vnd.apple.mpegurl"]] as [Any],
"headers": ["Referer": "https://river.example/"]]] as [[String: Any]]
"headers": ["Referer": "https://river.example/"]]]
document["config"] = ["river": native, "broken": ["player": 42], "bad name": native]
document["tracks"] = [["track": "ssub", "providers": [
42, ["provider": "broken", "servers": "invalid"], provider("proxy"), provider("iframe"),
provider("rewrite"), provider("bad name"), resilient] as [Any]]]
42, ["provider": "broken", "servers": "invalid"], provider("bad name"), resilient] as [Any]]]
let resilientSources = try catalog(document)
let resilientChoice = try resilientSources.select(videoProvider: "proxy", captionProvider: "iframe")
try require(resilientSources.videoProviders == ["river"] && resilientSources.captionProviders == ["river"] &&
resilientChoice.source.url == "https://river.example/master.m3u8", "malformed and unsupported entries do not poison usable alternatives")
try require(resilientSources.videoProviders == ["river:ssub"] &&
resilientSources.captionProviders == ["river:ssub"],
"malformed neighboring entries do not poison usable provider tracks")
for (old, replacement) in [
("https://vault.example/english.jpeg", "https://user:secret@vault.example/english.jpeg"),
("\"default\": false", "\"default\": true")
] {
let safeVideo = try project(fixture.replacingOccurrences(of: old, with: replacement))
try require(safeVideo.url == source.url && safeVideo.subtitles.isEmpty, "unsafe caption sets are excluded without losing safe video")
try require(safeVideo.url == source.url && safeVideo.subtitles.isEmpty,
"unsafe caption sets are excluded without losing safe video")
}
let renewed = try project(fixture.replacingOccurrences(of: "token=secret", with: "token=renewed"))
try require(renewed.identity == source.identity && renewed.url != source.url, "token rotation does not change stable identity")
try require(renewed.identity == source.identity && renewed.url != source.url,
"token rotation does not change stable identity")
for (old, replacement) in [
("\"episodeNumber\": 1", "\"episodeNumber\": 49"),
("\"proxy\": false", "\"proxy\": true"),
("\"enabled\": false", "\"enabled\": true"),
("\"player\": \"native\"", "\"player\": \"iframe\""),
("\"track\": \"ssub\"", "\"track\": \"dub\""),
("\"proxy\": false", "\"proxy\": {\"segments\": true}"),
("\"format\": \"hls\"", "\"format\": \"mp4\""),
("\"embed\": null", "\"embed\": {\"url\": \"https://embed.example/secret\"}"),
("https://vault.example/master.m3u8?token=secret", "file:///secret"),
("\"embed\": null", "\"embed\": false"),
("https://ultracloud.cc/\"", "https://ultracloud.cc/\\r\\nX-Injected: secret\""),
@@ -204,7 +272,7 @@ struct StreamResolverChecks {
_ = try await cancelled.value
throw Failure(message: "Cancelled resolution was accepted")
} catch is CancellationError {}
print("PASS: streaming URL security, runtime native providers, independent captions, bounded responses and cancellation")
print("PASS: streaming URL security, provider/track choices, proxy/HLS requirements, independent captions, bounded responses and cancellation")
}
static func main() async {