在uitableview单元中播放视频

joe*_*oey 5 avfoundation uitableview ios

我正在尝试设置一个可以播放视频的UITableView。许多在此使用MPMoviePlayer(以前做题播放视频到UITableView的在SWIFT播放视频的UITableView播放视频从UITableView的),现在已不建议在iOS版9为数不多的以使用过AVFoundation(什么我使用),是这样的:当UITableViewCell完全可见并且是我从中获取大部分代码的地方时,播放视频。这是我的代码,位于cellForRowAtIndexPath内部:

 VideoCell *videoCell = (VideoCell *)[self.tableView dequeueReusableCellWithIdentifier:@"VideoCell"];

        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
        NSURL *url = [[NSURL alloc] initWithString:urlString];

        dispatch_async(queue, ^{
        videoCell.item = [AVPlayerItem playerItemWithURL:url];

            dispatch_sync(dispatch_get_main_queue(), ^{
                videoCell.player = [[AVPlayer alloc] initWithPlayerItem:videoCell.item];
                videoCell.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;

                AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:videoCell.player];
                playerLayer.frame = CGRectMake(0, 0, videoCell.contentView.frame.size.width, videoCell.contentView.frame.size.height);
                [videoCell.contentView.layer addSublayer:playerLayer];
                playerLayer.videoGravity = AVLayerVideoGravityResize;
                [videoCell.player play];

            });
        });


        return videoCell;
Run Code Online (Sandbox Code Playgroud)

据我了解,在播放视频之前,我需要异步下载视频。我以前异步下载图像,其中的“下载”部分始终涉及转换NSURL-> NSData-> UIImage。然后,当您拥有UIImage时,就可以在单元格中显示它了,因此可以调出主队列和dispatch_async并执行单元格。在主队列上。

在这里,我有一个NSURL,但是我不太明白这里的哪些步骤应该在主队列中,哪些应该不在主线程中。我尝试了前面提到的SO问题中提出的建议,但到目前为止它没有用。表格单元格刚刚加载,视频从不播放。我只看到第一帧。有时它的前1秒会播放,但随后会缓冲,不会播放。我正在使用一个只有1个对象的表视图,因此只有1个视频要播放,但仍然没有播放。

我在做什么错,有人可以帮助我确切说明哪些部分需要在主线程上,哪些需要关闭?我在顶部提到的线程中的响应者说,“那里有很多教程”,但是在扫描google时我没有看到任何内容。“异步”和“ iOS”这两个词几乎总是会获得有关图片下载而非视频的搜索结果。但是,如果有任何教程,那么很高兴看到它。

谢谢

Vis*_*. S 3

以下是我用来在表格视图单元格中播放视频的方法。我不确定这是最好的方法,无论如何它可能会帮助你:)

首先,我创建了一个自定义单元格。在setter方法中我调用了一个方法来设置AVPlayer。

- (void)setUpAVPlayer
{
    @try {
        self.videoPlayer = [[AVPlayer alloc]initWithPlayerItem:self.videoPlayerItem];
    }
    @catch (NSException *exception) {
        NSLog(@"Exception : %@",exception.description);
        [self.videoPlayer replaceCurrentItemWithPlayerItem:self.videoPlayerItem];
    }


    // Setting player properties.
    playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.videoPlayer];
    playerLayer.videoGravity = AVLayerVideoGravityResize;
    [self.previewImageView.layer addSublayer:playerLayer];
    self.previewImageView.clipsToBounds = YES;
    playerLayer.hidden = YES;

    [playerLayer addObserver:self forKeyPath:@"readyForDisplay" options:0 context:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(pauseAllRunningPlayers) name:@"pause" object:nil];


    // AVPlayer KVO

    [self.videoPlayer addObserver:self forKeyPath:@"rate"                            options:NSKeyValueObservingOptionNew context:kRateDidChangeKVO];
    [self.videoPlayer addObserver:self forKeyPath:@"currentItem.status"              options:NSKeyValueObservingOptionNew context:kStatusDidChangeKVO];
    [self.videoPlayer addObserver:self forKeyPath:@"currentItem.duration"            options:NSKeyValueObservingOptionNew context:kDurationDidChangeKVO];
    [self.videoPlayer addObserver:self forKeyPath:@"currentItem.loadedTimeRanges"    options:NSKeyValueObservingOptionNew context:kTimeRangesKVO];
    [self.videoPlayer addObserver:self forKeyPath:@"currentItem.playbackBufferFull"  options:NSKeyValueObservingOptionNew context:kBufferFullKVO];
    [self.videoPlayer addObserver:self forKeyPath:@"currentItem.playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:kBufferEmptyKVO];
    [self.videoPlayer addObserver:self forKeyPath:@"currentItem.error"               options:NSKeyValueObservingOptionNew context:kDidFailKVO];

    [videoLoadingIndicator stopAnimating];

}
Run Code Online (Sandbox Code Playgroud)

我发现在你的代码中你写了这样的播放函数[videoCell.player play];

仅当播放器状态变为“AVPlayerStatusReadyToPlay”时才应调用播放函数。这就是我使用 KVO 的原因。

希望这可以帮助你:)