使用unity的Microphone接口进行录音时遇到的相关问题

问题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 换成#import ,错误就消失了。

#import 

@interface AVAudioSession (AddAction)

@end

本人也是初次接触unity交互,这个解决办法暂时还不清楚会不会引起其他的问题,应该是不适用于必须将Action设置为NO的项目,如有更好解决办法还请多赐教。



问题2:背景音乐变轻

问题描述:当开启Microphone.Start时,背景音乐播放从扬声器变成了听筒。

解决办法:开启Microphone.Start时,再把听筒变成扬声器

#import 




void _forceToSpeaker();
bool _headsetConnected();

#import "iPhoneSpeaker.h"
#import 




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.



你可能感兴趣的:(unity)