             }
             
         case #keyPath(AVPlayerItem.asset):
-            guard let asset: AVAsset = newValue() else { return }
-            emit(.didChangeAsset(asset))
-            
-            let key = "duration"
-            let status = asset.statusOfValue(forKey: key, error: nil)
-            switch status {
-            case .unknown:
-                asset.loadValuesAsynchronously(forKeys: [key]) { [weak self] in
-                    let status = asset.statusOfValue(forKey: key, error: nil)
-                    guard case .loaded = status else { return }
-                    self?.emit(.didChangeItemDuration(to: asset.duration))
-                }
-            case .loaded:
-                emit(.didChangeItemDuration(to: asset.duration))
-            default: break
-            }
+            guard let new: AVAsset = newValue() else { return }
+            emit(.didChangeAsset(new))
+            
+            let old: AVAsset? = oldValue()
+            old?.removeObserver(self, forKeyPath: #keyPath(AVAsset.duration))
+            new.addObserver(self,
+                            forKeyPath: #keyPath(AVAsset.duration),
+                            options: [.initial, .new],
+                            context: nil)
+            
+        case #keyPath(AVAsset.duration):
+            guard let object = object as? AVAsset else { return }
+            guard case .loaded = object.statusOfValue(forKey: "duration", error: nil) else { return }
+            guard let duration: CMTime = newValue() else { return }
+            emit(.didChangeItemDuration(to: duration))
             
         default:
             super.observeValue(

                                  name: kCMTimebaseNotification_EffectiveRateChanged as NSNotification.Name,
                                  object: player.currentItem)
        }
    }
}

                                     context: nil)
                
                if let new = newItem {
                    if case .unknown = new.asset.statusOfValue(forKey: "duration", error: nil) {
                        new.asset.loadValuesAsynchronously(forKeys: ["duration"], completionHandler: nil)
                    }
                    
                    center.addObserver(
                        self,
                        selector: #selector(SystemPlayerObserver.didPlayToEnd),
