No AVPlayer Delegate? How to track when song finished playing? Objective C iPhone development
Yes, the AVPlayer class does not have a delegate protocol like the AVAudioPlayer. You need to subscribe to notifications on an AVPlayerItem. You can create an AVPlayerItem using the same URL that you would otherwise pass to -initWithURL:
on AVPlayer.
-(void)startPlaybackForItemWithURL:(NSURL*)url { // First create an AVPlayerItem AVPlayerItem* playerItem = [AVPlayerItem playerItemWithURL:url]; // Subscribe to the AVPlayerItem's DidPlayToEndTime notification. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(itemDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerItem]; // Pass the AVPlayerItem to a new player AVPlayer* player = [[[AVPlayer alloc] initWithPlayerItem:playerItem] autorelease]; // Begin playback [player play]} -(void)itemDidFinishPlaying:(NSNotification *) notification { // Will be called when AVPlayer finishes playing playerItem}
Yes. Add a KVO observer to the player's status or rate:
- (IBAction)go { self.player = ..... self.player.actionAtItemEnd = AVPlayerActionStop; [self.player addObserver:self forKeyPath:@"rate" options:0 context:0]; }- (void)stopped { ... [self.player removeObserver:self]; //assumes we are the only observer}- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (context == 0) { if(player.rate==0.0) //stopped [self stopped]; } else [super observeVal...];}
So basically, that's it.
Disclaimer: I wrote that in here so I didn't check if the code was good. ALSO I never used AVPlayer before but it should be about right.
Swift 3 - I add an observer to AVPlayerItem
every time I add a video to the player:
func playVideo(url: URL) { let playerItem = AVPlayerItem(asset: AVURLAsset(url: someVideoUrl)) NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem) self.player.replaceCurrentItem(with: playerItem) self.player.play()}func playerItemDidPlayToEndTime() { // load next video or something}