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.