2011-07-26 74 views
76

我環顧四周,但我找不到AVPlayer class的代理協議。是什麼賦予了?沒有AVPlayer代表?如何追蹤歌曲播放完畢? Objective C iPhone開發

我使用它的子類AVQueuePlayer來播放從URL加載的數組AVPlayerItems。當歌曲結束播放時,有什麼方法可以調用方法嗎?值得注意的是在隊列的最後?

如果這是不可能的,有什麼辦法,我可以調用一個方法,當歌曲開始播放,緩衝後?我試圖在那裏獲得一個加載圖標,但是在音樂實際開始之前它會關閉圖標,即使它在[audioPlayer play]操作之後。

回答

1

Apple文檔AVFoundation Programming Guide(查找監控回放部分)中有很多信息。這似乎主要是通過KVO,所以你可能希望刷新,如果你不太熟悉(有一個指南Key Value Observing ProgrammingGuide

+4

謝謝,首先我把它通過監測通過志願的時間工作,但隨後我實現了AVPlayerItemDidPlayToEndTimeNotification因爲它更乾淨,處理器密集度更低。 – Tyler

+0

有點瘋狂的NSNotificationCenter,KVO和基於塊的組合。讓你的頭腦開始蘋果! – CupawnTae

7

是的。添加一個KVO觀察員的球員的狀態或率:

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

因此,基本上,這是它

免責聲明:我寫的是,在這裏,所以我沒有檢查,如果代碼是好的我也從來沒有使用過AVPlayer之前,但它應該是有關的權利

+0

@downvoter:請發表評論 –

+0

如何刪除@「rate」observer? –

+0

我在編輯中被告知我需要確認速度。改編 –

141

是的,AVPlayer類沒有委託協議,如AVAudioPlayer。您需要訂閱AVPlayerItem上的通知。您可以使用相同的URL創建AVPlayerItem,否則您將在AVPlayer上傳遞至-initWithURL:

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

這很好,但不處理暫停。 –

+1

請務必使用'itemDidFinishPlaying:',例如與冒號。從'NSNotificationCenter'文檔中:_ notificationSelector指定的方法必須只有一個參數('NSNotification'的一個實例)._ –

+0

@RudolfAdamkovic感謝您的提示 - 我已經編輯了相應的答案。 – arexx

1

我用這一個,和它的作品:

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

其中_playingAudio是我的自定義類的一些屬性和timeObserverid伊娃。

1

斯威夫特3 - 每次我的視頻添加到播放時添加觀察員AVPlayerItem

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

非常感謝,先生。對我來說這個技巧的答案是:-) –

相關問題