簡體   English   中英

將音頻更改為藍牙設備並返回

[英]change audio to bluetooth device and back

當用戶選擇操作表上的選項時,我試圖將音頻輸出更改為設備。 這是代碼,當我選擇將音頻發送到設備時,下次不會出現藍牙。:

for input in AVAudioSession.sharedInstance().availableInputs!{
            if input.portType == AVAudioSessionPortBluetoothA2DP || input.portType == AVAudioSessionPortBluetoothHFP || input.portType == AVAudioSessionPortBluetoothLE{
                let bluetooth = UIAlertAction(title: input.portName, style: .default, handler: {
                    (alert: UIAlertAction!) -> Void in
                    let audioSession = AVAudioSession.sharedInstance()
                    do {
                        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: AVAudioSessionCategoryOptions.allowBluetooth)
                        try audioSession.setActive(true)
                    } catch {
                        fatalError("Error Setting Up bluetooth output \(input.portName)")
                    }


                })

                bluetooth.setValue(UIImage(named:"bluetooth.png"), forKey: "image")
                optionMenu.addAction(bluetooth)
            }

let iphomeOutput = UIAlertAction(title: "iPhone", style: .default, handler: {
                (alert: UIAlertAction!) -> Void in
                let audioSession = AVAudioSession.sharedInstance()
                do {
                    do {
                        try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord, with: AVAudioSessionCategoryOptions.duckOthers)
                        try audioSession.setActive(true)
                    } catch {
                        fatalError("Error Setting Up audio output Phone")
                    }
                    try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.none)
                } catch let error as NSError {
                    print("audioSession error turning off speaker: \(error.localizedDescription)")
                }
            })

            for description in currentRoute.outputs {
                if description.portType == AVAudioSessionPortHeadsetMic{
                    optionMenu.setValue(true, forKey: "checked")
                    break
                }
            }
            optionMenu.addAction(iphomeOutput)

我也許可以更有效地做到這一點,但這是我最終使用的:

var deviceAction = UIAlertAction()
        var headphonesExist = false

        let audioSession = AVAudioSession.sharedInstance()
        let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let currentRoute = audioSession.currentRoute
        for input in audioSession.availableInputs!{
            if input.portType == AVAudioSessionPortBluetoothA2DP || input.portType == AVAudioSessionPortBluetoothHFP || input.portType == AVAudioSessionPortBluetoothLE{
                                let localAction = UIAlertAction(title: input.portName, style: .default, handler: {
                                    (alert: UIAlertAction!) -> Void in

                                    do {
                                        try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.none)
                                    } catch let error as NSError {
                                        print("audioSession error turning off speaker: \(error.localizedDescription)")
                                    }

                                    do {
                                        try audioSession.setPreferredInput(input)
                                    }catch _ {
                                        print("cannot set mic ")
                                    }


                                })

                for description in currentRoute.outputs {
                    if description.portType == AVAudioSessionPortBluetoothA2DP {
                        localAction.setValue(true, forKey: "checked")
                        break
                    }else if description.portType == AVAudioSessionPortBluetoothHFP {
                            localAction.setValue(true, forKey: "checked")
                            break
                    }else if description.portType == AVAudioSessionPortBluetoothLE{
                        localAction.setValue(true, forKey: "checked")
                        break
                    }
                }
                localAction.setValue(UIImage(named:"bluetooth.png"), forKey: "image")
                    optionMenu.addAction(localAction)

            } else if input.portType == AVAudioSessionPortBuiltInMic || input.portType == AVAudioSessionPortBuiltInReceiver  {

                deviceAction = UIAlertAction(title: "iPhone", style: .default, handler: {
                    (alert: UIAlertAction!) -> Void in

                    do {
                        try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.none)
                    } catch let error as NSError {
                        print("audioSession error turning off speaker: \(error.localizedDescription)")
                    }

                    do {
                        try audioSession.setPreferredInput(input)
                    }catch _ {
                        print("cannot set mic ")
                    }

                })

                for description in currentRoute.outputs {
                    if description.portType == AVAudioSessionPortBuiltInMic || description.portType  == AVAudioSessionPortBuiltInReceiver {
                        deviceAction.setValue(true, forKey: "checked")
                        break
                    }
                }

            } else if input.portType == AVAudioSessionPortHeadphones || input.portType == AVAudioSessionPortHeadsetMic {
                headphonesExist = true
                let localAction = UIAlertAction(title: "Headphones", style: .default, handler: {
                    (alert: UIAlertAction!) -> Void in

                    do {
                        try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.none)
                    } catch let error as NSError {
                        print("audioSession error turning off speaker: \(error.localizedDescription)")
                    }

                    do {
                        try audioSession.setPreferredInput(input)
                    }catch _ {
                        print("cannot set mic ")
                    }
                })
                for description in currentRoute.outputs {
                    if description.portType == AVAudioSessionPortHeadphones {
                        localAction.setValue(true, forKey: "checked")
                        break
                    } else if description.portType == AVAudioSessionPortHeadsetMic {
                        localAction.setValue(true, forKey: "checked")
                        break
                    }
                }

                optionMenu.addAction(localAction)
            }
        }

        if !headphonesExist {
            optionMenu.addAction(deviceAction)
        }

        let speakerOutput = UIAlertAction(title: "Speaker", style: .default, handler: {
            (alert: UIAlertAction!) -> Void in

            do {
                try audioSession.overrideOutputAudioPort(AVAudioSessionPortOverride.speaker)
            } catch let error as NSError {
                print("audioSession error turning on speaker: \(error.localizedDescription)")
            }
        })
        for description in currentRoute.outputs {
            if description.portType == AVAudioSessionPortBuiltInSpeaker{
                speakerOutput.setValue(true, forKey: "checked")
                break
            }
        }
        speakerOutput.setValue(UIImage(named:"speaker.png"), forKey: "image")
        optionMenu.addAction(speakerOutput)

        let cancelAction = UIAlertAction(title: "Hide", style: .cancel, handler: {
            (alert: UIAlertAction!) -> Void in

        })
        optionMenu.addAction(cancelAction)
        self.present(optionMenu, animated: true, completion: nil)

