ios - ¿No hay delegado de AVPlayer? Cómo rastrear cuando la canción terminó de reproducirse? Objetivo C desarrollo de iPhone
objective-c avplayerviewcontroller (5)
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.
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]
.
Hay mucha información en la guía de programació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) .
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
}