没有AVPlayer代表吗?如何跟踪歌曲播放完毕的时间?目标C iPhone开发


84

我环顾四周,但找不到的委托协议AVPlayer class。是什么赋予了?

我正在使用其子类AVQueuePlayer来播放的数组AVPlayerItems,每个数组都是从URL加载的。歌曲播放完毕后,有什么方法可以调用方法?明显在队列末尾吗?

如果那是不可能的,那么在歌曲开始播放后,缓冲之后,有什么方法可以调用该方法吗?我正在尝试在其中添加一个加载图标,但是即使在[audioPlayer play]操作之后,它也会在音乐真正开始之前将其关闭。

Answers:


152

是的,AVPlayer类没有像AVAudioPlayer这样的委托协议。您需要订阅AVPlayerItem上的通知。您可以使用将-initWithURL:在AVPlayer上传递给的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
}

1
确保使用itemDidFinishPlaying:,例如冒号。根据NSNotificationCenter文档提供:notificationSelector指定的方法必须只有一个参数(的一个实例NSNotification)。
RudolfAdamkovič13年

@RudolfAdamkovic感谢您的注释-我已经相应地编辑了答案。
arexx 2013年

8

是。将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,但是应该是正确的。


如何删除@“ rate”观察者?
Saumil Shah

在编辑中告诉我,必须确定要观察速率。改编
Daij-Djan

4
这种方法的一个问题是它将认为暂停是音乐的结尾。暂停时的费率等于结束时的零。
C6Silver

5

Swift 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

Apple文档《AVFoundation编程指南》中有很多信息(请参阅“监视回放”部分)。它似乎主要是通过KVO进行的,因此,如果您不太熟悉,您可能希望复习一下(有关于Key Value Observing ProgrammingGuide的指南


4
谢谢,首先,我通过通过KVO监视时间使它正常工作,然后我实现了AVPlayerItemDidPlayToEndTimeNotification,因为它更干净且处理器占用更少。
泰勒

1
那里有NSNotificationCenter,KVO和基于块的疯狂组合。下定决心,苹果!
CupawnTae

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我的带有某些属性的自定义类在哪里,并且timeObserveridivar。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.