Sin delegado de AVPlayer? ¿Cómo rastrear cuándo terminó la canción? Desarrollo del iPhone Objective C

He mirado a mi alnetworkingedor, pero no puedo encontrar un protocolo de delegado para la AVPlayer class . ¿Lo que da?

Estoy usando su subclass, AVQueuePlayer , para reproducir una variedad de AVPlayerItems , cada uno cargado desde una URL. ¿Hay alguna manera de que pueda llamar a un método cuando una canción termina de reproducirse? ¿Al final de la fila?

Y si eso no es posible, ¿hay alguna forma en que pueda llamar a un método cuando la canción COMIENZA a jugar, después del almacenamiento en búfer? Estoy intentando get un ícono de carga allí, pero apaga el ícono antes de que la música realmente comience, aunque sea después de la [audioPlayer play] .

Sí, la class AVPlayer no tiene un protocolo de delegado como el AVAudioPlayer. Necesita suscribirse a las notifications en un AVPlayerItem. Puede crear un AVPlayerItem utilizando la misma URL que de lo contrario pasaría a -initWithURL: en 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 } 

Sí. Agregue un observador KVO al estado o tasa del jugador:

 - (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...]; } 

Entonces, básicamente, eso es todo.

Descargo de responsabilidad: escribí eso aquí, así que no comprobé si el código era bueno. TAMBIÉN nunca utilicé AVPlayer antes, pero debería ser correcto.

Hay mucha información en la Guía de progtwigción de AVFoundation de Apple docs (busque la sección de reproducción de monitoreo). Parece que es principalmente a través de KVO, por lo que es posible que desee repasar eso si no es demasiado familiar (hay una guía para ello en Key Value Observing Programming Guide.

Estoy usando este y funciona:

 _player = [[AVPlayer alloc]initWithURL:[NSURL URLWithString:_playingAudio.url]]; CMTime endTime = CMTimeMakeWithSeconds(_playingAudio.duration, 1); timeObserver = [_player addBoundaryTimeObserverForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:endTime]] queue:NULL usingBlock:^(void) { [_player removeTimeObserver:timeObserver]; timeObserver = nil; //TODO play next sound }]; [self play]; 

donde _playingAudio es mi class personalizada con algunas properties y timeObserver es id ivar.

Swift 3 : agrego un observador a AVPlayerItem cada vez que agrego un video al reproductor:

 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 }