首页 文章

UITableViewCell中的AVPlayer.play()会暂时阻止UI

提问于
浏览
5

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

问题是当在tableView上滚动时,只要加载视频单元,UI就会冻结一小部分,这使得应用看起来很笨重 . 当一行中有多个视频单元时,这种效果会变得更糟 . 任何想法和帮助将不胜感激

TableView Code:

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
}

Custom Cell Observer Code

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块 .

我可以做些什么来获得丝滑流畅的视频播放和Instagram的滚动?

1 回答

  • 4

    Another Update 强烈推荐使用Facebook 's Async Display Kit ASVideoNode as a drop in replacement for AVPlayer. You' ll在加载和播放视频时获得丝滑的Instagram桌面视频效果 . 我认为AVPlayer在主线程上运行一些进程,并且's no way to get around them cause it'发生在相对较低的级别 .

    Update: Solved

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

    假设是没有办法避免视频花费一定的时间加载主线程(除非你是Instagram并且你拥有一些AsyncDisplayKit魔法,但我不想做那个跳转),所以相反尝试删除UI块,尝试隐藏它 .

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

    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 .

    if(!isScrolling && cell.videoPlayer == nil){
    
        //Load video cell here
    }
    

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

    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 . 希望这有帮助,如果您有任何具体问题或者我所描述的内容不清楚,请告诉我 .

相关问题