我使用AVQueuePlayer
循环遍历AVPlayerItems
数组。
我循环它的方式,我听AVPlayerItemDidPlayToEndTimeNotification
,每次调用时,我将当前对象添加到队列的末尾。
继承人代码:
viewWillAppear
{
...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_queuePlayer currentItem]];
[_queuePlayer play];
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
AVPlayerItem *fakeNew = [[AVPlayerItem alloc] initWithAsset:p.asset];
if (_queuePlayer.items.count == 1)
{
[p seekToTime:kCMTimeZero];
[_queuePlayer play];
}
else
{
[_queuePlayer insertItem:fakeNew afterItem:[_queuePlayer.items lastObject]];
}
NSLog(@"array of items to play:%lu", (unsigned long)_queuePlayer.items.count);
}
问题是,该方法仅针对播放的第一个视频调用,之后,该方法停止被调用,因此,例如,如果我在阵列中有2个电影,它将同时播放它们+第一个再次,任何想法为什么会发生这种情况?
更多信息: 还尝试每次制作一个新玩家并将其设置为图层。未能多次发送通知
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
[self.playList removeObjectAtIndex:0];
[self.playList addObject:p];
AVPlayer *newPlayer = [[AVPlayer alloc] initWithPlayerItem:[self.playList objectAtIndex:0]];
_player = newPlayer;
self.AVPlayerLayerView.layer.player = self.player;
[_player play];
}
答案 0 :(得分:1)
经过大量的捣乱,显然无论出于何种原因,视图每次都未注册为观察者,我只是在每次通知后删除并添加了观察者:
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
AVPlayerItem *fakeNewItem = [[AVPlayerItem alloc] initWithAsset:p.asset];
[self.playList removeObjectAtIndex:0];
[self.playList addObject:fakeNewItem];
AVPlayer *newPlayer = [[AVPlayer alloc] initWithPlayerItem:[self.playList objectAtIndex:0]];
_player = newPlayer;
self.AVPlayerLayerView.layer.player = self.player;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_player currentItem]];
[_player play];
}
答案 1 :(得分:0)
有一个干净的方法来解决这个问题。我接下来用下一段代码
首先,您必须添加在复制时间发生变化时从AVPlayer接收反馈所需的代码。
- (void)addPeriodicTimeObserverForReproductionChanges {
@weakify(self);
[self.player
addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(kBQDefaultTimeIntervalReproductionChanges, NSEC_PER_SEC)
queue:self.eventsQueue
usingBlock:^(CMTime time) {
@strongify(self);
[self dispatchBlockOnMainQueue:^{
if ([self.delegate respondsToSelector:@selector(playerItemController:didChangeReproductionTime:)])
[self.delegate playerItemController:self
didChangeReproductionTime:time];
[self checkForItemPlayToEnd];
}];
}];
}
- (void)checkForItemPlayToEnd
{
CMTime durationScaled = CMTimeConvertScale(self.duration,self.player.currentTime.timescale, kCMTimeRoundingMethod_Default);
if (CMTIME_COMPARE_INLINE(durationScaled, ==, self.player.currentTime)) {
[self playerDidFinishReproducingItem];
}
}