我在AVQueuePlayer上度过了一段难忘的时光。很简单,我在一个使用playerItemWithURL构建的AVPlayerItem数组上制作它:并指向网络上服务器上的视频资产。
如果我试图在刺激器(原文如此)中运行这个东西,它会通过第一个资产播放,开始播放第二个资产然后就死了。有时它甚至没有通过第一个资产。
现在,我知道sim的行为与设备不同,所以我也尝试在设备上使用同样的问题。
当我在项目上记录各种状态更改时,我看到缓冲区用完了,播放器就死了。对于一个正在播放项目队列的构造来说,这似乎有点愚蠢...当然缓冲区可能会不足,但为什么它会死掉呢?
我做错了什么,或者这是它应该如何表现?
通过观察loadedTimeRanges属性以及何时将PLAY发送给播放器,我解决了这个问题。但这会导致口吃回放,这也很糟糕。
这是我的代码。有人可以告诉我如何在没有完全播放的情况下执行此操作吗?
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePlayerItemReachedEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.queuePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handlePlayerStalled:) name:AVPlayerItemPlaybackStalledNotification object:self.queuePlayer];
NSString *baseURL = @"http://www.aDomain.com/assets/";
NSMutableArray *vidItemArray = [[NSMutableArray alloc] initWithCapacity:5];
for (int i = 1; i <= 5; i++) {
AVPlayerItem *vid = [AVPlayerItem playerItemWithURL:[NSURL URLWithString:[baseURL stringByAppendingFormat:@"%d.mov", i]]];
[vid addObserver:self forKeyPath:@"status" options:0 context:nil];
[vid addObserver:self forKeyPath:@"playbackBufferEmpty" options:0 context:nil];
[vid addObserver:self forKeyPath:@"loadedTimeRanges" options:0 context:nil];
[vidItemArray addObject:vid];
}
self.queuePlayer = [AVQueuePlayer queuePlayerWithItems:vidItemArray];
[self.mPlaybackView setPlayer:self.queuePlayer];
}
- (void)handlePlayerItemReachedEnd:(NSNotification *)notification {
NSLog(@"Clip #%d finished playing", [self.queuePlayer.items indexOfObject:self.queuePlayer.currentItem]);
}
- (void)handlePlayerStalled:(NSNotification *)notification {
NSLog(@"CLIP STALLED...");
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([object isKindOfClass:[AVPlayerItem class]]) {
AVPlayerItem *item = (AVPlayerItem *)object;
if ([keyPath isEqualToString:@"status"]) {
switch (item.status) {
case AVPlayerItemStatusFailed:
NSLog(@"player item status failed");
break;
case AVPlayerItemStatusReadyToPlay:
NSLog(@"player item status is ready to play");
[self.queuePlayer play];
break;
case AVPlayerItemStatusUnknown:
NSLog(@"player item status is unknown");
break;
}
}
else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) {
if (item.playbackBufferEmpty) {
NSLog(@"player item playback buffer is empty");
}
}
else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
NSLog(@"Loaded time range = %@", item.loadedTimeRanges);
self.queuePlayer play];
}
}
}
答案 0 :(得分:5)
您最初不应向AVPlayerItem
添加许多AVQueuePlayer
,因为它们会在框架自行决定的同时开始缓冲。
尝试加载一个文件,然后在KVO上currentItem
更改了下一个队列,它可能会解决您的问题。我正在使用它来实现无间隙播放。