fix: verify stream queue startup and canonical report paths

This commit is contained in:
2026-10-22 14:26:16 +02:00
parent 0588d162d6
commit 4fe53c0a07
4 changed files with 29 additions and 31 deletions
+25 -27
View File
@@ -387,6 +387,7 @@ final class PlayerModel: ObservableObject {
guard canOpen, progressInitializationError == nil else { return }
queueCastDevice = nil
queue.replaceStreams(streamQueue.entries.map { (url: $0.url, label: $0.label) })
if fileName == nil { configureStartWindow(showing: false) }
showsQueue = queue.items.count > 1
showsYouTubeInput = false
openQueueSelection(keepingReceiver: false)
@@ -920,7 +921,7 @@ final class PlayerModel: ObservableObject {
queueAnimation = nil
queueAnimationCompletion = nil
let targetWidth: CGFloat = showsQueue ? 260 : 0
guard let window, !isCompact, !compactWindow.isTransitioning else {
guard let window, fileName != nil, !isCompact, !compactWindow.isTransitioning else {
queueWidth = targetWidth
queueWindowVideoWidth = nil
return
@@ -1264,6 +1265,10 @@ final class PlayerModel: ObservableObject {
private func poll() {
guard let handle else { return }
if window?.isVisible == true, let streamQueue = Self.startupStreamQueue {
Self.startupStreamQueue = nil
openStreamQueue(streamQueue)
}
if reportingEnabled && !reportingErrorShown {
if player_get_progress_error(handle, &reportingErrorBuffer) {
showReportingError(reportingErrorMessage)
@@ -3118,7 +3123,7 @@ private struct PlayerContent: View {
var body: some View {
let titleControlsVisible = model.showsQueue || model.isQueueTransitioning || model.controlsVisible
let startScreen = model.fileName == nil && !model.isCompact && !model.compactWindow.isTransitioning
let startScreen = model.fileName == nil && model.queue.items.isEmpty && !model.isCompact && !model.compactWindow.isTransitioning
HStack(spacing: 0) {
videoContent
if !model.isCompact && !model.compactWindow.isTransitioning && model.queueWidth > 0 {
@@ -3520,6 +3525,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
let events = NSAppleEventManager.shared()
events.setEventHandler(self, andSelector: #selector(openInternetURL(_:withReplyEvent:)),
forEventClass: AEEventClass(kInternetEventClass), andEventID: AEEventID(kAEGetURL))
// Pre-main model/AppKit initialization suppresses SwiftUI's initial player window.
if let error = PlayerModel.shared.progressInitializationError {
PlayerModel.shared.shutdown()
FileHandle.standardError.write(Data("terebi: \(error)\n".utf8))
NSApp.setActivationPolicy(.regular)
NSApp.activate()
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "Could not initialize playback progress reporting"
alert.informativeText = error
alert.runModal()
exit(73)
}
}
@objc private func openInternetURL(_ event: NSAppleEventDescriptor, withReplyEvent reply: NSAppleEventDescriptor) {
@@ -3546,9 +3564,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
if let index = arguments.firstIndex(of: "--source-file"), index + 1 < arguments.count {
PlayerModel.shared.openResolvedSource(URL(fileURLWithPath: arguments[index + 1]))
}
if let streamQueue = PlayerModel.startupStreamQueue {
PlayerModel.shared.openStreamQueue(streamQueue)
}
}
// Let SwiftUI create the initial window for a Finder/document launch.
@@ -3574,7 +3589,6 @@ struct TerebiApp: App {
PlayerContent(model: model)
.focusedSceneObject(model)
}
.defaultLaunchBehavior(.presented)
.defaultSize(width: 640, height: 400)
.windowResizability(.contentSize)
.windowStyle(.hiddenTitleBar)
@@ -3604,19 +3618,16 @@ public func terebiAppMain() {
exit(78)
}
let arguments = Array(CommandLine.arguments.dropFirst())
if let index = arguments.firstIndex(of: "--queue-file") {
let queueArguments = arguments.filter { $0.hasPrefix("--queue-file=") }
if let argument = queueArguments.first {
do {
guard index + 1 < arguments.count, arguments[index + 1].hasPrefix("/"),
arguments.filter({ $0 == "--queue-file" }).count == 1,
let path = String(argument.dropFirst("--queue-file=".count))
guard path.hasPrefix("/"), queueArguments.count == 1,
!arguments.contains("--progress-file"), !arguments.contains("--source-file"),
!arguments.contains("--open-media") else {
throw CocoaError(.fileReadCorruptFile)
}
PlayerModel.startupStreamQueue = try StreamQueue.load(from: URL(fileURLWithPath: arguments[index + 1]))
_ = NSApplication.shared
if let error = PlayerModel.shared.progressInitializationError {
throw NSError(domain: "Terebi.Queue", code: 73, userInfo: [NSLocalizedDescriptionKey: error])
}
PlayerModel.startupStreamQueue = try StreamQueue.load(from: URL(fileURLWithPath: path))
} catch {
FileHandle.standardError.write(Data("terebi: \(error.localizedDescription)\n".utf8))
exit(73)
@@ -3633,19 +3644,6 @@ public func terebiAppMain() {
exit(73)
}
PlayerModel.startupProgressFile = arguments[index + 1]
_ = NSApplication.shared
if let error = PlayerModel.shared.progressInitializationError {
PlayerModel.shared.shutdown()
FileHandle.standardError.write(Data("terebi: \(error)\n".utf8))
NSApp.setActivationPolicy(.regular)
NSApp.activate()
let alert = NSAlert()
alert.alertStyle = .critical
alert.messageText = "Could not initialize playback progress reporting"
alert.informativeText = error
alert.runModal()
exit(73)
}
}
TerebiApp.main()
}