                                options: [.old, .new],
                                context: &playerItemContext)
         player.replaceCurrentItem(with: playerItem)
-        
-        let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
-        nowPlayingInfoCenter.nowPlayingInfo = [
-            MPMediaItemPropertyTitle: episode.title,
-            MPMediaItemPropertyArtist: episode.seriesTitle,
-            MPMediaItemPropertyPlaybackDuration: episode.duration,
-        ]
-        nowPlayingInfoCenter.playbackState = .playing
+        updateNowPlayingInfo()
+        delegate?.updateUIForEpisode(episode: currentEpisode!)
+        delegate?.updateUIForPlayback()
+    }
+    
+    @objc func play() {
+        if let currentItem = player.currentItem {
+            if currentItem.status == .readyToPlay {
+                try! AVAudioSession.sharedInstance().setActive(true)
+                player.play()
+                player.rate = savedRate.rawValue
+                delegate?.updateUIForPlayback()
+                updateNowPlayingInfo()
+                addTimeObservers()
+            } else {
+                autoplayEnabled = true
+            }
+        }
+    }
+    
+    @objc func pause() {
+        if let currentItem = player.currentItem {
+            guard let rate = PlayerRate(rawValue: player.rate) else { return }
+            if currentItem.status == .readyToPlay {
+                savedRate = rate
+                player.pause()
+                updateNowPlayingInfo()
+                removeTimeObservers()
+                delegate?.updateUIForPlayback()
+            } else {
+                autoplayEnabled = false
+            }
+        }
+    }
+    
+    func togglePlaying() {
+        if isPlaying {
+            pause()
+        } else {
+            play()
+        }
+        delegate?.updateUIForPlayback()
+    }
+    
+    func reset() {
+        autoplayEnabled = true
+        currentItemPrepared = false
+        isScrubbing = false
+        player.rate = 1.0
+    }
+    
+    func skip(seconds: Double) {
+        guard let currentItem = player.currentItem else { return }
+        let newTime = CMTimeAdd(currentItem.currentTime(), CMTime(seconds: seconds, preferredTimescale: CMTimeScale(1.0)))
+        player.currentItem?.seek(to: newTime, completionHandler: { success in
+            self.updateNowPlayingInfo()
+        })
+        
+        if newTime > CMTime(seconds: 0.0, preferredTimescale: CMTimeScale(1.0)) {
+            delegate?.updateUIForPlayback()
+        }
+    }
+    
+    func setSpeed(rate: PlayerRate) {
+        savedRate = rate
+        if isPlaying {
+            player.rate = rate.rawValue
+        }
+        delegate?.updateUIForPlayback()
+    }
+    
+    func getSpeed() -> PlayerRate {
+        return savedRate
+    }
+    
+    func getProgress() -> Double {
+        if let currentItem = player.currentItem {
+            let currentTime = currentItem.currentTime()
+            let durationTime = currentItem.duration
+            if !durationTime.isIndefinite && durationTime.seconds != 0 {
+                return currentTime.seconds / durationTime.seconds
+            }
+        }
+        return 0.0
+    }
+    
+    func setProgress(progress: Double) {
+        if let duration = player.currentItem?.duration {
+            if !duration.isIndefinite {
+                player.currentItem!.seek(to: CMTime(seconds: duration.seconds * min(max(progress, 0.0), 1.0), preferredTimescale: CMTimeScale(1.0)), completionHandler: nil)
+                delegate?.updateUIForPlayback()
+            }
+        }
+    }
+    
+    func configureCommands() {
         UIApplication.shared.beginReceivingRemoteControlEvents()
         let commandCenter = MPRemoteCommandCenter.shared()
         commandCenter.pauseCommand.addTarget(self, action: #selector(Player.pause))

    
    private var player: AVPlayer
    private(set) var currentEpisode: Episode?
    private var autoplayEnabled: Bool
    private var currentItemPrepared: Bool
    var isScrubbing: Bool

        isScrubbing = false
        savedRate = .normal
        super.init()
        
        configureCommands()
    }
    
    deinit {
