web-dev-qa-db-ja.com

AVPlayerデリゲートなし?曲の再生が終了したときを追跡する方法は?客観的なC iPhone開発

見回しましたが、AVPlayer classのデリゲートプロトコルが見つかりません。何が得られますか?

サブクラスAVQueuePlayerを使用して、それぞれURLからロードされたAVPlayerItemsの配列を再生しています。曲の再生が終了したときにメソッドを呼び出す方法はありますか?特にキューの最後に?

それが不可能な場合、曲がバッファリングした後に再生を開始するときにメソッドを呼び出す方法はありますか?読み込み中のアイコンを取得しようとしていますが、[audioPlayer play]アクションの後であっても、実際に音楽が始まる前にアイコンをオフにします。

83
Tyler

はい、AVPlayerクラスにはAVAudioPlayerのようなデリゲートプロトコルはありません。 AVPlayerItemの通知をサブスクライブする必要があります。通常はAVPlayerの-initWithURL:に渡すのと同じURLを使用して、AVPlayerItemを作成できます。

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

はい。 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を使用したことはありませんが、ほぼ正しいはずです。

8
Daij-Djan

Swift-プレーヤーにビデオを追加するたびに、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
}
5
budidino

Apple docs AVFoundation Programming Guide (モニタリング再生セクションを探してください)には多くの情報があります。主にKVOを使用しているようです。あまり慣れていない場合は、その上にブラッシュアップします(そのためのガイドがあります Key Value Observing ProgrammingGuide

1
Paul.s

私はこれを使用していますが、動作します:

_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 ivarです。

1
Timur Mustafaev