可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I got the following code:
- (id)init {
if (self = [super init]) {
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
}
return self;
}
But somehow the sound does not want to come out of the speakers, can someone see what I am doing wrong?
The code I use for playing is:
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFilePathURL error:nil];
[player prepareToPlay];
[player setVolume:1.0];
[player play];
回答1:
I used the AudioToolbox framework that's why I initialized my audio session as following:
AudioSessionInitialize(NULL, NULL, NULL, NULL);
Here's the rest of my code that I used to configure the audio session. I didn't override the audio route and I also think this is not necessary.
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
OSStatus err = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory),
&sessionCategory);
AudioSessionSetActive(TRUE);
if (err) {
NSLog(@"AudioSessionSetProperty kAudioSessionProperty_AudioCategory failed: %d", err);
}
回答2:
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.
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! :)
Some Apple documentation here: http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/AudioSessionServicesReference/Reference/reference.html
Do a search on the page for kAudioSessionProperty_OverrideAudioRoute
回答3:
For iOS7 AudioSessionSetProperty is deprecated. The answer in the following post by foundry shows how to do this for iOS7:
https://stackoverflow.com/a/18808124/1949877
回答4:
Very good example here http://ruckt.info/playing-sound-through-iphone-speaker/ Solved my problem.
The method below - configureAVAudioSession - reroutes the audio to the main speakers in iOS 7.0. To do so, call it before playing the audio in this way: [self configureAVAudioSession]
.
- (void) configureAVAudioSession //To play through main iPhone Speakers
{
//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");
}
}
回答5:
I'm just going to clarify this for other readers of this post.
I was looking for the answer to this problem, specifically for the SpeakHere example. I grabbed this little chunk of code and it did the trick.
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty (kAudioSessionProperty_OverrideAudioRoute,sizeof (audioRouteOverride),&audioRouteOverride);
I hope this is not too much of a digression. I just thought it would be good for those who just need these two little statements.
回答6:
You're code for playing the sound looks correct, and there's no reason you should have to use AudioToolbox. One thing you might want to make sure of is that you are using supported audio formats. (I personally have had success with MP3 and WAV)
Also, could you share with us your code as to how you get the url to your sound file?
回答7:
While the other answers do provide the desired effect of playing audio on the speaker instead of the receiver, they are not the idiomatic way to achieve that goal.
One should rather use the AVAudioSessionCategoryOption
(what a mouthful) DefaultToSpeaker
. The documentation for that reads (emphasis mine):
When using this option and no other audio route (such as a headset) is available, session audio will play through the device’s built-in speaker. When not using this option, and no other audio output is available or selected, audio will play through the receiver (a speaker intended to be held to the ear). Note that only iPhone devices are equipped with a receiver; on iPad and iPod touch devices, this option has no effect.
To use this, change your call to setCategory:
to pass the option, like this:
let session = AVAudioSession.sharedInstance()
try session.setCategory(AVAudioSessionCategoryPlayAndRecord, withOptions: [.DefaultToSpeaker])
回答8:
Try this:
NSError *error;
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
if(error) {
NSLog(@"STKAudioManager: AudioSession cannot use speakers");
}