From 0ddd66edc4ada2acd2ba7f673fbadfdbf275adf0 Mon Sep 17 00:00:00 2001 From: Samuel Zielke Date: Mon, 14 Sep 2026 01:42:28 +0200 Subject: [PATCH] =?UTF-8?q?Fix:=20Absturz=20beim=20=C3=96ffnen=20der=20Rev?= =?UTF-8?q?iew-Ansicht?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AVKits VideoPlayer (SwiftUI) crasht auf diesem macOS-Stand beim Anzeigen mit einem Swift-Runtime-Fehler: "failed to demangle superclass of VideoPlayerView from mangled name 'So12AVPlayerViewC'". Das ist ein Metadata-Bug in Apples eigener _AVKit_SwiftUI-Bridge, kein Fehler in unserem Code — bestätigt über den Crash-Report (SIGABRT, swift::fatalError beim Instanziieren der generischen Metadata für VideoPlayerView). Fix: PlayerView bindet AppKits AVPlayerView direkt per NSViewRepresentable ein statt über AVKits SwiftUI-Wrapper zu gehen — umgeht den kaputten Codepfad komplett. --- Sources/DropTwo/Views/PlayerView.swift | 28 +++++++++++++++++++++++++ Sources/DropTwo/Views/ReviewSheet.swift | 12 ++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 Sources/DropTwo/Views/PlayerView.swift diff --git a/Sources/DropTwo/Views/PlayerView.swift b/Sources/DropTwo/Views/PlayerView.swift new file mode 100644 index 0000000..8306560 --- /dev/null +++ b/Sources/DropTwo/Views/PlayerView.swift @@ -0,0 +1,28 @@ +import AppKit +import AVKit +import SwiftUI + +/// Dünne Hülle um AppKits `AVPlayerView` statt AVKits SwiftUI-`VideoPlayer`. +/// +/// `VideoPlayer` crasht auf manchen macOS-Ständen beim Öffnen mit einem +/// Swift-Runtime-Fehler ("failed to demangle superclass of VideoPlayerView +/// from mangled name 'So12AVPlayerViewC'") — ein Metadata-Bug in Apples +/// eigener `_AVKit_SwiftUI`-Bridge, kein Fehler in diesem Code. `AVPlayerView` +/// direkt per `NSViewRepresentable` einzubinden umgeht den kaputten Codepfad. +struct PlayerView: NSViewRepresentable { + let player: AVPlayer + + func makeNSView(context: Context) -> AVPlayerView { + let view = AVPlayerView() + view.player = player + view.controlsStyle = .inline + view.showsFullScreenToggleButton = false + return view + } + + func updateNSView(_ nsView: AVPlayerView, context: Context) { + if nsView.player !== player { + nsView.player = player + } + } +} diff --git a/Sources/DropTwo/Views/ReviewSheet.swift b/Sources/DropTwo/Views/ReviewSheet.swift index a336cf8..b86add6 100644 --- a/Sources/DropTwo/Views/ReviewSheet.swift +++ b/Sources/DropTwo/Views/ReviewSheet.swift @@ -3,10 +3,12 @@ import DropTwoCore import SwiftUI /// Schritt 5: 9:16-Master mit eingeblendetem 4:5-Rahmen zur Framing-Kontrolle. -/// Scrubbar über die nativen AVKit-Kontrollen von `VideoPlayer`. Der Rahmen -/// nutzt exakt dieselbe Geometrie wie `CropEngine.targetSize` — was hier zu -/// sehen ist, ist tatsächlich das, was beim Crop rauskommt. Rein zur Kontrolle: -/// der Offset ist hier noch nicht verstellbar (README, "Danach"-Liste). +/// Scrubbar über die nativen Kontrollen von `PlayerView` (AppKits +/// `AVPlayerView`, nicht AVKits SwiftUI-`VideoPlayer` — siehe dort für den +/// Grund). Der Rahmen nutzt exakt dieselbe Geometrie wie +/// `CropEngine.targetSize` — was hier zu sehen ist, ist tatsächlich das, was +/// beim Crop rauskommt. Rein zur Kontrolle: der Offset ist hier noch nicht +/// verstellbar (README, "Danach"-Liste). struct ReviewSheet: View { let sourceURL: URL @Environment(\.dismiss) private var dismiss @@ -45,7 +47,7 @@ struct ReviewSheet: View { } else if let player, let videoSize, videoSize.height > 0 { GeometryReader { proxy in ZStack { - VideoPlayer(player: player) + PlayerView(player: player) cropOverlay(sourceSize: videoSize, viewSize: proxy.size) } }