101 lines
2.6 KiB
Swift
101 lines
2.6 KiB
Swift
import SwiftUI
|
|
import AVFoundation
|
|
import SwiftBricks
|
|
|
|
/// VideoPlayer自定义Widget — 注册到BricksEngine的"VideoPlayer"类型
|
|
struct VideoPlayerWidget: View {
|
|
let bridge: PlayerBridge
|
|
let schema: ControlSchema
|
|
@ObservedObject var engine: BricksEngine
|
|
|
|
var body: some View {
|
|
VideoPlayerRepresentable(player: bridge.player)
|
|
.background(Color.black)
|
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
.contentShape(Rectangle())
|
|
.onTapGesture {
|
|
bridge.togglePlayPause()
|
|
}
|
|
.onTapGesture(count: 2) {
|
|
bridge.toggleFullscreen()
|
|
}
|
|
}
|
|
}
|
|
|
|
// 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
|