             if item == self.playerItem {
                 switch keyPath {
                 case "status":
-                    if player?.status == AVPlayerStatus.readyToPlay {
+                    if item.status == .failed || player?.status == AVPlayerStatus.failed {
+                        self.state = .error
+                    } else if player?.status == AVPlayerStatus.readyToPlay {
                         self.state = .buffering
                         if shouldSeekTo != 0 {
                             print("BMPlayerLayer | Should seek to \(shouldSeekTo)")

                            self.hasReadyToPlay = true
                            self.state = .readyToPlay
                        }
                    } else if player?.status == AVPlayerStatus.failed {
                        self.state = .error
                    }
                    
                case "loadedTimeRanges":

    
    // MARK: - 计时器事件
    @objc fileprivate func playerTimerAction() {
        guard let playerItem = playerItem else { return }
        
        if playerItem.duration.timescale != 0 {
            let currentTime = CMTimeGetSeconds(self.player!.currentTime())
            let totalTime   = TimeInterval(playerItem.duration.value) / TimeInterval(playerItem.duration.timescale)
            delegate?.bmPlayer(player: self, playTimeDidChange: currentTime, totalTime: totalTime)
        }
        updateStatus(includeLoading: true)
    }
    
    fileprivate func updateStatus(includeLoading: Bool = false) {
        if let player = player {
            if let playerItem = playerItem, includeLoading {
                if playerItem.isPlaybackLikelyToKeepUp || playerItem.isPlaybackBufferFull {
                    self.state = .bufferFinished
                } else if playerItem.status == .failed {
                    self.state = .error
                } else {
                    self.state = .buffering
                }
            }
            if player.rate == 0.0 {
