简体   繁体   中英

How to stop audio playback when disconnecting audio devices in Swift app?

I'm writing a Swift app that streams audio from Web Radio URLs and I can't make it behave properly on audio route changes, specifically when disconnecting audio devices.

I referred to this page of Apple's documentation, however I'm confused as to how the headphonesConnected variable is used in the example and how to cover not only headphones, but other devices like Bluetooth headsets, CarPlay devices etc.

Basically I'd need my app to follow the iOS guidelines by stopping playback whenever an external audio device(headphones, BT headsets, CarPlay devices) is disconnected.

First make an observer:

NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: AVAudioSession.routeChangeNotification, object: nil)

and implement the handleRouteChange:

 @objc func handleRouteChange(_ notification: Notification) {
          
         //bron: https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioHardwareRouteChanges/HandlingAudioHardwareRouteChanges.html#//apple_ref/doc/uid/TP40007875-CH5-SW3
        
          guard let userInfo = notification.userInfo,
          let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
          let reason = AVAudioSession.RouteChangeReason(rawValue:reasonValue) else {return}
        
          switch reason {
            
          case .routeConfigurationChange:
          
               let session = AVAudioSession.sharedInstance()
          
               for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.headphones {
            
                    play()
            
                    break
               
               }
            
               for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.airPlay {

                    play()

                    break

               }

               for output in session.currentRoute.outputs where output.portType == AVAudioSession.Port.carAudio {

                    if isPlaying && autoplayCaraudio {
                         
                         play()

                    }

                    break

               }

          case .oldDeviceUnavailable:
            
               if let previousRoute = userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {

                    for output in previousRoute.outputs where output.portType == AVAudioSession.Port.headphones {

                         pause()

                         break

                    }

                    for output in previousRoute.outputs where output.portType == AVAudioSession.Port.airPlay {

                         pause()

                         break

                    }

                    for output in previousRoute.outputs where output.portType == AVAudioSession.Port.carAudio {

                         pause()

                         break

                    }

               }
            
          default: ()
            
        }
        
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM