滚动时UICollectionView卡住

时间:2019-07-19 05:37:21

标签: ios swift uicollectionview avplayer

我的collectionView单元格中有一些视频。我正在从URL提取它们,并使用AVPlayer对其进行播放。

一切正常。但是,根据视频是否包含音频,有必要显示静音/取消静音图标。

为了检查视频是否包含音频,我使用了以下代码:

(self.player?.currentItem?.asset.tracks.filter({$0.mediaType == AVMediaType.audio}).count != 0)

我是从How to check if AVPlayer has Video or just Audio?

那里得到的

添加此代码后,滚动视图时,我的collectionView第一次卡住。

我从单元格的 init 调用它。 尝试在后台线程上执行该操作,但仍然出现问题。

DispatchQueue.global(qos: .background).async {
    let isAudioAvailable = (self.player?.currentItem?.asset.tracks.filter({$0.mediaType == AVMediaType.audio}).count != 0)
    DispatchQueue.main.async {
        self.audioIconButton.isHidden = !isAudioAvailable
        self.player?.isMuted = isMuted
        let image = isMuted ? #imageLiteral(resourceName: "Mute_Icon") : #imageLiteral(resourceName: "Unmute_Icon")
        self.audioIconButton.setImage(image, for: .normal)
    })
}

要从URL获取的代码:

func getAVPlayerFromUrl(view: UIView) -> AVPlayer? {
    let size: CGSize = view.bounds.size.applying(CGAffineTransform(scaleX: UIScreen.main.scale, y: UIScreen.main.scale))
    guard let url = URL(string: AppConfig.shared.appConfig.video_buckets.videoURL(for: self, size: size)) else { return nil }

    let videoAsset = AVURLAsset(url: url)
    videoAsset.loadValuesAsynchronously(forKeys: ["playable"])
    let playerItem: AVPlayerItem = AVPlayerItem(asset: videoAsset)
    return AVPlayer(playerItem: playerItem)
}

请让我知道这里出了什么问题。 还是还有其他方法可以区分视频是否包含音频?

1 个答案:

答案 0 :(得分:1)

这里的想法是缓存加载asset时的计数,而不是加载cell

因此,提取逻辑将更改为类似于下面的代码

func getAVPlayerFromUrl(view: UIView, cellIndex: Int) -> AVPlayer? {
    let size: CGSize = view.bounds.size.applying(CGAffineTransform(scaleX: UIScreen.main.scale, y: UIScreen.main.scale))
    guard let url = URL(string: AppConfig.shared.appConfig.video_buckets.videoURL(for: self, size: size)) else { return nil }

    let videoAsset = AVURLAsset(url: url)
    videoAsset.loadValuesAsynchronously(forKeys: ["playable"]) {
        // Here audioCount is the dict we are using to save the count and cellIndex is the index of the cell in collectionview
        self.audioCount[cellIndex] = videoAsset.tracks.filter({$0.mediaType == AVMediaType.audio}).count
    }
    let playerItem: AVPlayerItem = AVPlayerItem(asset: videoAsset)
    return AVPlayer(playerItem: playerItem)
}

最后像

一样使用它
let isAudioAvailable = (self.audioCount[index] != 0)
self.audioIconButton.isHidden = !isAudioAvailable
self.player?.isMuted = isMuted
let image = isMuted ? #imageLiteral(resourceName: "Mute_Icon") : #imageLiteral(resourceName: "Unmute_Icon")
self.audioIconButton.setImage(image, for: .normal)