Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No AVPlayer Delegate? How to track when song finished playing? Objective C iPhone development

I've looked around but I can't find a delegate protocol for the AVPlayer class. What gives?

I'm using its subclass, AVQueuePlayer, to play an array of AVPlayerItems, each loaded from a URL. Is there any way I can call a method when a song finishes playing? Notably at the end of the queue?

And if that's not possible, is there any way I could call a method when the song STARTS playing, after buffering? I'm trying to get a loading icon in there but it turns the icon off before the music actually begins, even though it's after the [audioPlayer play] action.

like image 357
Tyler Avatar asked Jul 26 '11 21:07

Tyler


2 Answers

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 } 
like image 159
arexx Avatar answered Sep 24 '22 06:09

arexx


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.

like image 25
Daij-Djan Avatar answered Sep 22 '22 06:09

Daij-Djan