                            forKeyPath: #keyPath(AVPlayer.currentItem),
                            options: [.initial, .new, .old],
                            context: nil)
-        NotificationCenter.default.addObserver(
-            self,
-            selector: #selector(SystemPlayerObserver.didPlayToEnd(notification:)),
-            name: Notification.Name.AVPlayerItemDidPlayToEndTime,
-            object: player.currentItem)
     }
     
     func didPlayToEnd(notification: NSNotification) {

                              forKeyPath: #keyPath(AVPlayer.currentItem))
        NotificationCenter.default.removeObserver(
            self,
            name: Notification.Name.AVPlayerItemDidPlayToEndTime,
            object: player.currentItem)
    }
}

        case #keyPath(AVPlayer.rate):
            emit(.didChangeRate(from: oldValue(), to: newValueUnwrapped()))
        case #keyPath(AVPlayer.currentItem):
            
            let newItem = newValue() as AVPlayerItem?
            /* Process new item */ do {
                newItem?.addObserver(self,
                                     forKeyPath: #keyPath(AVPlayerItem.status),
                                     options: [.initial, .new, .old],
                                     context: nil)
                newItem?.addObserver(self,
                                     forKeyPath: #keyPath(AVPlayerItem.duration),
                                     options: [.initial, .new, .old],
                                     context: nil)
                newItem?.addObserver(self,
                                     forKeyPath: #keyPath(AVPlayerItem.isPlaybackBufferFull),
                                     options: [.initial, .new, .old],
                                     context: nil)
                newItem?.addObserver(self,
                                     forKeyPath: #keyPath(AVPlayerItem.isPlaybackLikelyToKeepUp),
                                     options: [.initial, .new, .old],
                                     context: nil)
                newItem?.addObserver(self,
                                     forKeyPath: #keyPath(AVPlayerItem.loadedTimeRanges),
                                     options: [.initial, .new],
                                     context: nil)
                if let new = newItem {
                    NotificationCenter.default.addObserver(
                        self,
                        selector: #selector(SystemPlayerObserver.didPlayToEnd(notification:)),
                        name: .AVPlayerItemDidPlayToEndTime,
                        object: new)
                }
            }
            
            let oldItem = oldValue() as AVPlayerItem?
            /* Process old item */ do {
                oldItem?.removeObserver(self,
                                        forKeyPath: #keyPath(AVPlayerItem.status))
                oldItem?.removeObserver(self,
                                        forKeyPath: #keyPath(AVPlayerItem.duration))
                oldItem?.removeObserver(self,
                                        forKeyPath: #keyPath(AVPlayerItem.isPlaybackBufferFull))
                oldItem?.removeObserver(self,
                                        forKeyPath: #keyPath(AVPlayerItem.isPlaybackLikelyToKeepUp))
                oldItem?.removeObserver(self,
                                        forKeyPath: #keyPath(AVPlayerItem.loadedTimeRanges))
                if let old = oldItem {
                    NotificationCenter.default.removeObserver(
                        self,
                        name: .AVPlayerItemDidPlayToEndTime,
                        object: old)
                }
            }

            let oldUrl: URL? = {
                guard let oldItem = oldItem else { return nil }
                guard let asset = oldItem.asset as? AVURLAsset else {
