【问题标题】:Redirecting audio output to phone speaker and mic input to headphones将音频输出重定向到手机扬声器,将麦克风输入重定向到耳机
【发布时间】:2011-08-21 08:49:43
【问题描述】:

是否可以将音频输出重定向到手机扬声器并仍然使用麦克风耳机输入?

如果我将音频路由重定向到手机扬声器而不是耳机,它也会重定向麦克风。这是有道理的,但我似乎不能只重定向麦克风输入?有什么想法吗?

这是我用来将音频重定向到扬声器的代码:

UInt32 doChangeDefaultRoute = true;        
propertySetError = AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
NSAssert(propertySetError == 0, @"Failed to set audio session property: OverrideCategoryDefaultToSpeaker");
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);

【问题讨论】:

  • 您可能知道这一点,但是当您启用扬声器时,您也会启用手机上的麦克风。但是在 iPod 上,如果您启用扬声器,您仍然可以从耳机中获取麦克风声音。可能是因为 ipod 上没有麦克风。我简要地得到了一个 ios 4.3 sdk 应用程序来从耳机和扬声器输出中获取麦克风,通过在路线更改后再次初始化 AUgraph,但它间歇性地发生了,现在它根本没有发生(ios 4.3+ xcode 4+)

标签: iphone objective-c ios audio


【解决方案1】:

恐怕这不可能。

来自Audio Session Programming Guide - kAudioSessionProperty_OverrideAudioRoute

如果在您设置此属性的值时插入了耳机 到 kAudioSessionOverrideAudioRoute_Speaker,系统更改 输入和输出的音频路由:输入来自 内置麦克风;输出到内置扬声器。

this question 可能重复

【讨论】:

  • 可能值得按照 Tommy 在this question 中所做的相同步骤来查找可用的AVCaptureDevices
【解决方案2】:

这是可能的,但你如何设置它很挑剔。

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

使用AVAudioSessionCategoryPlayAndRecord 非常重要,否则路由将无法到达扬声器。为音频会话设置覆盖路由后,您可以使用 AVAudioPlayer 实例并将一些输出发送到扬声器。

希望对其他人有用,就像对我一样。这方面的文档很分散,但 Skype 应用程序证明这是可能的。坚持下去,我的朋友们! :)

这里有一些 Apple 文档:http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/AudioSessionServicesReference/Reference/reference.html

在页面上搜索kAudioSessionProperty_OverrideAudioRoute

【讨论】:

    【解决方案3】:

    你可以做的是在任何情况下强制音频输出到扬声器:

    来自UI Hacker - iOS: Force audio output to speakers while headphones are plugged in

    @interface AudioRouter : NSObject
    
    + (void) initAudioSessionRouting;
    + (void) switchToDefaultHardware;
    + (void) forceOutputToBuiltInSpeakers;
    
    @end
    

    #import "AudioRouter.h"
    #import <AudioToolbox/AudioToolbox.h>
    #import <AVFoundation/AVFoundation.h>
    
    @implementation AudioRouter
    
    #define IS_DEBUGGING NO
    #define IS_DEBUGGING_EXTRA_INFO NO
    
    + (void) initAudioSessionRouting {
    
        // Called once to route all audio through speakers, even if something's plugged into the headphone jack
        static BOOL audioSessionSetup = NO;
        if (audioSessionSetup == NO) {
    
            // set category to accept properties assigned below
            NSError *sessionError = nil;
            [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error: &sessionError];
    
            // Doubly force audio to come out of speaker
            UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
            AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
    
            // fix issue with audio interrupting video recording - allow audio to mix on top of other media
            UInt32 doSetProperty = 1;
            AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof(doSetProperty), &doSetProperty);
    
            // set active
            [[AVAudioSession sharedInstance] setDelegate:self];
            [[AVAudioSession sharedInstance] setActive: YES error: nil];
    
            // add listener for audio input changes
            AudioSessionAddPropertyListener (kAudioSessionProperty_AudioRouteChange, onAudioRouteChange, nil );
            AudioSessionAddPropertyListener (kAudioSessionProperty_AudioInputAvailable, onAudioRouteChange, nil );
    
        }
    
        // Force audio to come out of speaker
        [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
    
    
        // set flag
        audioSessionSetup = YES;
    }
    
    + (void) switchToDefaultHardware {
        // Remove forcing to built-in speaker
        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_None;
        AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
    }
    
    + (void) forceOutputToBuiltInSpeakers {
        // Re-force audio to come out of speaker
        UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
        AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
    
    
    }
    
    void onAudioRouteChange (void* clientData, AudioSessionPropertyID inID, UInt32 dataSize, const void* inData) {
    
        if( IS_DEBUGGING == YES ) {
            NSLog(@"==== Audio Harware Status ====");
            NSLog(@"Current Input:  %@", [AudioRouter getAudioSessionInput]);
            NSLog(@"Current Output: %@", [AudioRouter getAudioSessionOutput]);
            NSLog(@"Current hardware route: %@", [AudioRouter getAudioSessionRoute]);
            NSLog(@"==============================");
        }
    
        if( IS_DEBUGGING_EXTRA_INFO == YES ) {
            NSLog(@"==== Audio Harware Status (EXTENDED) ====");
            CFDictionaryRef dict = (CFDictionaryRef)inData;
            CFNumberRef reason = CFDictionaryGetValue(dict, kAudioSession_RouteChangeKey_Reason);
            CFDictionaryRef oldRoute = CFDictionaryGetValue(dict, kAudioSession_AudioRouteChangeKey_PreviousRouteDescription);
            CFDictionaryRef newRoute = CFDictionaryGetValue(dict, kAudioSession_AudioRouteChangeKey_CurrentRouteDescription);
            NSLog(@"Audio old route: %@", oldRoute);
            NSLog(@"Audio new route: %@", newRoute);
            NSLog(@"=========================================");
        }
    
    
    
    }
    
    + (NSString*) getAudioSessionInput {
        UInt32 routeSize;
        AudioSessionGetPropertySize(kAudioSessionProperty_AudioRouteDescription, &routeSize);
        CFDictionaryRef desc; // this is the dictionary to contain descriptions
    
        // make the call to get the audio description and populate the desc dictionary
        AudioSessionGetProperty (kAudioSessionProperty_AudioRouteDescription, &routeSize, &desc);
    
        // the dictionary contains 2 keys, for input and output. Get output array
        CFArrayRef outputs = CFDictionaryGetValue(desc, kAudioSession_AudioRouteKey_Inputs);
    
        // the output array contains 1 element - a dictionary
        CFDictionaryRef diction = CFArrayGetValueAtIndex(outputs, 0);
    
        // get the output description from the dictionary
        CFStringRef input = CFDictionaryGetValue(diction, kAudioSession_AudioRouteKey_Type);
        return [NSString stringWithFormat:@"%@", input];
    }
    
    + (NSString*) getAudioSessionOutput {
        UInt32 routeSize;
        AudioSessionGetPropertySize(kAudioSessionProperty_AudioRouteDescription, &routeSize);
        CFDictionaryRef desc; // this is the dictionary to contain descriptions
    
        // make the call to get the audio description and populate the desc dictionary
        AudioSessionGetProperty (kAudioSessionProperty_AudioRouteDescription, &routeSize, &desc);
    
        // the dictionary contains 2 keys, for input and output. Get output array
        CFArrayRef outputs = CFDictionaryGetValue(desc, kAudioSession_AudioRouteKey_Outputs);
    
        // the output array contains 1 element - a dictionary
        CFDictionaryRef diction = CFArrayGetValueAtIndex(outputs, 0);
    
        // get the output description from the dictionary
        CFStringRef output = CFDictionaryGetValue(diction, kAudioSession_AudioRouteKey_Type);
        return [NSString stringWithFormat:@"%@", output];
    }
    
    + (NSString*) getAudioSessionRoute {
        /*
         returns the current session route:
         * ReceiverAndMicrophone
         * HeadsetInOut
         * Headset
         * HeadphonesAndMicrophone
         * Headphone
         * SpeakerAndMicrophone
         * Speaker
         * HeadsetBT
         * LineInOut
         * Lineout
         * Default
        */
    
        UInt32 rSize = sizeof (CFStringRef);
        CFStringRef route;
        AudioSessionGetProperty (kAudioSessionProperty_AudioRoute, &rSize, &route);
    
        if (route == NULL) {
            NSLog(@"Silent switch is currently on");
            return @"None";
        }
        return [NSString stringWithFormat:@"%@", route];
    }
    
    @end
    

    【讨论】:

      猜你喜欢
      • 2022-09-26
      • 2014-10-31
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多