2

I've got a player going on, and have been instructed on how to set a notification for itemDidFinishPlaying: (AVPlayerItemDidPlayToEndTimeNotification), however, for some reason, that notification function is not called at the end of the video.

 import UIKit
 import AVKit

 class ViewController: UIViewController {

 let playerLayer = AVPlayerLayer()

func playMe(inputfile: String, inputtype: String) {


    let path = NSBundle.mainBundle().pathForResource(inputfile, ofType:inputtype)!
    let videoURL = NSURL(fileURLWithPath: path)
    let playerItem = AVPlayerItem(URL: videoURL)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = self.view.bounds
    self.view.layer.addSublayer(playerLayer)
    player.play()
    print ("Play has started")

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "itemDidFinishPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem)
    print ("Item Did Finish Playing -notification added")

}

func itemDidFinishPlaying(notification: NSNotification) {
    playerLayer.removeFromSuperlayer()
    print ("Notification sent with removeFromSuperlayer done")

}
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

what am I missing? I've tried having the notification entry at viewDidLoad(), I've tried removing the : from the end of itemDidFinishPlaying, I've tried setting the notification before the start of the playback, I've had object: nil and object:playerItem in the NSNotificationCenter..

I really am quite clueless as to how to proceed.

are these types of things only available when one has a AVPlayerViewController - or a secondary view controller that is spawned on button press?

Ramkrishna Sharma
  • 6,961
  • 3
  • 42
  • 51
esaruoho
  • 896
  • 1
  • 7
  • 25

1 Answers1

0

this seems to happen if you do not hold a reference to the AVPlayer instance. try this:

import UIKit
import AVFoundation

class ViewController: UIViewController {
    var player: AVPlayer?
    var playerLayer: AVPlayerLayer?

    func playMe(inputfile: String, inputtype: String) {
        guard let path = NSBundle.mainBundle().pathForResource(inputfile, ofType: inputtype) else {
            print("couldn't find \(inputfile).\(inputtype)")

            return
        }

        player = AVPlayer()
        playerLayer = AVPlayerLayer(player: player)

        let playerItem = AVPlayerItem(URL: NSURL(fileURLWithPath: path))

        player?.replaceCurrentItemWithPlayerItem(playerItem)

        playerLayer.frame = view.bounds

        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.itemDidFinishPlaying(_:)), name: AVPlayerItemDidPlayToEndTimeNotification, object: player?.currentItem)

        view.layer.insertSublayer(playerLayer!, atIndex: 0)

        player?.play()
    }

    func itemDidFinishPlaying(notification: NSNotification) {
        playerLayer?.removeFromSuperlayer()
        print ("Notification sent with removeFromSuperlayer done")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

This should do the trick.

Don't forget to remove observers

deinit {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}
ergoon
  • 1,264
  • 9
  • 17