MiniPlayer/Sources/VideoPlayerView.swift
yumoqing 6811572b7e fix: rewrite UI as pure SwiftUI, fix crash/fullscreen/height issues
- Skip BricksView, render video directly in SwiftUI (fixes 1/3 height)
- Fullscreen uses plain NSView+AVPlayerLayer (fixes objc_release crash)
- Remove NSApp.hide(nil) (fixes fullscreen not showing)
- Add volume +/- buttons and volume slider indicator
- Add iOS/iPadOS support with #if os guards
- ProgressSlider decoupled from BricksEngine
- PlayerBridge no longer depends on player.ui JSON
2026-06-22 00:04:06 +08:00

80 lines
1.9 KiB
Swift

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 makeNSView(context: Context) -> PlayerNSView {
let view = PlayerNSView()
view.player = player
return view
}
func updateNSView(_ nsView: PlayerNSView, context: Context) {
nsView.player = player
}
}
class PlayerNSView: NSView {
override init(frame: NSRect) {
super.init(frame: frame)
wantsLayer = true
let playerLayer = AVPlayerLayer()
playerLayer.videoGravity = .resizeAspect
layer = playerLayer
}
required init?(coder: NSCoder) {
fatalError()
}
override func layout() {
super.layout()
(layer as? AVPlayerLayer)?.frame = bounds
}
var player: AVPlayer? {
get { (layer as? AVPlayerLayer)?.player }
set { (layer as? AVPlayerLayer)?.player = newValue }
}
}
#endif