import AppKit import TerebiConfiguration @MainActor private final class FixedQualityClock { var now = 1000.0 } @main @MainActor struct AutomaticQualityPlaybackChecks { static func require(_ condition: @autoclosure () -> Bool, _ message: String) { if !condition() { FileHandle.standardError.write(Data(("FAIL: " + message + "\n").utf8)) exit(1) } } // Only the infrastructure watchdog uses elapsed time. Adaptation uses an injected clock; // playback readiness and network stalls are observable media events, not sleeps. static func until(_ model: PlayerModel, _ message: String, _ condition: () -> Bool) { let deadline = ContinuousClock.now.advanced(by: .seconds(20)) while !condition(), ContinuousClock.now < deadline { RunLoop.main.run(until: Date(timeIntervalSinceNow: 0.01)) } require(condition(), message + " (height=\(model.youtubeHeight ?? 0), status=\(model.state.status), error=\(model.errorText ?? "none"))") } static func polled(_ model: PlayerModel) { let revision = model.state.revision until(model, "native model processes a fresh playback snapshot") { model.state.revision != revision } } static func main() { _ = NSApplication.shared NSApp.setActivationPolicy(.prohibited) let suite = "terebi.automatic-quality-playback-check.\(UUID().uuidString)" let defaults = UserDefaults(suiteName: suite)! defer { defaults.removePersistentDomain(forName: suite) } let clock = FixedQualityClock() let model = PlayerModel(defaults: defaults, qualityClock: { clock.now }) defer { model.shutdown() } model.setVolume(0) // Control only the external extractor; media decoding and all model transitions stay real. guard let controlPath = ProcessInfo.processInfo.environment["TEREBI_QUALITY_CONTROL"] else { require(false, "isolated extraction controls are available") return } let control = URL(fileURLWithPath: controlPath, isDirectory: true) func mark(_ name: String) { require(FileManager.default.createFile(atPath: control.appendingPathComponent(name).path, contents: Data()), "publish extraction control " + name) } func marked(_ name: String) -> Bool { FileManager.default.fileExists(atPath: control.appendingPathComponent(name).path) } require(!model.automaticYouTubeQuality, "automatic quality is opt-in") let window = NSWindow(contentRect: NSRect(x: -10_000, y: -10_000, width: 640, height: 360), styleMask: [.titled, .closable, .miniaturizable, .resizable], backing: .buffered, defer: false) window.isReleasedWhenClosed = false defer { window.close() } model.attachWindow(window) let normalFrame = window.frame let compactKey = try! KeyChord("p") mark("gate-open") model.openYouTube("https://www.youtube.com/watch?v=aqz-KE-bpKQ") until(model, "initial YouTube resolution reaches the controlled extraction gate") { model.resolvingYouTube && marked("entered-open") } model.handleKey(compactKey) require(model.isCompact, "compact shortcut enters while the YouTube URL is unresolved") until(model, "compact mode remains usable across empty playback polls while resolving") { model.isCompact && !model.compactWindow.isTransitioning } require(window.level == .floating && window.frame.width < normalFrame.width, "unresolved video has a usable compact window") model.handleKey(compactKey) until(model, "compact shortcut restores while YouTube resolution is still pending") { !model.isCompact && !model.compactWindow.isTransitioning } require(window.frame == normalFrame && model.resolvingYouTube, "resolution continues while restoring the original normal window") require(model.perform(.enterCompact), "compact control action is available during resolution") mark("release-open") try! FileManager.default.removeItem(at: control.appendingPathComponent("gate-open")) until(model, "default selects real 1080p and runs out of the gated network prefix") { model.youtubeHeight == 1080 && model.canTogglePlayback && model.state.status == PLAYER_PLAYING && model.state.position > 0.5 && model.state.buffering } require(model.isCompact, "loading completion preserves the requested compact mode") until(model, "decoded metadata updates compact geometry") { !model.compactWindow.isTransitioning && abs(window.frame.width / window.frame.height - model.state.video_aspect_ratio) < 0.01 } model.handleKey(compactKey) until(model, "compact shortcut restores during network buffering") { !model.isCompact && !model.compactWindow.isTransitioning } model.handleKey(compactKey) until(model, "compact shortcut re-enters during network buffering") { model.isCompact && !model.compactWindow.isTransitioning } clock.now = 2000 polled(model) require(model.youtubeHeight == 1080 && !model.resolvingYouTube, "disabled automatic quality leaves a stalled manual/default stream alone") model.setAutomaticYouTubeQuality(true) polled(model) let position = model.state.position clock.now = 2003 until(model, "persistent stall automatically reopens actual 720p media") { model.youtubeHeight == 720 && model.canTogglePlayback && model.state.status == PLAYER_PLAYING && !model.state.seek_pending && (model.bufferedRange.map { $0.upperBound - model.state.position >= 20 } ?? false) } require(model.state.position >= position && model.state.position < position + 3, "automatic quality reopening preserves current playback progress") polled(model) clock.now = 2063 until(model, "sustained health automatically restores actual 1080p media") { model.youtubeHeight == 1080 && model.canTogglePlayback && model.state.status == PLAYER_PLAYING && !model.state.seek_pending } model.setYouTubeQuality(model.youtubeHeight) require(!model.automaticYouTubeQuality && !model.isBusy && model.state.status == PLAYER_PLAYING, "reselecting the current manual resolution disables auto without disrupting playback") model.setAutomaticYouTubeQuality(true) let reopened = PlayerModel(defaults: defaults, qualityClock: { clock.now }) require(!reopened.automaticYouTubeQuality, "session opt-in does not survive player restart") reopened.shutdown() model.setYouTubeQuality(nil) require(!model.automaticYouTubeQuality && model.youtubeQuality == nil, "default quality is also a manual override") let manual = PlayerModel(defaults: defaults, configuration: PlayerConfiguration(automaticQuality: true), qualityClock: { clock.now }) require(manual.automaticYouTubeQuality, "manual session override does not replace startup configuration") manual.shutdown() model.setYouTubeQuality(720) until(model, "manual selection opens real healthy 720p media") { model.youtubeHeight == 720 && model.canChangeYouTubeQuality && model.state.status == PLAYER_PLAYING && !model.state.seek_pending && (model.bufferedRange.map { $0.upperBound - model.state.position >= 20 } ?? false) } let selectedTitle = model.fileName let selectedQuality = model.youtubeQuality mark("gate-1080") clock.now = 3000 model.setAutomaticYouTubeQuality(true) polled(model) let healthyPosition = model.state.position until(model, "healthy native playback continues before the controlled upshift") { model.state.position > healthyPosition + 0.02 } clock.now = 3060 until(model, "automatic upshift reaches the selected extraction gate") { marked("entered-1080") && model.resolvingYouTube } require(model.setPlayback(playing: false), "pause is accepted during automatic extraction") mark("release-1080") until(model, "cancelled extraction finishes and native pause is acknowledged") { marked("finished-1080") && !model.resolvingYouTube && model.canTogglePlayback && model.state.status == PLAYER_PAUSED && !model.state.seek_pending } let cancelledPosition = model.state.position for _ in 0..<3 { polled(model) require(model.state.status == PLAYER_PAUSED && abs(model.state.position - cancelledPosition) < 0.05 && model.state.has_video && model.state.has_audio && model.youtubeHeight == 720 && model.youtubeQuality == selectedQuality && model.fileName == selectedTitle && model.errorText == nil, "late extraction cannot reopen different quality or resume deliberately paused media") } try! FileManager.default.removeItem(at: control.appendingPathComponent("gate-1080")) require(model.seekRelative(37 - model.state.position), "original paused media accepts a nonzero seek") until(model, "native original media acknowledges the seek") { model.canChangeYouTubeQuality && model.state.status == PLAYER_PAUSED && !model.state.seek_pending && abs(model.state.position - 37) < 0.05 } mark("fail-1080") for playing in [false, true] { require(model.setPlayback(playing: playing), "original playback state is selectable before quality failure") until(model, "original native playback reaches the requested state before quality failure") { model.canChangeYouTubeQuality && model.state.status == (playing ? PLAYER_PLAYING : PLAYER_PAUSED) && (!playing || model.state.position > 37.1) } let originalPosition = model.state.position model.setYouTubeQuality(1080) until(model, "failed manual quality switch restores the original native playback state") { model.errorText != nil && !model.resolvingYouTube && model.canTogglePlayback && model.state.status == (playing ? PLAYER_PLAYING : PLAYER_PAUSED) && (!playing || model.state.position > originalPosition + 0.1) } require(model.state.has_video && model.state.has_audio && model.youtubeHeight == 720 && model.youtubeQuality == selectedQuality && model.fileName == selectedTitle && model.state.position >= originalPosition - 0.05 && model.state.position < originalPosition + (playing ? 2 : 0.05), "failed manual quality switch retains original selected media and playback progress") } model.closeFile() require(!model.isCompact && !model.compactWindow.isTransitioning, "closing a streamed video restores its original window mode") print("PASS native adaptive playback: resolving/loading/buffering compact shortcuts+controls/default-off/stalled downshift/healthy upshift/progress preservation/current+default manual override/session-only settings/cancelled extraction pause/failed manual quality playing+paused preservation") } }