Search code examples
swiftavplayertvosavqueueplayer

How to detect volume button press on tvOS remote


Im trying to find a way to observe the player so that I can detect when a user increases or decreases the volume on the Apple TV. I have managed to get this to work for iOS by using:


 var audioSession: AVAudioSession?

 audioSession?.addObserver(self, forKeyPath: "outputVolume", options: [.new], context: &videoPlayerViewControllerKVOContext)


 if keyPath == "outputVolume" {
        guard let mute = (change?[NSKeyValueChangeKey.newKey] as? NSNumber)?.floatValue else {
            return
        }
        
        var isMuted = false
        
        if (mute == 0) && (!player.isMuted) {
            isMuted = true
        } else if (mute.isZero) && (player.isMuted) {
            isMuted = false
        }
        
    }

However this doesn't work for tvOS. Is there a way to do this on tvOS?


Solution

  • It is not clear all other code, but you have to keep reference to created observer.

    Here is possible solution (tested with Xcode 12.1)

    private var observer: NSKeyValueObservation?
    
    // ... other code
    
    self.observer = audioSession?.observe(\.outputVolume) { [weak self] (audioSession, _) in
        guard let `self` = self else { return }
        let mute = audioSession.outputVolume
        
        var isMuted = false
        if (mute == 0) && (!self.player.isMuted) {
            isMuted = true
        } else if (mute.isZero) && (self.player.isMuted) {
            isMuted = false
        }
        
        // do what's needed here with `isMuted`
    }