我用擴展更新了 FreeGor 的答案(和一點安排)

extension AVAudioSession {

func ChangeAudioOutput(presenterViewController : UIViewController) {
    let CHECKED_KEY = "checked"
    let IPHONE_TITLE = "iPhone"
    let HEADPHONES_TITLE = "Headphones"
    let SPEAKER_TITLE = "Speaker"
    let HIDE_TITLE = "Hide"
    
    var deviceAction = UIAlertAction()
    var headphonesExist = false
    
    let currentRoute = self.currentRoute
    
    let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    for input in self.availableInputs!{
        
        switch input.portType  {
        case AVAudioSession.Port.bluetoothA2DP, AVAudioSession.Port.bluetoothHFP, AVAudioSession.Port.bluetoothLE:
            let action = UIAlertAction(title: input.portName, style: .default) { (action) in
                do {
                    // remove speaker if needed
                    try self.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
                    
                    // set new input
                    try self.setPreferredInput(input)
                } catch let error as NSError {
                    print("audioSession error change to input: \(input.portName) with error: \(error.localizedDescription)")
                }
            }
            
            if currentRoute.outputs.contains(where: {return $0.portType == input.portType}){
                action.setValue(true, forKey: CHECKED_KEY)
            }
            
            optionMenu.addAction(action)
            break
            
        case AVAudioSession.Port.builtInMic, AVAudioSession.Port.builtInReceiver:
            deviceAction = UIAlertAction(title: IPHONE_TITLE, style: .default) { (action) in
                do {
                    // remove speaker if needed
                    try self.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
                    
                    // set new input
                    try self.setPreferredInput(input)
                } catch let error as NSError {
                    print("audioSession error change to input: \(input.portName) with error: \(error.localizedDescription)")
                }
            }
            
            if currentRoute.outputs.contains(where: {return $0.portType == input.portType}){
                deviceAction.setValue(true, forKey: CHECKED_KEY)
            }
            break
            
        case AVAudioSession.Port.headphones, AVAudioSession.Port.headsetMic:
            headphonesExist = true
            let action = UIAlertAction(title: HEADPHONES_TITLE, style: .default) { (action) in
                do {
                    // remove speaker if needed
                    try self.overrideOutputAudioPort(AVAudioSession.PortOverride.none)
                    
                    // set new input
                    try self.setPreferredInput(input)
                } catch let error as NSError {
                    print("audioSession error change to input: \(input.portName) with error: \(error.localizedDescription)")
                }
            }
            
            if currentRoute.outputs.contains(where: {return $0.portType == input.portType}){
                action.setValue(true, forKey: CHECKED_KEY)
            }
            
            optionMenu.addAction(action)
            break
        default:
            break
        }
    }
    
    if !headphonesExist {
        optionMenu.addAction(deviceAction)
    }
    
    let speakerOutput = UIAlertAction(title: SPEAKER_TITLE, style: .default, handler: {
        (alert: UIAlertAction!) -> Void in
        
        do {
            try self.overrideOutputAudioPort(AVAudioSession.PortOverride.speaker)
        } catch let error as NSError {
            print("audioSession error turning on speaker: \(error.localizedDescription)")
        }
    })
    
    if currentRoute.outputs.contains(where: {return $0.portType == AVAudioSession.Port.builtInSpeaker}){
        speakerOutput.setValue(true, forKey: CHECKED_KEY)
    }
    
    optionMenu.addAction(speakerOutput)
    
    
    let cancelAction = UIAlertAction(title: HIDE_TITLE, style: .cancel, handler: {
        (alert: UIAlertAction!) -> Void in
        
    })
    optionMenu.addAction(cancelAction)
    presenterViewController.present(optionMenu, animated: true, completion: nil)
    
 }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM