我的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)
}
请让我知道这里出了什么问题。 还是还有其他方法可以区分视频是否包含音频?
答案 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)