首页 文章

AVQueuePlayer挫折(缓冲区欠载处理)

提问于
浏览
3

我和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];
        }
    }
}

1 回答

  • 5

    您最初不应该添加许多 AVPlayerItem ,因为它们将在框架的自由裁量权的同时开始缓冲 .

    尝试加载一个文件,然后在KVO currentItem 上更改了下一个队列,它可能会解决您的问题 . 我用它来实现无间隙播放 .

相关问题