2

I use AVPlayer to play a simple MP4 video. As I need to know when the video finishes, I add an observer for the notification AVPlayerItemDidPlayToEndTime.

This works fine, if the video is played on the device, but the notification is never posted if we are streaming the video from a device to an Apple TV (4th gen) with tvOS 12.2 via AirPlay.

Strangely, this problem only occurs with MP4 videos, not with HLS streams (m3u8), which makes me wonder if this might be a tvOS (or AirPlay) bug.

I created a small POC to isolate the problem, and this is what I do:

let bunny = "https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_1mb.mp4"

// create a new player with every call to startVideo() for demo purposes
func startVideo() {

    // remove layer of current play from playerContainer as
    // a new one will be created below
    if let sublayers = playerContainer.layer.sublayers {
        for layer in sublayers {
            layer.removeFromSuperlayer()
        }
    }

    if let videoUrl = URL(string: bunny) {
        // create player with sample video URL
        self.player = AVPlayer(url: videoUrl)

        guard let player = self.player else {return}

        // add player layer to playerContainer
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = playerContainer.bounds
        playerLayer.videoGravity = .resizeAspectFill
        playerContainer.layer.addSublayer(playerLayer)

        // add block-based observer to listen for AVPlayerItemDidPlayToEndTime event
        let _ = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                                       object: player.currentItem,
                                                       queue: .main) { notification in
            print("Item did finish playing! \(notification)")
        }

        player.play()
    }
}

Just to clarify again, this works fine, if one of the following conditions is true:

  • The video is played on the device, and no AirPlay is involved.
  • The video is streamed to an AppleTV 3rd gen.
  • An HLS instead of an MP4 video is used.

I also tried the following things, but the result was the same:

  • Don't set currentItem as object when adding observer.
  • Don't specify the queue when adding observer.
  • Don't use block-based but selector-based method to add an observer.

Any help is appreciated. This might be a duplicate of this question, but as there are no answers, and linked question is about HLS and not MP4, I decided to post this question anyway.

Flo
  • 2,309
  • 20
  • 27

0 Answers0