问题1:背景音乐没声音
问题描述:unity的界面展示需要背景音乐和录音的功能,当开启Microphone.Start时,背景音乐就没有声音了,是一直都不会再有声音;当切完后台回来后,就又有声音了。控制台打印的信息中觉得最可疑的就是:
错误信息: [avas] AVAudioSession.mm:1074:-[AVAudioSession setActive:withOptions:error:]: Deactivating an audio session that has running I/O. All I/O should be stopped or paused prior to deactivating the audio session.
然后就以这个问题为出发点在网上搜啊搜,又类似该问题的方法都试了,但是没有得到解决。
但是发现,引起上述错误信息的方法是将下面这个单例方法中的Action参数设置为NO:
[[AVAudioSession sharedInstance] setActive:<#(BOOL)#> withOptions:<#(AVAudioSessionSetActiveOptions)#> error:<#(NSError * _Nullable __autoreleasing * _Nullable)#>]
然后我在我的工程文件中重新写这个方法,将Action参数设置为YES,但是无济于事,也就是说,只要将Action设置为NO了,就已经出现上述错误了,再设置为YES也只是徒劳无功。
确定问题方向:Microphone.Start时,在某个地方调用了上面这个单例方法,将Action设置为NO了,所以就要讲设置为NO的地方找到并修改,unity也看不到代码,感觉又到了问题的尽头。
但是我发现setAction:这个方法是有返回值的,返回值类型是BOOL,那这个返回值是不是就是和setAction:的值一样的呢?于是抱着试一试的心理(万一成功了呢)做了一下操作:
首先:写一个AVAudioSession的分类,在这个分类的.m中重写这个类的setAction:方法,将该方法的返回值强制返回YES。
#import "AVAudioSession+AddAction.h"
@implementation AVAudioSession (AddAction)
- (BOOL)setActive:(BOOL)active withOptions:(AVAudioSessionSetActiveOptions)options error:(NSError * _Nullable __autoreleasing *)outError {
return YES;
}
@end
但是发现这个分类是继承自AVFAudio的,会报错,但是我们知道这个框架是继承自AVFoundation的,于是我讲.h中的#import <AVFAudio/AVFAudio.h>换成#import <AVFoundation/AVFoundation.h>,错误就消失了。
#import <AVFoundation/AVFoundation.h>
@interface AVAudioSession (AddAction)
@end
本人也是初次接触unity交互,这个解决办法暂时还不清楚会不会引起其他的问题,应该是不适用于必须将Action设置为NO的项目,如有更好解决办法还请多赐教。
问题2:背景音乐变轻
问题描述:当开启Microphone.Start时,背景音乐播放从扬声器变成了听筒。
解决办法:开启Microphone.Start时,再把听筒变成扬声器
#import <Foundation/Foundation.h>
void _forceToSpeaker();
bool _headsetConnected();
#import "iPhoneSpeaker.h"
#import <AVFoundation/AVFoundation.h>
void _forceToSpeaker() {
// want audio to go to headset if it's connected
if (_headsetConnected()) {
return;
}
OSStatus error;
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute,
sizeof(audioRouteOverride),
&audioRouteOverride);
if (error) {
NSLog(@"Audio already playing through speaker!");
} else {
NSLog(@"Forcing audio to speaker");
}
}
bool _headsetConnected() {
UInt32 routeSize = sizeof(CFStringRef);
CFStringRef route = NULL;
OSStatus error = AudioSessionGetProperty(kAudioSessionProperty_AudioRoute, &routeSize, &route);
if (!error &&
(route != NULL)&&
([(__bridge NSString*)route rangeOfString:@"Head"].location != NSNotFound))
{
/* don't think this is needed
see "the get rule":
https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-CJBEJBHH
*/
//CFRelease(route);
NSLog(@"Headset connected!");
return true;
}
return false;
}
Call iPhoneSpeaker.ForceToSpeaker() after completing recording and start playing recorded audio. In Build settings - player settings - prepare iOS for Recording - unchecked, to play audio's loudly in iphone device.
In Edit - Player settings - Audio - check audio setted as sterio or others instead of mono.