Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何处理AVPlayer.avplayerTemplateBackstalled通知_Ios_Swift_Avplayer_Nsnotificationcenter - Fatal编程技术网

Ios 如何处理AVPlayer.avplayerTemplateBackstalled通知

Ios 如何处理AVPlayer.avplayerTemplateBackstalled通知,ios,swift,avplayer,nsnotificationcenter,Ios,Swift,Avplayer,Nsnotificationcenter,我使用的是AVPlayer,有时播放器会随机暂停。我正在观察\.timeControlStatus,但我得到的唯一响应是.paused。我也在观察\。我的播放方式很像Keepup,\。我的播放缓冲区是空的,和\。我的播放缓冲区是满的,但这些都不会触发。然而,使用Notification.Name.avplayerTemplayBackstalled我确实收到一条打印语句,上面写着“stalled” 即使\.rate在播放器暂停时触发,但在.avplayeritemploybackstalled触

我使用的是AVPlayer,有时播放器会随机暂停。我正在观察
\.timeControlStatus
,但我得到的唯一响应是
.paused
。我也在观察
\。我的播放方式很像Keepup
\。我的播放缓冲区是空的
,和
\。我的播放缓冲区是满的
,但这些都不会触发。然而,使用
Notification.Name.avplayerTemplayBackstalled
我确实收到一条打印语句,上面写着“stalled”

即使
\.rate
在播放器暂停时触发,但在
.avplayeritemploybackstalled
触发之前触发,有时
\.timeControlStatus.pause
.avplayeritemploybackstalled
之后触发,播放器就坐在那里

.avplayerTemplayBackstalled
运行且播放器暂停时,我该怎么办

NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemPlaybackStalled(_:)),
                                               name: NSNotification.Name.AVPlayerItemPlaybackStalled,
                                               object: playerItem)

@objc fileprivate func playerItemPlaybackStalled(_ notification: Notification) {
    print("playerItemPlaybackStalled")
}
这是我的全部代码:

let player = AVPlayer()
player.automaticallyWaitsToMinimizeStalling = false
playerLayer = AVPlayerLayer(player: player)
playerLayer?.videoGravity = AVLayerVideoGravity.resizeAspect
// add KVO observers and NotificationCenter observers
// playerItem keys are already loaded
playerItem.preferredForwardBufferDuration = TimeInterval(1.0)
player.replaceCurrentItem(with: playerItem)


playerStatusObserver = player?.observe(\.currentItem?.status, options: [.new, .old]) { [weak self] (player, change) in
        
    switch (player.status) {
    case .readyToPlay:
        DispatchQueue.main.async {
            // play video
        }
    case .failed, .unknown:
        print("Video Failed to Play")
    @unknown default:
        break
    }
}
    
playerRateObserver = player?.observe(\.rate, options:  [.new, .old], changeHandler: { [weak self](player, change) in

    if player.rate == 1  {
        DispatchQueue.main.async {
            // if player isn't playing play it
        }
    } else {
        DispatchQueue.main.async {
           // is player is playing pause it
        }
    }
})
    
playerTimeControlStatusObserver = player?.observe(\.timeControlStatus, options: [.new, .old]) { [weak self](player, change) in
        
    switch (player.timeControlStatus) {
    case .playing:
            DispatchQueue.main.async { [weak self] in
                // if player isn't playing pay it
            }
    case .paused:
            print("timeControlStatus is paused") // *** SOMETIMES PRINTS after .AVPlayerItemPlaybackStalled runs***

    case .waitingToPlayAtSpecifiedRate:
            print("timeControlStatus- .waitingToPlayAtSpecifiedRate")

    if let reason = player.reasonForWaitingToPlay {
                
            switch reason {
            case .evaluatingBufferingRate:
                    print("timeControlStatus- .evaluatingBufferingRate") // never prints
                    
            case .toMinimizeStalls:
                    print("timeControlStatus- .toMinimizeStalls") // never prints
                    
            case .noItemToPlay:
                    print("timeControlStatus- .noItemToPlay") // never prints
                    
            default:
                    print("Unknown \(reason)")
            }
        }
    @unknown default:
        break
    }
}
    
