diff --git a/Sources/MiniPlayerApp.swift b/Sources/MiniPlayerApp.swift index 778d99c..40ff2dc 100644 --- a/Sources/MiniPlayerApp.swift +++ b/Sources/MiniPlayerApp.swift @@ -11,6 +11,7 @@ struct MiniPlayerApp: App { ContentView(bridge: bridge) .frame(minWidth: 900, minHeight: 600) .onAppear { bridge.setup() } + .onDisappear { bridge.cleanup() } } #if os(macOS) .commands { diff --git a/Sources/PlayerBridge.swift b/Sources/PlayerBridge.swift index 870bd28..917a727 100644 --- a/Sources/PlayerBridge.swift +++ b/Sources/PlayerBridge.swift @@ -425,7 +425,10 @@ final class PlayerBridge: ObservableObject { import AppKit class FullscreenPlayerView: NSView { - private let playerLayer = AVPlayerLayer() + // 使用 makeBackingLayer 让 AppKit 管理 AVPlayerLayer + override func makeBackingLayer() -> CALayer { AVPlayerLayer() } + + private var playerLayer: AVPlayerLayer { layer as! AVPlayerLayer } var player: AVPlayer? { get { playerLayer.player } @@ -442,14 +445,6 @@ class FullscreenPlayerView: NSView { override var acceptsFirstResponder: Bool { true } - override func layout() { - super.layout() - if playerLayer.superlayer !== layer { - layer?.addSublayer(playerLayer) - } - playerLayer.frame = bounds - } - override func mouseDown(with event: NSEvent) { if event.clickCount == 2 { NotificationCenter.default.post(name: .init("ExitFullscreen"), object: nil) diff --git a/Sources/VideoPlayerView.swift b/Sources/VideoPlayerView.swift index 12efd97..1b115ab 100644 --- a/Sources/VideoPlayerView.swift +++ b/Sources/VideoPlayerView.swift @@ -42,19 +42,32 @@ import AppKit struct VideoPlayerRepresentable: NSViewRepresentable { let player: AVPlayer + func makeCoordinator() -> Coordinator { Coordinator() } + + class Coordinator { + weak var view: PlayerNSView? + } + func makeNSView(context: Context) -> PlayerNSView { let view = PlayerNSView() view.player = player + context.coordinator.view = view return view } func updateNSView(_ nsView: PlayerNSView, context: Context) { - nsView.player = player + // 只在 player 引用变化时设置(Coordinator 确保不重复设置) + if nsView.player !== player { + nsView.player = player + } } } class PlayerNSView: NSView { - private let playerLayer = AVPlayerLayer() + // 使用 makeBackingLayer 让 AppKit 管理 AVPlayerLayer 作为 backing layer + override func makeBackingLayer() -> CALayer { AVPlayerLayer() } + + private var playerLayer: AVPlayerLayer { layer as! AVPlayerLayer } override init(frame: NSRect) { super.init(frame: frame) @@ -64,16 +77,6 @@ class PlayerNSView: NSView { required init?(coder: NSCoder) { fatalError() } - override func layout() { - super.layout() - // 确保 playerLayer 作为 sublayer 存在(不要在 init 中 addSublayer, - // 因为 wantsLayer=true 后 layer 可能还没创建) - if playerLayer.superlayer !== layer { - layer?.addSublayer(playerLayer) - } - playerLayer.frame = bounds - } - var player: AVPlayer? { get { playerLayer.player } set { playerLayer.player = newValue }