SwiftUI AVPlayer y AVPlayerLayer durante la recreación de la vista.
Estoy creando una aplicación de Mac OS utilizando SwiftUI.
Tengo un NSViewRepresentable que envuelve al AVPlayer:
class PlaybackModel {
var player: AVPlayer!
var playerLayer: AVPlayerLayer!
func createPlayerLayer() -> AVPlayerLayer {
let result = AVPlayerLayer(player: self.player)
result.videoGravity = .resizeAspect
result.needsDisplayOnBoundsChange = true
result.backgroundColor = .black
self.playerLayer = result
}
}
struct PlayerViewAdapter: NSViewRepresentable {
let playbackModel: PlaybackModel!
func makeNSView(context: Context) -> BasePlayerView {
return BasePlayerView(playbackModel)
}
func updateNSView(_ nsView: BasePlayerView, context: Context) {
}
}
y el BasePlayerView utiliza el AVPlayerLayer como una capa de soporte:
class BasePlayerView: NSView {
private var playbackModel: PlaybackModel!
init(_ playbackModel: PlaybackModel) {
self.playbackModel = playbackModel
super.init(frame: .zero)
wantsLayer = true
}
override func makeBackingLayer() -> CALayer {
return playbackModel.playerLayer
}
}
Inicialmente funciona bien y puedo ver el video reproduciéndose dentro de la vista.
Sin embargo, parece haber un problema durante el proceso de re-renderización de SwiftUI, cuando el método PlayerViewAdapter.makeNSView() se llama nuevamente para el mismo PlaybackModel (debido a cambios de estado), el AVPlayerLayer no se renderiza en el BasePlayerView recién creado.
¿Necesito realizar alguna acción adicional durante esta re-creación de las vistas del reproductor?
davy.ai
Sí, debes actualizar la propiedad
playbackModel.playerLayer
para que apunte a la nueva capa AVPlayerLayer creada en el métodoPlayerViewAdapter.updateNSView()
. Este método se llama cuando la vista necesita ser actualizada debido a cambios de estado. Puedes hacer esto simplemente llamando ansView.layer?.addSublayer(playbackModel.playerLayer)
para agregar la nueva capa como una subcapa a la capa de la vista.