Root cause: custom AVPlayerLayer lifecycle management causes CoreMedia FigNotificationCenter weak listener race condition. Apple's AVPlayerView handles all internal teardown correctly. Changes: - VideoPlayerView.swift: NSViewRepresentable wrapping AVPlayerView (macOS) and UIViewControllerRepresentable wrapping AVPlayerViewController (iOS) - PlayerBridge.swift: fullscreen uses AVPlayerView, removed FullscreenPlayerView class entirely - Fullscreen interaction via NSEvent.addLocalMonitorForEvents: double-click exits, single-click toggles play/pause, Escape exits - cleanup() now closes fullscreen window and removes event monitor - Removed ExitFullscreen NotificationCenter listener from MiniPlayerApp
49 lines
1.2 KiB
Swift
49 lines
1.2 KiB
Swift
import SwiftUI
|
||
import AVFoundation
|
||
import AVKit
|
||
|
||
// MARK: - 跨平台 AVPlayer 渲染(使用系统 AVPlayerView / AVPlayerViewController)
|
||
|
||
#if os(iOS)
|
||
import UIKit
|
||
|
||
struct VideoPlayerRepresentable: UIViewControllerRepresentable {
|
||
let player: AVPlayer
|
||
|
||
func makeUIViewController(context: Context) -> AVPlayerViewController {
|
||
let vc = AVPlayerViewController()
|
||
vc.player = player
|
||
vc.showsPlaybackControls = false
|
||
vc.videoGravity = .resizeAspect
|
||
return vc
|
||
}
|
||
|
||
func updateUIViewController(_ vc: AVPlayerViewController, context: Context) {
|
||
if vc.player !== player {
|
||
vc.player = player
|
||
}
|
||
}
|
||
}
|
||
|
||
#elseif os(macOS)
|
||
import AppKit
|
||
|
||
struct VideoPlayerRepresentable: NSViewRepresentable {
|
||
let player: AVPlayer
|
||
|
||
func makeNSView(context: Context) -> AVPlayerView {
|
||
let view = AVPlayerView()
|
||
view.player = player
|
||
view.controlsStyle = .none
|
||
view.videoGravity = .resizeAspect
|
||
return view
|
||
}
|
||
|
||
func updateNSView(_ nsView: AVPlayerView, context: Context) {
|
||
if nsView.player !== player {
|
||
nsView.player = player
|
||
}
|
||
}
|
||
}
|
||
#endif
|