I am playing the audio from an url using AVPlayer, but when the iPhone is connected to a Bluetooth device it is not playing via Bluetooth, how to play via Bluetooth if it is
For Swift 3.1
Short version:
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord, with: [.allowBluetooth])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
Extended version to be sure, that you're using correct input:
/**
Check availability of recording and setups audio session
with prioritized input.
*/
func setupSessionForRecording() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryRecord, with: [.allowBluetooth])
} catch {
fatalError("Error Setting Up Audio Session")
}
var inputsPriority: [(type: String, input: AVAudioSessionPortDescription?)] = [
(AVAudioSessionPortLineIn, nil),
(AVAudioSessionPortHeadsetMic, nil),
(AVAudioSessionPortBluetoothHFP, nil),
(AVAudioSessionPortUSBAudio, nil),
(AVAudioSessionPortCarAudio, nil),
(AVAudioSessionPortBuiltInMic, nil),
]
for availableInput in audioSession.availableInputs! {
guard let index = inputsPriority.index(where: { $0.type == availableInput.portType }) else { continue }
inputsPriority[index].input = availableInput
}
guard let input = inputsPriority.filter({ $0.input != nil }).first?.input else {
fatalError("No Available Ports For Recording")
}
do {
try audioSession.setPreferredInput(input)
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
/**
Check availability of playing audio and setups audio session
with mixing audio.
*/
func setupSessionForPlaying() {
let audioSession = AVAudioSession.sharedInstance()
do {
try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])
try audioSession.setActive(true)
} catch {
fatalError("Error Setting Up Audio Session")
}
}
The main idea that you have 2 functions for changing audio session settings. Use setupSessionForRecording
right before recording, and setupSessionForPlaying
before playing audio.
Important to use AVAudioSessionCategoryRecord
and AVAudioSessionCategoryPlayback
, but not AVAudioSessionCategoryPlayAndRecord
, because of it's buggy. Use AVAudioSessionCategoryPlayAndRecord
only if you really need to play and record audio same time.
You need to set a category and options on the AVAudioSession
.
Try this when the app starts:
//configure audio session
NSError *setCategoryError = nil;
BOOL setCategorySuccess = [[AVAudioSession sharedInstance]
setCategory:AVAudioSessionCategoryPlayback
withOptions:AVAudioSessionCategoryOptionAllowBluetooth
error:&setCategoryError];
if (setCategorySuccess) {
NSLog(@"Audio Session options set.");
} else {
NSLog(@"WARNING: Could not set audio session options.");
}
Try this
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory),&sessionCategory);
// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionAllowBluetooth error:&sessionError];
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryEnableBluetoothInput, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);