我有一个 Swift 应用程序,它有一个类似于社交媒体应用程序卷轴的视频列表。 我在 UICollectionView 中使用带有 HLS 格式视频的 AVplayer。 我有两个问题:
缓冲总是很慢,即使在为接下来的 4 个单元格实施预加载后也是如此。
在滚动大约 20 个视频后,缓冲区冻结并且播放器在所有视频上停顿了大约 20 秒,然后它开始工作,在更多 20 个视频之后问题发生了,每次停顿时我都会在控制台上收到此错误发生:
[27944:5390492] [connection] nw_connection_copy_connected_local_endpoint_block_invoke [C60] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection
[27944:5390492] [connection] nw_connection_copy_connected_remote_endpoint_block_invoke [C60] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection
[27944:5390492] [connection] nw_connection_copy_protocol_metadata_internal_block_invoke [C60] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection
[27944:5390492] [connection] nw_connection_copy_connected_local_endpoint_block_invoke [C61] Client called nw_connection_copy_connected_local_endpoint on unconnected nw_connection
[27944:5390492] [connection] nw_connection_copy_connected_remote_endpoint_block_invoke [C61] Client called nw_connection_copy_connected_remote_endpoint on unconnected nw_connection
[27944:5390492] [connection] nw_connection_copy_protocol_metadata_internal_block_invoke [C61] Client called nw_connection_copy_protocol_metadata_internal on unconnected nw_connection
这是WillDisplay函数中preload的逻辑
for section in 0..<collectionView.numberOfSections {
for i in indexPath.item ... indexPath.item + 4 {
let indexPath = IndexPath(item: i, section: section)
if indexPath.item >= 0,
indexPath.item < reelsArray.count,
!SharedManager.shared.players.contains(where: {$0.id == reelsArray[indexPath.item].id ?? ""}) ,
let urlString = reelsArray[indexPath.item].media,
let videoURL = URL(string: urlString) {
let asset = AVAsset(url: videoURL)
let playerItem = AVPlayerItem(asset: asset)
playerItem.preferredMaximumResolution = CGSize(width: 426, height: 240)
playerItem.preferredPeakBitRate = Double(200000)
playerItem.preferredForwardBufferDuration = 3
let player = NRPlayer(playerItem: playerItem)
player.automaticallyWaitsToMinimizeStalling = false
let playerPreload = PlayerPreloadModel(index: indexPath.item, timeCreated: Date(), id: reelsArray[indexPath.item].id ?? "", player: player)
SharedManager.shared.players.append(playerPreload)
}
}
}
这里是单元格中的播放函数
setImage()
let asset = AVAsset(url: url)
let playerItem = AVPlayerItem(asset: asset)
playerLayer.player?.automaticallyWaitsToMinimizeStalling = false
playerItem.preferredMaximumResolution = CGSize(width: 426, height: 240)
playerItem.preferredPeakBitRate = Double(200000)
playerItem.preferredForwardBufferDuration = 3
let player = NRPlayer(playerItem: playerItem)
playerLayer = AVPlayerLayer(player: player)
playerLayer.player?.currentItem?.addObserver(self, forKeyPath: #keyPath(AVPlayerItem.status), options: NSKeyValueObservingOptions.new, context: nil)
playerContainer.layer.addSublayer(playerLayer)
playerLayer.frame = playerContainer.bounds
playerContainer.backgroundColor = .clear
playerLayer.videoGravity = .resize
playerContainer.layer.masksToBounds = true
playerLayer.masksToBounds = true
NotificationCenter.default.addObserver(self, selector: #selector(videoDidEnded), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerLayer.player?.currentItem)
playerLayer.player?.addObserver(self, forKeyPath: "timeControlStatus", options: NSKeyValueObservingOptions.new, context: nil)
playerLayer.player?.play()
imgThumbnailView.layoutIfNeeded()
if SharedManager.shared.isAudioEnableReels == false {
playerLayer.player?.volume = 0
imgSound.image = UIImage(named: "newMuteIC")
} else {
playerLayer.player?.volume = 1
imgSound.image = UIImage(named: "newUnmuteIC")
}