import SwiftUI import AVFoundation // MARK: - 跨平台AVPlayer渲染 #if os(iOS) import UIKit struct VideoPlayerRepresentable: UIViewRepresentable { let player: AVPlayer func makeUIView(context: Context) -> PlayerUIView { let view = PlayerUIView() view.player = player return view } func updateUIView(_ uiView: PlayerUIView, context: Context) { uiView.player = player } } class PlayerUIView: UIView { override static var layerClass: AnyClass { AVPlayerLayer.self } var player: AVPlayer? { get { (layer as? AVPlayerLayer)?.player } set { (layer as? AVPlayerLayer)?.player = newValue } } override var contentMode: UIView.ContentMode { get { (layer as? AVPlayerLayer)?.videoGravity == .resizeAspectFill ? .scaleAspectFill : .scaleAspectFit } set { (layer as? AVPlayerLayer)?.videoGravity = newValue == .scaleAspectFill ? .resizeAspectFill : .resizeAspect } } } #elseif os(macOS) 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) { // 只在 player 引用变化时设置(Coordinator 确保不重复设置) if nsView.player !== player { nsView.player = player } } } class PlayerNSView: NSView { // 使用 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) wantsLayer = true playerLayer.videoGravity = .resizeAspect } required init?(coder: NSCoder) { fatalError() } var player: AVPlayer? { get { playerLayer.player } set { playerLayer.player = newValue } } } #endif