8

我遵循了关心我的扬声器状态的方法:

音频会话.h

enum {
    kAudioSessionOverrideAudioRoute_None    = 0,
    kAudioSessionOverrideAudioRoute_Speaker = 'spkr'
};

我的课

@synthesize speakerEnabled;

...

- (void)setSpeakerEnabled:(BOOL)enable {
speakerEnabled = enable;
if(enable) {
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;  
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
                             , sizeof (audioRouteOverride)
                             , &audioRouteOverride);
 } else {
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;  
    AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute
                             , sizeof (audioRouteOverride)
                             , &audioRouteOverride);
 }
}

但是,它仅适用于 iPhone,适用于 iPad - 没有任何反应。

  • 当我按下按钮时:Speaker On,我进入if(enable)AudioSessionSetProperty接收kAudioSessionOverrideAudioRoute_Speaker

  • 当我按下按钮时:Speaker Off,我进入elseAudioSessionSetProperty接收kAudioSessionOverrideAudioRoute_None

我开始调试并没有发现设备之间的区别。

我有 iPad2 iOS 6.1。

我错过了什么?

请帮我

编辑

正如 LombaX 所说,我在启动应用程序AVAudioSession类别中添加了:

NSError *err = nil;
    BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&err];

    if(!success){
        [MyLogger logc:MyLoggerLog format:"%@",[err localizedDescription]];
    }

success = YES

还是不行。

4

2 回答 2

10

我想你误解了这个属性的使用。您希望启用/禁用扬声器。这不完全是 的意图kAudioSessionProperty_OverrideAudioRoute。相反,它以相当有限的方式影响输出声音路由。

这些是 iPhone 可用的各种可能的输出路径

extern const CFStringRef kAudioSessionOutputRoute_LineOut           
extern const CFStringRef kAudioSessionOutputRoute_Headphones            
extern const CFStringRef kAudioSessionOutputRoute_BluetoothHFP        
extern const CFStringRef kAudioSessionOutputRoute_BluetoothA2DP      
extern const CFStringRef kAudioSessionOutputRoute_BuiltInReceiver   
extern const CFStringRef kAudioSessionOutputRoute_BuiltInSpeaker    
extern const CFStringRef kAudioSessionOutputRoute_USBAudio            
extern const CFStringRef kAudioSessionOutputRoute_HDMI              
extern const CFStringRef kAudioSessionOutputRoute_AirPlay   

这些只是可能的路线 - 实际可用的路线取决于上下文。Apple 严格限制您在应用程序内确定这些路线的能力,因为这是用户需要以与设备一致的方式控制的东西。它们中的大多数是由用户插入/拔出硬件(耳机、USB、HDMI、线路输出)隐式确定的,Apple 不希望您的应用在这里与用户期望发生冲突。

如果媒体上下文正确(并且可以使用 Airplay),则可以使用MPVolumeView's 选择 Airplay。routeButton蓝牙可以由OverrideCategoryEnableBluetoothInput控制输入输出)引导

特别要注意的是,它kAudioSessionOutputRoute_BuiltInReceiver是你打电话时贴在耳朵上的 iPhone 上的低级扬声器。如果没有插入外部设备(例如耳机),这是 iPhone 的默认音频输出路径。kAudioSessionOutputRoute_BuiltInSpeaker是手机底部的“免提”扬声器。

BuiltInSpeaker您可以通过设置以下覆盖属性之一从当前默认值重新路由到此:

key: kAudioSessionProperty_OverrideAudioRoute
values:   kAudioSessionOverrideAudioRoute_Speaker
      :   kAudioSessionOverrideAudioRoute_None

指定是否覆盖音频会话类别的正常音频路由。

key: kAudioSessionProperty_OverrideCategoryDefaultToSpeaker
values:   TRUE
      :   FALSE

指定在没有连接其他音频路由(例如耳机)时是否将音频路由到扬声器(而不是接收器)。

这两个都只设计用于kAudioSessionCategory_PlayAndRecord音频会话类别。

请注意,在这两种情况下,您都没有在任何输出路由中进行选择,您只是覆盖了“默认路由”以支持内置(大声)扬声器。

iPad 没有电话,也没有BuiltInReceiver扬声器。这是默认路线,在没有连接的小工具或播放器的情况下,是一样的BuiltInSpeaker。因此,覆盖没有任何效果。

假设你真的想在你的应用程序中静音,你如何实现这取决于你的应用程序设计的许多其他方面。如果您想使设备静音,Apple 宁愿用户通过响铃/静音开关来控制它。似乎他们不会有任何其他方式:

我收到了 Apple 对此的回应。他们说他们没有也从未提供过检测硬件静音开关的方法,也不打算这样做。 https://stackoverflow.com/a/8009073/1375695

扬声器设置是设备的替代品,而不是给定的声音
http://lists.apple.com/archives/coreaudio-api/2009/Mar/msg00300.html

于 2013-05-01T04:19:31.427 回答
2

您是否尝试在播放前设置音频类别?我记得我前段时间遇到了同样的问题,找到了这个解决方案(调整类别)

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];

我在文档上没有找到任何内容,我认为在 iPad 上您必须设置类别,因为 iPhone 和 iPad 在一个细节上有所不同:在 iPhone 上,左侧硬件开关可以使扬声器静音。在 iPad 上,相同的开关用于锁定旋转。

试着让我知道

编辑:

有用的链接:

http://developer.apple.com/library/ios/#documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Cookbook/Cookbook.html

于 2013-04-29T15:58:58.200 回答