[英]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.