菜鸟教程小白 发表于 2022-12-11 19:23:18

ios - 在 tableview 中平滑加载视频


                                            <p><p>我一直在尝试使用放置在 TableView 单元中的 AVPlayer 将一些视频添加到我的 tableView 中。</p>

<p>但在加载视频时 UI 会卡住。 </p>

<p>这是我在 indexpath 中的 cellforRow。</p>

<pre><code>func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCel {


    var tableCell : UITableViewCell? = nil

    if (tableCell == nil){

      tableCell = tableView.dequeueReusableCell(withIdentifier: &#34;cell&#34;)
    }

    let view = tableCell?.viewWithTag(9999)
    tableCell?.tag = indexPath.row


    DispatchQueue.main.async {
         if (tableCell?.tag == indexPath.row){
                let player = self.cache.object(forKey: indexPath.row as AnyObject) as! AVPlayer
                let playerLayer = AVPlayerLayer(player: player)
                playerLayer.frame = (view?.bounds)!
                view?.layer.addSublayer(playerLayer)
                player.play()

            }

//            tableView.reloadData()
    }

return tableCell!
}
</code></pre>

<p>这就是我将视频添加到缓存的方式。 </p>

<pre><code>    for i in 0...10{

      var videoURL : URL? = nil

      if (i%2 == 0){

            videoURL = URL(string: &#34;https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4&#34;)
      }else{

            videoURL = URL(string: &#34;http://techslides.com/demos/sample-videos/small.mp4&#34;)

      }
      let player = AVPlayer(url: videoURL!)

      arr?.append(player)

      self.cache.setObject(player, forKey: i as AnyObject)
      print(&#34;count = \(arr?.count)&#34;)
    }
</code></pre>

<p>解决此问题的最佳方法是什么?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>谢天谢地,你很幸运。 iOS 仅针对这些类型的问题进行了优化。 Apple 工程师竭尽全力提供 API 来帮助您实现流畅的滚动<em>和</em>同时加载您的内容。</p>

<blockquote>
<p><strong>Note</strong>: Solving this issue <em>requires</em> offloading tasks to differentthreads on the CPU. It can get complicated, and there&#39;s a lot to learn about it. I <em>strongly</em> recommend you read Apple&#39;s documentation.</p>
</blockquote>

<p>首先,要知道<code>cellForRowAtIndexPath:</code> 方法<em>应该</em>一般在主线程上调用你的数据源。这意味着您必须调用 <code>DispatchQueue.main.async</code> 在这种情况下不合适。 </p>

<p>相反,您需要将 <code>AVPlayer</code> 缓存卸载到单独的后台线程,然后返回主线程以<strong>更新</strong>单元格的层内容。此外,您不应该在 <code>cellForRowAtIndexPath:</code> 中这样做。您可能需要子类化一个 <code>UITableViewCell</code> 并在其中编写自己的加载序列 - 这样,您可以快速 <code>init</code> 自定义单元格,将其交还给 <code> cellForRowAtIndexPath:</code>(然后可以愉快地继续),并继续从单元子类中加载和更新。</p>

<p>要在后台线程中设置您的 AVPlayer,请执行以下操作:</p>

<pre><code>DispatchQueue.global(qos: .background).async {
    // Background thread
    // Do your AVPlayer work here

    // When you need to update the UI, switch back out to the main thread
    DispatchQueue.main.async {
      // Main thread
      // Do your UI updates here
    }
}
</code></pre>

<p>您可能希望查看在创建后台线程时传入的服务质量值。对于这种特定情况,<code>userInitiated</code> QOS 可能会更好,因为加载视频是用户启动操作的结果。</p>

<p>至于视频的实际缓存。我对 <code>AVPlayer</code> 或 <code>AVPlayerItem</code> 不是<em>太</em>熟悉,但据我了解,您可以提供更多元数据(即持续时间、轨道等) <code>AVPlayer</code> 在尝试在层中渲染视频之前,它运行得越快(参见这个相关的 <a href="https://stackoverflow.com/a/30376386/814730" rel="noreferrer noopener nofollow">StackOverflow Question</a> )。 </p>

<p>此外,您可能想要查看 iOS 10 中新引入的 API,您可以在表格 View 中<strong>预取</strong>单元格。如果您利用预取优化,您可能会在后台加载 <code>AVPlayer</code> 所需的所有内容,并且在请求单元格显示在 <code>cellForRowAtIndexPath:</code> 之前很久.</p>

<p>无论如何,希望您可以从那里开始并解决问题。一定要花时间阅读关于 <code>AVKit</code>、<code>GCD</code> 和 <code>UITableView</code> 的文档(特别是新的预取 API)。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 在 tableview 中平滑加载视频,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/43118501/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/43118501/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 在 tableview 中平滑加载视频