¿No hay delegado de AVPlayer? Cómo rastrear cuando la canción terminó de reproducirse? Objetivo C desarrollo de iPhone

He buscado pero no puedo encontrar un protocolo de delegado para la AVPlayer class . ¿Lo que da?

Estoy usando su subclase, AVQueuePlayer , para reproducir una matriz 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? Notablemente al final de la cola?

Y si eso no es posible, ¿hay alguna manera de llamar a un método cuando la canción COMIENZA a reproducirse, después del almacenamiento en búfer? Estoy tratando de obtener un ícono de carga pero apaga el ícono antes de que comience la música, incluso después de la [audioPlayer play] .

Sí, la clase AVPlayer no tiene un protocolo delegado como AVAudioPlayer. Debe suscribirse a las notificaciones en un AVPlayerItem. Puede crear un AVPlayerItem usando la misma URL que de otra manera 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 de KVO al estado o al índice 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: lo escribí aquí, así que no verifiqué si el código era bueno. TAMBIÉN nunca usé AVPlayer antes, pero debería ser lo correcto.

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 } 

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 ser principalmente a través de KVO por lo que es posible que desee repasarlo si no está muy familiarizado (hay una guía para ello en Key Value Observation ProgrammingGuide) .

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 clase personalizada con algunas propiedades y timeObserver is id ivar.