在 TableView 中重用 AVPlayer
Reuse AVPlayer's in TableView
任何人都可以帮助创建一个 AVPlayer
的池以在 table 视图中重复使用吗?因此,我们的想法是拥有一个 AVPlayer
的池,比方说 3 个,并在用户滚动浏览 table 时继续重复使用它们。
以下是应用程序的简要介绍以及我们想要构建的内容:
- 每个视频都是mp4,只有5秒长。所以每个单元格将播放一个 5 秒的视频并循环播放。
- 所有视频都是本地的,它们会在 table 显示给用户之前下载到磁盘。这将有助于 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()
}
}
扩展您使用池的想法,而不是重新发明轮子,为什么不利用 UITableViewCell
当前的可重用性实现呢?在任何给定时间,n
'reusable' UITableViewCell
存在,充当您的池。
如果这些单元格中的每一个都包含一个 AVPlayer
子视图,那么管理将由 table 视图为您完成。因此,在 UITableViewCell
的重用标识符中,停止播放器(如果需要),更新其 MP4(最好从内存缓存),然后重新启动。
如果需要,您可以在单元格消失时缓存视频的位置,以便在滚动过程中看起来视频从未停止播放。
-- 作为旁注,理论上这会起作用,但尚未使用实时应用程序进行测试。明显的警告是在主线程上加载到 AVPlayer
的视频的大小,同时试图保持 60fps。
编辑:
请参阅 了解更多信息。
任何人都可以帮助创建一个 AVPlayer
的池以在 table 视图中重复使用吗?因此,我们的想法是拥有一个 AVPlayer
的池,比方说 3 个,并在用户滚动浏览 table 时继续重复使用它们。
以下是应用程序的简要介绍以及我们想要构建的内容:
- 每个视频都是mp4,只有5秒长。所以每个单元格将播放一个 5 秒的视频并循环播放。
- 所有视频都是本地的,它们会在 table 显示给用户之前下载到磁盘。这将有助于 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()
}
}
扩展您使用池的想法,而不是重新发明轮子,为什么不利用 UITableViewCell
当前的可重用性实现呢?在任何给定时间,n
'reusable' UITableViewCell
存在,充当您的池。
如果这些单元格中的每一个都包含一个 AVPlayer
子视图,那么管理将由 table 视图为您完成。因此,在 UITableViewCell
的重用标识符中,停止播放器(如果需要),更新其 MP4(最好从内存缓存),然后重新启动。
如果需要,您可以在单元格消失时缓存视频的位置,以便在滚动过程中看起来视频从未停止播放。
-- 作为旁注,理论上这会起作用,但尚未使用实时应用程序进行测试。明显的警告是在主线程上加载到 AVPlayer
的视频的大小,同时试图保持 60fps。
编辑:
请参阅