playbackLikelyToKeepUpObserver = player?.currentItem?.observe(\.isPlaybackLikelyToKeepUp, options: [.old, .new]) {  (playerItem, change) in
    print("isPlaybackLikelyToKeepUp") // never prints
}
    
playbackBufferEmptyObserver = player?.currentItem?.observe(\.isPlaybackBufferEmpty, options: [.old, .new]) { (playerItem, change) in
    print("isPlaybackBufferEmpty") // never prints
}
    
playbackBufferFullObserver = player?.currentItem?.observe(\.isPlaybackBufferFull, options: [.old, .new]) { (playerItem, change) in
    print("isPlaybackBufferFull") // never prints
}
    
NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemDidReachEnd(_:)),
                                               name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                                               object: playerItem)

NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemFailedToPlayToEndTime(_:)),
                                           name: .AVPlayerItemFailedToPlayToEndTime,
                                           object: playerItem)
    
    
NotificationCenter.default.addObserver(self, selector: #selector(playerItemNewError(_:)),
                                           name: .AVPlayerItemNewErrorLogEntry,
                                           object: playerItem)

NotificationCenter.default.addObserver(self, selector: #selector(self.playerItemPlaybackStalled(_:)),
                                           name: NSNotification.Name.AVPlayerItemPlaybackStalled,
                                           object: playerItem)

@objc func playerItemDidReachEnd(_ notification: Notification) {
    // show replay button
}

@objc func playerItemFailedToPlayToEndTime(_ notification: Notification) {
    print("playerItemFailedToPlayToEndTime") // never prints

    if let error = notification.userInfo?["AVPlayerItemFailedToPlayToEndTime"] as? Error {
        print(error.localizedDescription) // never prints
    }
}

@objc func playerItemNewError(_ notification: Notification) {
    print("playerItemNewErrorLogEntry") // never prints
}

@objc func playerItemPlaybackStalled(_ notification: Notification) {
    print("playerItemPlaybackStalled") // *** PRINTS ***
}

我找到了那个。基本上,在暂停的通知中,我检查缓冲区是否已满。如果没有,我从链接运行代码。

我找到了。基本上,在暂停的通知中,我检查缓冲区是否已满。如果没有,我将从链接运行代码。

@matt顺便说一句,谢谢你的建议,我将设置一个活动指示器,并且不会触摸播放器。@matt它一直在发生,问题是之后没有发生任何事情,这意味着没有其他观察者或通知被调用。视频只有15秒,大约5秒后就冻结了,我让它停了5分钟,期待着会发生什么,但是娜达。如果它试图填充缓冲区,它不应该在5分钟内被填充,然后其他方法之一被触发吗?嗯,我想我错了。我不知道为什么视频会在5秒钟后暂停,可能需要更多信息。我也不太明白为什么你要将
自动等待最小化设置为
false
,这类设置有违目的。我添加了automaticallywaitstominimimizestalling=false,认为这可能会帮助它播放得更快。你说它违背目的是什么意思?我来评论一下,看看摊位是否还在occurs@matt顺便说一句,谢谢你的建议,我会挂一个活动指示器,不会碰播放器。@matt它一直在发生,问题是之后什么也没有发生,这意味着没有其他观察员或通知被呼叫。视频只有15秒,大约5秒后就冻结了,我让它停了5分钟,期待着会发生什么,但是娜达。如果它试图填充缓冲区,它不应该在5分钟内被填充,然后其他方法之一被触发吗?嗯,我想我错了。我不知道为什么视频会在5秒钟后暂停,可能需要更多信息。我也不太明白为什么你要将
自动等待最小化设置为
false
,这类设置有违目的。我添加了automaticallywaitstominimimizestalling=false,认为这可能会帮助它播放得更快。你说它违背目的是什么意思?我将对它进行注释,看看是否仍然出现失速