5

I am building an alarm clock app which works in conjunction with a physical Bluetooth device. I need to send one audio file (a song selected from the iTunes Library) to the built-in speaker and a separate audio file to the Bluetooth device (which is, effectively, a Bluetooth HFP speaker) at the same time.

My first thought in completing this would be to use AVAudioSession's new AVAudioSessionCategoryMultiRoute, but iOS 7 does not detect my speaker as a possible route; it will detect either the built-in speaker or the HFP speaker, but it will not detect both simultaneously. Detecting both is required to send two files at the same time.

My second thought was to use AVAudioSessionCategoryPlayAndRecord (even though the app has no need for a microphone) and to use overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker and overrideOutputAudioPort:AVAudioSessionPortOverrideNone like so:

NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:@"alarm"
                                                          ofType:@"m4a"];

NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];

self.bluetoothAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL
                                                               error:nil];

self.bluetoothAudioPlayer.delegate = self;

[self.bluetoothAudioPlayer play];

NSError *error = nil;

NSURL *selectedSongURL = [self.selectedSong valueForProperty:MPMediaItemPropertyAssetURL];

NSLog(@"selectedSongURL: %@", selectedSongURL);

if (selectedSongURL) {
    if (![[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error]) {
        NSLog(@"overrideOutput error: %@", error);
    }
    self.internalAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:selectedSongURL error:nil];
    self.internalAudioPlayer.delegate = self;
    [self.internalAudioPlayer play];
}

After this alarm is silenced, I run [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil]; to reset the override call.

However, this doesn't work because iOS just puts both audio signals on the same speaker.

Is there a way to send one audio stream to a Bluetooth HFP speaker and a different audio stream to the built-in speaker?

Tim B.
  • 467
  • 3
  • 14
  • This isn't possible with public api as iOS abstracts away the audio system. (how they can intergrate Airplay & bluetooth speaker support without apps nowing about it). – Kyle Howells Apr 02 '15 at 14:48

0 Answers0