ios 将音频输出重定向到电话扬声器,将麦克风输入重定向到耳机
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5931799/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Redirecting audio output to phone speaker and mic input to headphones
提问by user744412
Is it possible to redirect audio output to the phone speaker and still use the microphone headphone input?
是否可以将音频输出重定向到电话扬声器并仍然使用麦克风耳机输入?
If i redirect the audio route to the phone speaker instead of the headphones it also redirects the mic. This makes sense but I can't seem to just be able to just redirect the mic input? Any ideas?
如果我将音频路由重定向到电话扬声器而不是耳机,它也会重定向麦克风。这是有道理的,但我似乎不能只是重定向麦克风输入?有任何想法吗?
Here is the code I'm using to redirect audio to the speaker:
这是我用来将音频重定向到扬声器的代码:
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);
回答by jocull
This is possible, but it's picky about how you set it up.
这是可能的,但对如何设置它很挑剔。
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
It's very important to use AVAudioSessionCategoryPlayAndRecord
or the route will fail to go to the speaker. Once you've set the override route for the audio session, you can use an AVAudioPlayer
instance and send some output to the speaker.
使用非常重要,AVAudioSessionCategoryPlayAndRecord
否则路由将无法到达扬声器。为音频会话设置覆盖路由后,您可以使用AVAudioPlayer
实例并将一些输出发送到扬声器。
Hope that works for others like it did for me. The documentation on this is scattered, but the Skype app proves it's possible. Persevere, my friends! :)
希望别人喜欢它为我做了工作的。这方面的文档很分散,但 Skype 应用程序证明这是可能的。坚持下去,我的朋友们!:)
Some Apple documentation here: http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/AudioSessionServicesReference/Reference/reference.html
这里有一些 Apple 文档:http: //developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/AudioSessionServicesReference/Reference/reference.html
Do a search on the page for kAudioSessionProperty_OverrideAudioRoute
在页面上搜索 kAudioSessionProperty_OverrideAudioRoute
回答by Alex L
It doesn't look like it's possible, I'm afraid.
恐怕这看起来不太可能。
From the Audio Session Programming Guide- kAudioSessionProperty_OverrideAudioRoute
来自音频会话编程指南- kAudioSessionProperty_OverrideAudioRoute
If a headset is plugged in at the time you set this property's value to kAudioSessionOverrideAudioRoute_Speaker, the system changes the audio routing for input as well as for output: input comes from the built-in microphone; output goes to the built-in speaker.
如果在将此属性的值设置为 kAudioSessionOverrideAudioRoute_Speaker 时插入了耳机,则系统会更改输入和输出的音频路由:输入来自内置麦克风;输出到内置扬声器。
Possible duplicate of this question
这个问题的可能重复
回答by loretoparisi
What you can do is to force audio output to speakers in any case:
您可以做的是在任何情况下强制音频输出到扬声器:
From UI Hacker - iOS: Force audio output to speakers while headphones are plugged in
来自UI Hacker - iOS:插入耳机时强制音频输出到扬声器
@interface AudioRouter : NSObject
+ (void) initAudioSessionRouting;
+ (void) switchToDefaultHardware;
+ (void) forceOutputToBuiltInSpeakers;
@end
and
和
#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 Hyman
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