我的iOS 7应用程序会在必要时发出文字。
我想做的是让用户在我的运行时收听他的音乐或播客(或使用音频的任何其他应用)。
预期的行为是,当我的应用说话时,其他音频会混音或躲避,然后其他音频会立即在初始级别恢复音量。
我已经尝试了很多方法来实现这个目标,但没有什么是足够好的,因为我在代码之后列出了我面临的问题。
我目前的实施基于在播放或文字转语音之前创建会话,如下所示:
+ (void)setAudioActive {
[[self class] setSessionActiveWithMixing:YES];
}
在播放/演讲之后,我将我设置为空闲如下:
+ (void)setAudioIdle {
[[self class] setSessionActiveWithMixing:NO];
}
根据活动参数处理会话设置的核心功能,如下所示:
+ (void)setSessionActiveWithMixing:(BOOL)active
{
NSError *error = NULL;
BOOL success;
AVAudioSession *session = [AVAudioSession sharedInstance];
static NSInteger counter = 0;
success = [session setActive:NO error:&error];
if (error) {
DDLogError(@"startAudioMixAndBackground: session setActive:NO, %@", error.description);
}
else {
counter--; if (counter<0) counter = 0;
}
if (active) {
AVAudioSessionCategoryOptions options = AVAudioSessionCategoryOptionAllowBluetooth
//|AVAudioSessionCategoryOptionDefaultToSpeaker
|AVAudioSessionCategoryOptionDuckOthers
;
success = [session setCategory://AVAudioSessionCategoryPlayback
AVAudioSessionCategoryPlayAndRecord
withOptions: options
error: &error];
if (error) {
// Do some error handling
DDLogError(@"startAudioMixAndBackground: setCategory:AVAudioSessionCategoryPlayback, %@", error.description);
}
else {
//activate the audio session
success = [session setActive:YES error:&error];
if (error) {
DDLogError(@"startAudioMixAndBackground: session setActive:YES, %@", error.description);
}
else {
counter++;
}
}
}
DDLogInfo(@"Audio session counter is: %ld",counter);
}
我目前的问题是:
1)当我的应用程序开始说话时,我听到声音中有一些小故障,这使它不好;
2)当我将路由连接到蓝牙时,基础音频(比如播客或ipod音乐)变得非常低并且听起来很嘈杂,这使得我的解决方案仅仅无法使用,我的用户将拒绝此级别的质量不佳。
3)当其他蓝牙连接的设备试图发出声音时(例如汽车或实例中的GPS),我的应用程序没有收到任何中断(或我处理错误),请参阅我的代码如下:
- (void)startAudioMixAndBackground {
// initialize our AudioSession -
// this function has to be called once before calling any other AudioSession functions
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioSessionDidChangeInterruptionType:)
name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
// set our default audio session state
[[self class] setAudioIdle];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
if ([self canBecomeFirstResponder]) {
[self becomeFirstResponder];
}
@synchronized(self) {
self.okToPlaySound = YES;
}
//MPVolumeSettingsAlertShow();
}
// want remote control events (via Control Center, headphones, bluetooth, AirPlay, etc.)
- (void)remoteControlReceivedWithEvent:(UIEvent *)event
{
if (event.type == UIEventTypeRemoteControl)
{
switch(event.subtype)
{
case UIEventSubtypeRemoteControlPause:
case UIEventSubtypeRemoteControlStop:
[[self class] setAudioIdle];
break;
case UIEventSubtypeRemoteControlPlay:
[[self class] setAudioActive];
break;
default:
break;
}
}
}
#pragma mark - Audio Support
- (void)audioSessionDidChangeInterruptionType:(NSNotification *)notification
{
AVAudioSessionInterruptionType interruptionType = [[[notification userInfo]
objectForKey:AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
if (AVAudioSessionInterruptionTypeBegan == interruptionType)
{
DDLogVerbose(@"Session interrupted: --- Begin Interruption ---");
}
else if (AVAudioSessionInterruptionTypeEnded == interruptionType)
{
DDLogVerbose(@"Session interrupted: --- End Interruption ---");
}
}
答案 0 :(得分:-1)
您的问题很可能是由于您要设置的类别:AVAudioSessionCategoryPlayAndRecord。 PlayAndRecord类别不允许您的应用与其他应用混合/播放音频。您应该在此处再次参考音频会话类别的文档:https://developer.apple.com/library/ios/documentation/avfoundation/reference/AVAudioSession_ClassReference/Reference/Reference.html。似乎AVAudioSessionCategoryAmbient可能更像你想要的东西。