我找了一圈,但是我找不到 AVPlayer class
的委托协议。这是怎么回事?
我正在使用它的子类 AVQueuePlayer
,播放从URL加载的AVPlayerItems数组。是否有任何方式可以在歌曲播放完成时调用方法?特别是在队列末尾?
如果不可能,那么是否有任何办法可以在缓冲后歌曲开始播放时调用方法?我试图在那里加入一个加载图标,但即使在 [audioPlayer play]
操作之后,它也会在音乐实际开始之前关闭图标。
我找了一圈,但是我找不到 AVPlayer class
的委托协议。这是怎么回事?
我正在使用它的子类 AVQueuePlayer
,播放从URL加载的AVPlayerItems数组。是否有任何方式可以在歌曲播放完成时调用方法?特别是在队列末尾?
如果不可能,那么是否有任何办法可以在缓冲后歌曲开始播放时调用方法?我试图在那里加入一个加载图标,但即使在 [audioPlayer play]
操作之后,它也会在音乐实际开始之前关闭图标。
是的,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
}
- (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,但应该差不多。
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
}
在苹果文档AVFoundation编程指南中有很多信息(请查找监控播放部分)。它似乎主要通过KVO实现,如果您不太熟悉,可以参考键值观察编程指南进行学习。
_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
是我的自定义类,具有一些属性,timeObserver
是id
实例变量。
itemDidFinishPlaying:
,例如带有冒号。根据NSNotificationCenter
文档:通知选择器指定的方法必须有且仅有一个参数(一个NSNotification
实例)。 - Rudolf Adamkovič