UITableViewCell中的AVPlayer.play()短暂地阻止了UI [英] AVPlayer.play() in UITableViewCell briefly blocks UI

查看:125
本文介绍了UITableViewCell中的AVPlayer.play()短暂地阻止了UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将内联视频添加到我的UITableViewCells中,例如Instagram,Twitter,Vine等.我正在使用AVPlayerController和自定义单元格使用本地视频文件测试UI(请参见下面的示例代码).我等待AVPlayer的状态为ReadyToPlay,然后播放视频.

I’m trying add inline videos to my UITableViewCells a la Instagram, Twitter, Vine…etc. I’m testing out the UI with a local video file using AVPlayerController and a custom cell (see sample code below). I wait for the status of the AVPlayer to be ReadyToPlay and then play the video.

问题是,当在tableView上滚动时,每当加载视频单元时,UI就会冻结一部分的小节,这会使该应用显得笨拙.当连续有多个视频单元时,这种效果会更糟.任何想法和帮助将不胜感激

The issue is that when scrolling on the tableView the UI freezes for a fraction of section whenever a video cell is loaded which makes the app seem clunky. This effect is made worse when there are multiple video cells in a row. Any thoughts and help would be greatly appreciated

TableView代码:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

     let cell = tableView.dequeueReusableCellWithIdentifier("videoCell", forIndexPath: indexPath) as! CustomCell

     //Set up video player if cell doesn't already have one
     if(cell.videoPlayerController == nil){
         cell.videoPlayerController = AVPlayerViewController()
         cell.videoPlayerController.view.frame.size.width = cell.mediaView.frame.width
         cell.videoPlayerController.view.frame.size.height = cell.mediaView.frame.height 
         cell.videoPlayerController.view.center = cell.mediaView.center
         cell.mediaView.addSubview(cell.videoPlayerController.view) 
     }

     //Remove old observers on cell.videoPlayer if they exist
     if(cell.videoObserverSet){
         cell.videoPlayer.removeObserver(cell, forKeyPath: "status")
     }


     let localVideoUrl: NSURL = NSBundle.mainBundle().URLForResource("videoTest", withExtension: "m4v")!
     cell.videoPlayer = AVPlayer(URL:localVideoUrl)
     cell.videoPlayer.addObserver(cell, forKeyPath:"status", options:NSKeyValueObservingOptions.New, context = nil)
     cell.videoObserverSet = true         

     cell.videoPlayerController.player = cell.videoPlayer


     return cell
}

自定义单元观察者代码:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {

    if(keyPath=="status"){
        print("status changed on cell video!");

        if(self.videoPlayer.status == AVPlayerStatus.ReadyToPlay){

            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.videoPlayer.play()
            })
        }
    }
}

我还尝试使用loadValuesAsynchronouslyForKeys(["playable"])加载视频的AVAsset版本,但这对UI块也无济于事.

I also tried loading an AVAsset version of the video using the loadValuesAsynchronouslyForKeys(["playable"]) but that didn't help with the UI block either.

我该怎么做才能像Instagram一样流畅地播放和滚动视频?

What can I do to get the silky smooth video playback and scrolling of Instagram?

推荐答案

另一个更新 强烈建议使用Facebook的Async Display Kit ASVideoNode作为AVPlayer的替代品.在加载和播放视频时,您将获得如丝般流畅的Instagram tableview性能.我认为AVPlayer在主线程上运行一些进程,由于它发生在相对较低的级别,因此无法绕开它们.

Another Update Highly recommend using Facebook's Async Display Kit ASVideoNode as a drop in replacement for AVPlayer. You'll get the silky smooth Instagram tableview performance while loading and playing videos. I think AVPlayer runs a few processes on the main thread and there's no way to get around them cause it's happening at a relatively low level.

更新:已解决

我无法直接解决该问题,但是我习惯了一些技巧和假设并获得了想要的性能.

I wasn't able to directly tackle the issue, but I used to some tricks and assumptions and to get the performance I wanted.

假设是无法避免视频花费一定时间加载到主线程上(除非您是instagram并且拥有一些AsyncDisplayKit的魔力,但我不想跳该跳) ,因此与其尝试删除UI块,不如尝试将其隐藏.

The assumption was that there's no way to avoid the video taking a certain amount of time to load on the main thread (unless you're instagram and you possess some AsyncDisplayKit magic, but I didn't want to make that jump), so instead of trying to remove the UI block, try to hide it instead.

我通过在tableView上执行一个简单的 isScrolling 检查来隐藏UIBlock

I hid the UIBlock by implementing a simple isScrolling check on on my tableView

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {

    if(self.isScrolling){
        if(!decelerate){
            self.isScrolling = false
            self.tableView.reloadData()
        }
    }
}

func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

    if(self.isScrolling){
        self.isScrolling = false
        self.tableView.reloadData()
    }
}

func scrollViewWillBeginDragging(scrollView: UIScrollView) {
    self.isScrolling = true
}

然后确保在滚动tableView或已经播放视频时不要加载视频单元,并在滚动停止时重新加载tableView.

And then just made sure not to load the video cells when tableView is scrolling or a video is already playing, and reload the the tableView when the scrolling stops.

if(!isScrolling && cell.videoPlayer == nil){

    //Load video cell here
}

但是请确保删除videoPlayer,并在videoCell不再出现在屏幕上后停止收听重播通知.

But make sure to remove the videoPlayer, and stop listening to replay notifications once the videoCell is not on the screen anymore.

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    if(tableView.indexPathsForVisibleRows?.indexOf(indexPath) == nil){

        if (cell.videoPlayer != nil && murmur.video_url != nil){

            if(cell.videoPlayer.rate != 0){

                cell.videoPlayer.removeObserver(cell, forKeyPath: "status")
                cell.videoPlayer = nil;
                cell.videoPlayerController.view.alpha = 0;
            }
        }
    }
}

通过这些更改,我能够一次在屏幕上显示多个(2)视频单元,从而获得一个平滑的UI.希望这对您有所帮助,并让我知道您是否有任何具体问题,或者我所描述的内容不清楚.

With these changes I was able to achieve a smooth UI with multiple (2) video cells on the screen at a time. Hope this helps and let me know if you have any specific questions or if what I described wasn't clear.

这篇关于UITableViewCell中的AVPlayer.play()短暂地阻止了UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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