87

我环顾四周,但找不到AVPlayer class. 是什么赋予了?

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

如果这不可能,有什么办法可以在歌曲开始播放时调用方法,缓冲后?我试图在那里获得一个加载图标,但它会在音乐实际开始之前关闭图标,即使它是在[audioPlayer play]动作之后。

4

5 回答 5

153

是的,AVPlayer 类没有像 AVAudioPlayer 这样的委托协议。您需要订阅 AVPlayerItem 上的通知。您可以使用在 AVPlayer 上传递给的相同 URL 创建-initWithURL: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
}
于 2012-09-26T15:29:13.520 回答
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,但它应该是正确的。

于 2012-09-16T13:47:45.173 回答
6

Swift 3AVPlayerItem -每次向播放器添加视频时,我都会添加一个观察者:

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
}
于 2017-04-28T06:04:35.977 回答
1

Apple docs AVFoundation Programming Guide中有很多信息(查找监控回放部分)。它似乎主要是通过 KVO 实现的,所以如果您不太熟悉,可能希望复习一下(有一个关于Key Value Observing ProgrammingGuide的指南。

于 2011-07-27T13:23:50.730 回答
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。

于 2013-10-31T19:52:32.253 回答