在uitableview单元中播放视频 [英] playing video in uitableview cell

查看:111
本文介绍了在uitableview单元中播放视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置一个可以播放视频的UITableView.与此相关的许多以前的SO问题都使用了MPMoviePlayer(将视频播放到UITableView 在SWIFT的UItableView中播放视频在完全可见的情况下在UITableViewCell上播放视频,这是我从中获取大部分代码的地方.这是我的代码,位于cellForRowAtIndexPath内部:

I am trying to setup a UITableView that can play videos. Many of the previous SO questions on this used MPMoviePlayer(Playing Video into UITableView, Playing video in UItableView in SWIFT, Playing Video From UITableView), which is now deprecated in iOS 9. One of the few that used AVFoundation (what i'm using), is this one: Play video on UITableViewCell when it is completely visible and is where I'm getting most of my code from. Here is my code, inside 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;

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

From what I understand, I need to asynchronously download the videos before I play them. I've asynchronously downloaded images before, and the "download" part of that always involves converting NSURL -> NSData -> UIImage. And then when you have the UIImage, you're ready to display it in the cell, so you bring the main queue up and dispatch_async and perform the cell.imageView.image = yourImage; on the main queue.

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

Here, I have an NSURL, but I don't quite get which steps here should be on the main queue and which should be off the main thread. I tried what was suggested in the aforementioned SO question, but so far it isn't working. The table cell just loads, and the video never plays. I just see the first frame. Sometimes the first 1 second of it will play, but then it buffers after that and won't. I'm working with a table view that has only 1 object right now, so there is just 1 video to play, and it still isn't playing.

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

What am I doing wrong, and could someone help me explain exactly which parts need to be on the main thread and which off? A responder in the thread I mentioned at the top said there were "lots of tutorials on this out there," but upon scanning google I didn't see any. the terms "asynchronous" and "iOS" together almost always get search results about image downloading, not video. But if any tutorials exist it would be nice to see one.

谢谢

推荐答案

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

The following is the method that I have used to play video in the tableview cells. I'm not sure it is the best method for this, anyway it may help you :)

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

First I have created a custom cell. In the setter method I called a method to set 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];

}

我发现在您的代码中,您已经编写了b播放功能,例如[videoCell.player play];

I have found that in your code you have written theb play function like this [videoCell.player play];

仅当播放器状态变为"AVPlayerStatusReadyToPlay"时,才应调用播放功能.这就是为什么我使用KVO的原因.

You should call the play function only when the player state becomes 'AVPlayerStatusReadyToPlay'. Thats why I used KVOs.

希望这可能对您有所帮助:)

Hope this may helps you :)

这篇关于在uitableview单元中播放视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