AVPlayer Temsilcisi yok mu? Şarkının çalması bittiğinde nasıl takip edilir? Objective C iPhone geliştirme


84

Etrafıma baktım ama için bir delege protokolü bulamıyorum AVPlayer class. Ne oluyor?

Her biri bir URL'den yüklenen AVQueuePlayerbir dizi oynatmak için alt sınıfını kullanıyorum AVPlayerItems. Bir şarkının çalması bittiğinde bir yöntem çağırmamın bir yolu var mı? Özellikle kuyruğun sonunda mı?

Ve bu mümkün değilse, ara belleğe alma işleminden sonra şarkı STARTS çalarken bir yöntem çağırmamın bir yolu var mı? Orada bir yükleme simgesi almaya çalışıyorum ancak [audioPlayer play]eylemden sonra olsa bile müzik gerçekten başlamadan önce simgeyi kapatıyor .

Yanıtlar:


152

Evet, AVPlayer sınıfı AVAudioPlayer gibi bir temsilci protokolüne sahip değildir. Bir AVPlayerItem'deki bildirimlere abone olmanız gerekir. Aksi takdirde -initWithURL:AVPlayer'da ileteceğiniz URL'nin aynısını kullanarak bir AVPlayerItem oluşturabilirsiniz .

-(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
}

1
itemDidFinishPlaying:Örneğin kolon ile kullandığınızdan emin olun . Kaynaktan NSNotificationCenterbelgeler: notificationSelector ile belirtilen yöntem, bir ve sadece bir bağımsız değişken (bir örneği olması gerekir NSNotification).
Rudolf Adamkovič

@RudolfAdamkovic Not için teşekkürler - cevabımı buna göre düzenledim.
arexx

8

Evet. Oyuncunun durumuna veya oranına bir KVO gözlemcisi ekleyin:

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

Yani temelde bu kadar.

Feragatname: Bunu buraya yazdım, bu yüzden kodun iyi olup olmadığını kontrol etmedim. AYRICA daha önce hiç AVPlayer kullanmadım ama doğru olmalı.


@ "Rate" gözlemcisi nasıl kaldırılır?
Saumil Shah

Bir düzenlemede oranı kesinlikle gözlemlemem gerektiği söylendi. uyarlanmış
Daij-Djan

4
Bu yaklaşımla ilgili bir sorun, bir duraklamanın müziğin sonu olduğunu düşünmesidir. Duraklamadaki oran, sonunda olacağı gibi sıfırdır.
C6Silver

5

Swift 3 - AVPlayerItemOynatıcıya her video eklediğimde bir gözlemci ekliyorum:

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
}

1

Apple docs AVFoundation Programlama Kılavuzu'nda pek çok bilgi vardır (izleme oynatma bölümüne bakın). Esas olarak KVO aracılığıyla görünüyor, bu yüzden çok aşina değilseniz, bunu tazelemek isteyebilirsiniz ( Anahtar Değer Gözlem Programlama Kılavuzu için bunun için bir rehber vardır .


4
Teşekkürler, önce zamanı KVO aracılığıyla izleyerek çalıştırdım ama sonra daha temiz ve daha az işlemci yoğun olduğu için AVPlayerItemDidPlayToEndTimeNotification'ı uyguladım.
Tyler

1
Biraz çılgın NSNotificationCenter, KVO ve blok tabanlı karışımı. Kararını Apple'a ver!
CupawnTae

1

Bunu kullanıyorum ve işe yarıyor:

_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];

nerede _playingAudiobenim özel sınıf bazı özelliklere sahip olduğunu ve timeObserverbir idivar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.