 
     static let sharedInstance = AudioPlayer()
 
-    private let session: AVAudioSession = {
-        let session = AVAudioSession.sharedInstance()
-        try? session.setCategory(AVAudioSessionCategoryPlayback)
-        return session
-    }()
-    private var commands: [Any] = []
     private var player: AVAudioPlayer?
     private var info: [String: Any] = [:]
     private var timer: Timer?
     private var callback: ((_ player: AVAudioPlayer?) -> Void)?
 
-    func start() {
+    override init() {
+        super.init()
+        let session = AVAudioSession.sharedInstance()
+        try? session.setCategory(AVAudioSessionCategoryPlayback)
         try? session.setActive(true)
         UIApplication.shared.beginReceivingRemoteControlEvents()
-        registerControlEvents()
+        handleControlEvents()
+        handleNotifications()
         if UIApplication.shared.applicationState == .active {
             scheduleTimer()
         }
-        addObservers()
-    }
-
-    func stop() {
-        invalidateTimer()
-        player?.stop()
-        player = nil
-        info.removeAll()
-        MPNowPlayingInfoCenter.default().nowPlayingInfo = nil
-        deregisterControlEvents()
-        UIApplication.shared.endReceivingRemoteControlEvents()
-        try? session.setActive(false)
     }
 
     func play(data: Data, time: Date, _ eventCallback: ((_ player: AVAudioPlayer?) -> Void)? = nil) {

        center.likeCommand.isEnabled = false
        center.dislikeCommand.isEnabled = false
        center.bookmarkCommand.isEnabled = false
        commands.append(contentsOf: [
            center.pauseCommand.addTarget { [unowned self] _ in
                guard let player = self.player else { return .noActionableNowPlayingItem }
                player.pause()
                self.update()
                return .success
            },
            center.playCommand.addTarget { [unowned self] _ in
                guard let player = self.player else { return .noActionableNowPlayingItem }
                player.play()
                self.update()
                return .success
            }
        ])
    }

    private func deregisterControlEvents() {
        let center = MPRemoteCommandCenter.shared()
        center.playCommand.removeTarget(nil)
        center.pauseCommand.removeTarget(nil)
        commands.removeAll()
    }

    private func scheduleTimer() {

        info[MPMediaItemPropertyAlbumTitle] = album ?? ""
        info[MPMediaItemPropertyArtist] = artist ?? ""
        if let artwork = artwork {
            info[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: artwork.size) { (size) in artwork }
        }
        update()
    }

    private func update() {
        info[MPMediaItemPropertyPlaybackDuration] = player?.duration ?? 0
        info[MPNowPlayingInfoPropertyElapsedPlaybackTime] = player?.currentTime ?? 0
        MPNowPlayingInfoCenter.default().nowPlayingInfo = info
    }

    private func handleControlEvents() {
        let center = MPRemoteCommandCenter.shared()
        center.pauseCommand.isEnabled = true
        center.playCommand.isEnabled = true
