I am trying to use VLCKit along with AVPlayerLayer (in order to eventually use PIP) I have VLCKit working correctly but I am unable to use it with PlayerLayer
This is the most basic working example using AVPlayer as the player that I am trying to modify but with no luck. Any help appreciated, thanks.
import AVFoundation
import SwiftUI
class PlayerView: UIView {
var player: AVPlayer? {
get {
return playerLayer.player
}
set {
playerLayer.player = newValue
}
}
init(player: AVPlayer) {
super.init(frame: .zero)
self.player = player
self.backgroundColor = .black
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var playerLayer: AVPlayerLayer {
return layer as! AVPlayerLayer
}
// Override UIView property
override static var layerClass: AnyClass {
return AVPlayerLayer.self
}
}
struct PlayerContainerView: UIViewRepresentable {
typealias UIViewType = PlayerView
let player: AVPlayer
init(player: AVPlayer) {
self.player = player
}
func makeUIView(context: Context) -> PlayerView {
return PlayerView(player: player)
}
func updateUIView(_ uiView: PlayerView, context: Context) { }
}
class PlayerViewModel: ObservableObject {
let player: AVPlayer
init(fileName: String) {
let url = Bundle.main.url(forResource: fileName, withExtension: "mp4")
self.player = AVPlayer(playerItem: AVPlayerItem(url: url!))
}
@Published var isPlaying: Bool = false {
didSet {
if isPlaying {
play()
} else {
pause()
}
}
}
func play() {
let currentItem = player.currentItem
if currentItem?.currentTime() == currentItem?.duration {
currentItem?.seek(to: .zero, completionHandler: nil)
}
player.play()
}
func pause() {
player.pause()
}
}
enum PlayerAction {
case play
case pause
}
struct ContentView: View {
@ObservedObject var model: PlayerViewModel
init() {
model = PlayerViewModel(fileName: "video")
}
var body: some View {
ZStack {
VStack {
PlayerContainerView(player: model.player)
.frame(height: 200)
Button(action: {
self.model.isPlaying.toggle()
}, label: {
Image(systemName: self.model.isPlaying ? "pause" : "play")
.font(.largeTitle)
.padding()
})
}
}
.ignoresSafeArea()
}
}
In SwiftUI you can't have classes in your
Viewstructs. So first renamePlayerViewModelasPlayerCoordinatorand init it inside theUIViewRepresentable. It is also essential you implementupdateUIViewto copy the values from the struct to the objects, e.g. something like this:Then your View struct should be like this: