如何在不使用AudioSessionSetProperty的情况下将音频路由到扬声器?

37

由于AudioSessionSetProperty可能会变得已弃用,因此我正在尝试寻找其他方法将音频路由到扬声器的代码示例。

之前,我做了以下操作:

-(void)setSpeakerEnabled
{
    debugLog(@"%s",__FUNCTION__);
    UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;

    AudioSessionSetProperty (
                         kAudioSessionProperty_OverrideAudioRoute,
                         sizeof (audioRouteOverride),
                         &audioRouteOverride
                         );
}

尝试获得相同的结果,但无需调用AudioSessionSetProperty函数。


这个问题似乎不适合讨论,因为它涉及到受 NDA 保护的 iOS 7。 - Cole Tobin
错误。你说AudioSessionGetProperty已被弃用,但它在iOS 6中仍可用。它在iOS 7中被弃用。这违反了保密协议。 - Cole Tobin
13
我的看法是,Stack Overflow 并不应该去监管保密协议。 - foundry
2
@ColeJohnson,我正在观看2012 WWDC,其中在13:58会话505音频服务已过时。不过,我不会讨论我为什么要观看它。 - Jim Hankins
1
@Jim 嗯,那就是我的错了。我在 ADC(iOS 6 文档)上查找了这种方法,并且据我所知它并没有被弃用。 - Cole Tobin
4个回答

60

每次iOS发布新版本,越来越多的audioSession属性被迁移到AVFoundation中,因此在可用时应优先使用它们。

自iOS 6以来,“kAudioSessionProperty_OverrideAudioRoute”在AVAudioSession中通过该方法表示。

- (BOOL)overrideOutputAudioPort:error:

可用的值为AVAudioSessionPortOverrideNoneAVAudioSessionPortOverrideSpeaker

以下是完全通过AVFoundation配置的音频会话示例:

 - (void)configureAVAudioSession
{
   // Get your app's audioSession singleton object
    AVAudioSession *session = [AVAudioSession sharedInstance];

    // Error handling
    BOOL success;
    NSError *error;

    // set the audioSession category. 
    // Needs to be Record or PlayAndRecord to use audioRouteOverride:  

    success = [session setCategory:AVAudioSessionCategoryPlayAndRecord
                             error:&error];

   if (!success) {
       NSLog(@"AVAudioSession error setting category:%@",error);
   }

    // Set the audioSession override
    success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                          error:&error];
    if (!success) {
        NSLog(@"AVAudioSession error overrideOutputAudioPort:%@",error);
    }

    // Activate the audio session
    success = [session setActive:YES error:&error];
    if (!success) {
        NSLog(@"AVAudioSession error activating: %@",error);
    }
    else {
         NSLog(@"AudioSession active");
    }

}

更新

自iOS 7.0起,音频会话服务C API已经完全弃用,而使用AVAudioSession代替。

更新2

- (BOOL)overrideOutputAudioPort:error:  

是一种方法,而不是属性,并设置底层的仅写入 UInt32值。您无法获取当前值,应将该方法视为设置临时状态。如果音频路由更改或中断,则属性将重置为其默认值(AVAudioSessionPortOverrideNone)。您可以通过AVAudioSessionDelegate获取中断通知。


在iOS 7中,kAudioSessionProperty_OverrideCategoryEnableBluetoothInput如何工作? - Sjoerd Perfors
@SjoerdPerfors - 你可以使用AVAudioSession方法- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError,其中categoryAVAudioSessionCategoryPlayAndRecordAVAudioSessionCategoryRecord,而options则为AVAudioSessionCategoryOptionAllowBluetooth - foundry
感谢Foundry,但这并不相同,因为那只允许A2DP蓝牙。而且这也不会强制使用它。另请参阅:https://dev59.com/UnfZa4cB1Zd3GeqPSYLg - Sjoerd Perfors
对我没用!我的代码:AVAudioSessionPortOverride port = (onOff ? AVAudioSessionPortOverrideSpeaker : AVAudioSessionPortOverrideNone); success = [session overrideOutputAudioPort:port error:&error]; - hungbm06
1
如果有其他人想知道为什么这对他们不起作用。你需要在播放之前立即调用它。所以 [[AVAudioSession] sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&overrideError]; [_player play]; - Joseph
显示剩余5条评论

7
NSError *error;
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker 
                                                   error:&error];    
if(error)
{ 
    NSLog(@"Error: AudioSession cannot use speakers");
}

2
let audioSession = AVAudioSession.sharedInstance()

    do {
        try audioSession.setCategory(AVAudioSession.Category.playAndRecord, mode: .spokenAudio, options: .defaultToSpeaker)
        try audioSession.setActive(true, options: .notifyOthersOnDeactivation)
    } catch {
        print("error.")
    }  

// 将此代码粘贴到您的viewLoad区域中


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接