swiftavplayeravplayerlayer

AVPlayerLayer not playing video but the audio is good


I have somewhat of a confusing problem. I declared these variables in my class:

var audioPlayer = AVPlayer()
var videoPlayer = AVPlayer()
var videoLayer = AVPlayerLayer()

I have these codes for adding the container of the videoPlayer:

let aspectHeight = view.frame.width * 9/16
let viewFrame = CGRect(x: 5, y: 0, width: view.frame.width - 10, height: aspectHeight)
let layerFrame = CGRect(x: 0, y: 0, width: view.frame.width - 10, height: aspectHeight)

videoPlayerContainerView.frame = viewFrame
videoPlayerViewController.frame = viewFrame
videoLayer.frame = layerFrame

videoLayer.backgroundColor = UIColor.green.cgColor
videoPlayerContainerView.layer.addSublayer(videoLayer)
videoPlayerContainerView.addSubview(videoPlayerViewController)

videoElementContainerView.addView(newView: videoPlayerContainerView)

I also have this function (I replaced the passed argument with a temporary URL):

@IBAction func pausePlayVideo(_ sender: CustomButton) {
    let videoString = videoSourceURL + (sender.paramaters["thisVideoURL"] as! String)
    let videoURL = URL(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
    videoPlayer = AVPlayer(url: videoURL!)
    videoLayer = AVPlayerLayer(player: videoPlayer)

    videoPlayer.play()
}

I'm calling it here:

pausePlayButton.addTarget(self, action: #selector(ModuleLessonElementsViewController.pausePlayVideo(_:)), for: .touchUpInside)
pausePlayButton.paramaters["thisVideoURL"] = content

Here would be the view: The layer was added, the audio plays but the video does not.

When the button is pressed, the audio plays, however the video does not. Am I missing something important here?


Solution

  • It's very simple. Early on, you say:

    videoPlayerContainerView.layer.addSublayer(videoLayer)
    

    Okay, so you have a player layer videoLayer, associated with no player, and it is in the interface now. Fine.

    Later, when the button is pressed, you say:

    @IBAction func pausePlayVideo(_ sender: CustomButton) {
        // ...
        videoLayer = AVPlayerLayer(player: videoPlayer)
        videoPlayer.play()
    }
    

    So what just happened? You threw away your reference in videoLayer to the layer that you previously added to the interface, and substituted for it a completely new player layer that you just created, and that is not in the interface. Okay, so the video layer you have associated with the player is not in the interface, so you can hear the player but you can't see anything.