【问题标题】:Reuse AVPlayer's in TableView在 TableView 中重用 AVPlayer
【发布时间】:2016-11-19 21:16:28
【问题描述】:

任何人都可以帮助创建一个AVPlayer 的池以在 tableView 中重用吗?所以这个想法是拥有一个AVPlayer 的池,比如说3,并在用户滚动表格时继续重用它们。

以下是应用程序的简要概要以及我们想要构建的内容:

  • 每个视频都是 mp4,只有 5 秒长。所以每个单元格都会播放一个 5 秒的视频并循环播放。
  • 所有视频都是本地视频,它们会在表格显示给用户之前下载到磁盘。这将有助于 tableView 的平滑滚动性能。

现在我创建了太多 AVPlayer 并且没有重复使用它们,这对性能产生了不好的影响,例如滚动有点不稳定。此外,Apple 不允许创建无限数量的 AVPlayer

有什么想法吗?谢谢

更新 1:

import UIKit
import VIMVideoPlayer

var cache = NSCache<NSString, VIMVideoPlayerView>()

class FeedTableViewCell: UITableViewCell {
// MARK: - Properties

@IBOutlet weak var containerView: UIView!

static let reuseIdentifier = "FeedTableViewCell"

var video: Video? {
    didSet {
        if let cachedVideoPlayerView = cache.object(forKey: video!.preview!.remoteURL as NSString)  {
            // We have a cached video player view!
            containerView.addSubview(cachedVideoPlayerView)
        } else {
            // There is nothing cached.
            let previewURL = FileManager.applicationDocumentsDirectory.appendingPathComponent(video!.preview!.fileName!)
            let newVideoPlayer = VIMVideoPlayer()
            newVideoPlayer.setURL(previewURL)
            newVideoPlayer.isLooping = true
            newVideoPlayer.isMuted = true
            newVideoPlayer.disableAirplay()

            let newVideoPlayerView = VIMVideoPlayerView()
            newVideoPlayerView.frame = contentView.bounds
            newVideoPlayerView.delegate = self
            newVideoPlayerView.setVideoFillMode(AVLayerVideoGravityResizeAspectFill)
            newVideoPlayerView.player = newVideoPlayer
            containerView.addSubview(newVideoPlayerView)
            cache.setObject(newVideoPlayerView, forKey: video!.preview!.remoteURL as NSString)
        }
    }
}

// MARK: - Life Cycle

override func awakeFromNib() {
    super.awakeFromNib()

    print("AWAKE FROM NIB CELL")
}

override func prepareForReuse() {
    super.prepareForReuse()

}
}

// MARK: - VIMVideoPlayerViewDelegate
extension FeedTableViewCell: VIMVideoPlayerViewDelegate {
func videoPlayerViewIsReady(toPlayVideo videoPlayerView: VIMVideoPlayerView!) {
    videoPlayerView.player.play()
}
}

【问题讨论】:

标签: ios swift avfoundation avplayer avplayerlayer


【解决方案1】:

扩展您使用池的想法,而不是重新发明轮子,为什么不利用UITableViewCell 当前的可重用性实现?在任何给定时间,n 'reusable' UITableViewCells 都存在,充当您的池。

如果这些单元格中的每一个都包含一个AVPlayer 子视图,则管理由表视图为您完成。因此,在UITableViewCell 的重用标识符中,停止播放器(如果需要),更新其 MP4(最好从内存缓存中),然后重新启动。

如果需要,您可以在单元格消失时缓存视频的位置,以使视频在滚动过程中看起来从未停止播放。

-- 附带说明一下,理论上这会起作用,但尚未使用实时应用程序进行测试。明显的警告是在主线程上加载到 AVPlayer 的视频的大小,同时试图保持 60fps。

编辑:

请参阅https://stackoverflow.com/a/35514126/556479 了解更多信息。

【讨论】:

  • 请用一些代码查看我的更新。看起来,根据您的回答,tableView 已经创建了一定数量的AVPlayer,我需要做的是通过用新项目替换当前项目来重用它们——这是正确的吗?另外,在我上面的当前代码中,我似乎没有这样做,我正在做的是多次创建一个新播放器。
  • 顺便说一句,VIMVideoPlayerView 只是 AVPlayer 的包装,它是来自 Vimeo 的库。
  • @JEL 确切地说,不是为每个单元格创建一个新的 VIMVideoPlayerView,而是在每个单元格中实例化一次,并在 prepareForReuse 函数中告诉视图停止。
  • @JEL 请注意,如果video 变量为零,您的代码将会崩溃。你应该确保你在处理这种情况时有警卫/如果让
  • 好的,我想我现在开始更了解这一点了。我仍然感到困惑的是AVPlayer 的可重用性,因为我不知道如何用新视频替换当前视频。这种替换在哪里以及如何完成?你能解释一下这是如何完成的或发布一些示例代码吗?谢谢!
猜你喜欢
  • 2019-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多