UICollectionView 中的 AVPlayer

问题描述 投票:0回答:0

我有一个 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")
        }
swift uicollectionview avplayer instagram-reels
© www.soinside.com 2019 - 2024. All rights reserved.