fix: allow compact mode while media is loading

This commit is contained in:
2026-10-12 12:00:56 +02:00
parent f495c8b719
commit 1e75f554f0
6 changed files with 93 additions and 25 deletions
+57 -14
View File
@@ -36,12 +36,66 @@ struct AutomaticQualityPlaybackChecks {
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,
@@ -75,19 +129,6 @@ struct AutomaticQualityPlaybackChecks {
qualityClock: { clock.now })
require(manual.automaticYouTubeQuality, "manual session override does not replace startup configuration")
manual.shutdown()
// 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)
}
model.setYouTubeQuality(720)
until(model, "manual selection opens real healthy 720p media") {
model.youtubeHeight == 720 && model.canChangeYouTubeQuality && model.state.status == PLAYER_PLAYING &&
@@ -149,6 +190,8 @@ struct AutomaticQualityPlaybackChecks {
"failed manual quality switch retains original selected media and playback progress")
}
model.closeFile()
print("PASS native adaptive playback: default-off/stalled downshift/healthy upshift/progress preservation/current+default manual override/session-only settings/cancelled extraction pause/failed manual quality playing+paused preservation")
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")
}
}
+4
View File
@@ -45,6 +45,10 @@ def main():
control.mkdir()
wrapper.write_text("#!/bin/bash\nset -eu\nargs=(\"$@\")\n"
+ "control=" + shlex.quote(str(control)) + "\n"
+ 'if [[ -f "$control/gate-open" ]]; then\n'
+ ' : > "$control/entered-open"\n'
+ ' while [[ -f "$control/gate-open" && ! -f "$control/release-open" ]]; do sleep 0.01; done\n'
+ 'fi\n'
+ 'if [[ "$*" == *"[height=1080]"* ]]; then\n'
+ ' if [[ -f "$control/fail-1080" ]]; then\n'
+ ' echo "Fixture extraction deliberately failed" >&2; exit 1\n'
+18
View File
@@ -48,6 +48,24 @@ struct SystemPlaybackChecks {
let directory = URL(fileURLWithPath: CommandLine.arguments[1], isDirectory: true)
let center = MPNowPlayingInfoCenter.default()
let commands = MPRemoteCommandCenter.shared()
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)
model.open(directory.appendingPathComponent("anamorphic.mp4"))
require(model.isBusy && model.perform(.enterCompact) && model.isCompact,
"compact entry is available before native media opening acknowledges")
until("decoded anamorphic metadata replaces provisional compact geometry") {
model.state.status == PLAYER_PLAYING && model.isCompact && !model.compactWindow.isTransitioning &&
abs(window.frame.width / window.frame.height - 8.0 / 3.0) < 0.01
}
model.closeFile()
require(!model.isCompact && !model.compactWindow.isTransitioning,
"closing loading/loaded media restores immediately")
until("anamorphic source closes before the ordinary playback checks") { model.state.status == PLAYER_EMPTY }
require(!model.canPerform(.enterCompact), "empty playback does not enable compact entry")
model.open(directory.appendingPathComponent("av.mp4"))
until("open starts authoritative playback") { model.canTogglePlayback && model.state.status == PLAYER_PLAYING }