feat: play resolved Miruro HLS with external VTT and stable episode progress
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import Foundation
|
||||
import Darwin
|
||||
|
||||
@main
|
||||
struct PlayerCommandChecks {
|
||||
@@ -72,6 +73,64 @@ struct PlayerCommandChecks {
|
||||
require(try opened(["--", "--progress-file"]) == reportFlagFile,
|
||||
"escaped reporting option remains a filename")
|
||||
|
||||
let sourceFile = directory.appendingPathComponent("source with spaces.json")
|
||||
let sourceURL = "https://cdn.example/video/master.m3u8?token=secret%2Bvalue"
|
||||
var source: [String: Any] = [
|
||||
"version": 1, "url": sourceURL, "headers": ["Authorization": "Bearer secret "],
|
||||
"identity": ["provider": "miruro", "media_id": "opaque_A-1", "episode": 12],
|
||||
"subtitles": [["url": "https://cdn.example/sub.vtt?token=secret", "format": "vtt",
|
||||
"language": "en", "label": "English", "default": true, "headers": ["X-Token": "secret"]]]
|
||||
]
|
||||
func saveSource() throws {
|
||||
try JSONSerialization.data(withJSONObject: source).write(to: sourceFile)
|
||||
}
|
||||
try saveSource()
|
||||
let resolved = try ResolvedSource.load(from: sourceFile)
|
||||
require(resolved.url == sourceURL && resolved.headers == "Authorization: Bearer secret \r\n",
|
||||
"resolved URLs and header values remain byte-for-byte intact")
|
||||
require(resolved.identity == "miruro:opaque_A-1:12" && resolved.title == "Miruro episode 12",
|
||||
"stable identity excludes CDN tokens and omitted title has a useful fallback")
|
||||
require(resolved.subtitles.count == 1 && resolved.subtitles[0].isDefault &&
|
||||
resolved.subtitles[0].headers == "X-Token: secret\r\n", "subtitle metadata retains independent headers")
|
||||
guard case .launchSource(let delivered, let independent, let bypass, let output) =
|
||||
try PlayerCommand.parse(["--new-instance", "--no-config", "--source-file", sourceFile.lastPathComponent,
|
||||
"--progress-file", report.lastPathComponent], directory: directory) else {
|
||||
fatalError("FAIL: expected resolved source launch")
|
||||
}
|
||||
require(delivered == sourceFile && independent && bypass && output == report,
|
||||
"CLI forwards only an absolute source-file path with existing launch options")
|
||||
for arguments in [["--source-file", sourceFile.path], ["--new-instance", "--source-file"],
|
||||
["--new-instance", "--source-file", sourceFile.path, movie.path]] {
|
||||
do { _ = try PlayerCommand.parse(arguments, directory: directory); fatalError("FAIL: invalid source launch accepted") }
|
||||
catch {}
|
||||
}
|
||||
let original = source
|
||||
let invalidChanges: [[String: Any]] = [
|
||||
["version": 2], ["url": "https://user:secret@cdn.example/video"],
|
||||
["url": "file:///secret"], ["url": "https://cdn.example/video\nsecret"],
|
||||
["headers": ["X-Token": "secret\r\nInjected: yes"]], ["headers": ["X-Token": "secret\t"]],
|
||||
["headers": ["Bad Name": "secret"]], ["headers": ["X-Token": "one", "x-token": "two"]],
|
||||
["identity": ["provider": "miruro", "media_id": "bad:id", "episode": 1]],
|
||||
["identity": ["provider": "miruro", "media_id": "opaque", "episode": 0]],
|
||||
["identity": ["provider": "miruro", "media_id": "opaque", "episode": 1.5]],
|
||||
["subtitles": Array(repeating: (original["subtitles"] as! [[String: Any]])[0], count: 2)]
|
||||
]
|
||||
for change in invalidChanges {
|
||||
source = original.merging(change) { _, replacement in replacement }
|
||||
try saveSource()
|
||||
do { _ = try ResolvedSource.load(from: sourceFile); fatalError("FAIL: invalid source accepted") }
|
||||
catch { require(!error.localizedDescription.contains("secret"), "validation never reveals credentials") }
|
||||
}
|
||||
try Data(repeating: 32, count: 1_048_577).write(to: sourceFile)
|
||||
do { _ = try ResolvedSource.load(from: sourceFile); fatalError("FAIL: oversized source accepted") }
|
||||
catch {}
|
||||
let fifo = directory.appendingPathComponent("source.fifo")
|
||||
require(mkfifo(fifo.path, 0o600) == 0, "create unread FIFO source boundary")
|
||||
do {
|
||||
_ = try PlayerCommand.parse(["--new-instance", "--source-file", fifo.path], directory: directory)
|
||||
fatalError("FAIL: FIFO source accepted")
|
||||
} catch {}
|
||||
|
||||
for arguments in [["--url"], ["--url", canonical.absoluteString, movie.path], ["--"],
|
||||
[movie.path, movie.path], ["--unknown"], ["missing.mp4"], [directory.path],
|
||||
["file://remote-host/video.mp4"], ["https://example.com/video.mp4"],
|
||||
|
||||
Reference in New Issue
Block a user