【发布时间】:2014-01-29 14:38:26
【问题描述】:
我的 iOS 7 应用会在必要时发声。
我想做的是让用户在我的运行时能够收听他的音乐或播客(或任何其他使用音频的应用程序)。
预期的行为是,当我的应用说话时,其他音频会混合或闪避,然后其他音频会立即恢复到初始音量。
我尝试了很多方法来实现这个目标,但没有什么是足够好的,因为我在代码之后列出了我面临的问题。
我当前的实现是基于在播放或文本转语音之前创建一个会话,如下所示:
+ (void)setAudioActive {
[[self class] setSessionActiveWithMixing:YES];
}
在播放/演讲之后,我将 i 设置为空闲,如下所示:
+ (void)setAudioIdle {
[[self class] setSessionActiveWithMixing:NO];
}
根据active参数处理会话建立的核心函数,如下:
+ (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) 当我将路由连接到蓝牙时,底层音频(比如 Podcast 或 ipod 音乐)会变得非常低并且听起来很嘈杂,这使得我的解决方案无法使用,我的用户会拒绝这个级别的质量差。
3) 当其他蓝牙连接的设备尝试发出声音时(比如汽车或实例中的 GPS),我的 App 没有收到任何中断(或者我处理错误),请参见我的代码如下:
- (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 ---");
}
}
【问题讨论】:
-
您找到解决问题的方法了吗?我的问题是 2 号
-
唉,不。听起来没有人知道如何做这些事情。你有没有跑过什么特别的东西可以帮助你? (提出问题以引起注意)@Jan
-
看来这篇文章有很多问题。只是为了澄清问题,您是否无法将您的应用程序的音频与用户的音乐混合使用?由于您的解决方法,外部和蓝牙音频出现故障?
-
@sam 真实。我相信代码 sn-p 不言自明。更一般地说,需要哪些代码才能实现与计划相同的无缝结果?
标签: ios bluetooth avaudiosession