我的地址:http://blog.csdn.net/jinglijun/article/details/9633121
最近要开发一个类似微信的demo,需要支持用户语音对话,这个客户端有IOS版本和Android版本,要完成语音通信功能,
在网上看了下资料,类似这类产品使用的技术
talkbox Android版用的是ilbc的第三方编解码库,在iPhone上用的是caf
微信 Android版估计是amr估计转码的是交给腾讯强大的服务器了。
米聊 Android版和Iphone版用的都是speex
目前支持的开源第三方库有:libopencore_amr,ilbc和speex
考虑采用的方案:
speex需要Android和ios都进入转码,工作量太大,不采用。剩下的方案就是在amr和ilbc上选择了,android支持amr,低版本不支持ilbc, ios高版本(4.3)只支持ilbc,不能支持amr。刚开始的测试方案使用的是android将语音转ilbc,由于我对于android开发不是太熟悉,在同事的帮助下一直没有转换成功,现在想想可能是处理问题,如果能转换成或,这种方案应该是最方便的。
ios不支持amr,android原生也不支持aac,而且aac文件比amr大大概10倍,最终由于进度情况,决定通用amr的方案,因为毕竟amr比较小巧。那么ios就要完成录制后把wav然后使用libopencore库将其编成amr格式,这时可以发送给android端播放了。
现在发现一个问题,Android录制的AMR格式音频,在IOS4.3一下可以播放,使用AVAudioPlayer就可以。但是在IOS4.3上却无法播放。AVAudioPlayer的play始终返回NO。所以先将android版本发送过来的amr解码出来播放原始wav即可。
在网上找到类似的源代码修改了下,比如code4app。oschina都有这样的demo。但是这些demo 有些小问题,我用itouch测试,录音播放没问题,但是用iphone 录音 后播放声音好小啊,听不见,然后着了下原因,设置用Speaker 输出就好了“kAudioSessionOverrideAudioRoute_Speaker”
然后我还添加了类似微信录音时的分贝监测。
-(bool) LoudSpeaker:(bool)bOpen
{
//return false;
UInt32 route;
OSStatus error;
UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord; // 1
error = AudioSessionSetProperty (
kAudioSessionProperty_AudioCategory, // 2
sizeof (sessionCategory), // 3
&sessionCategory // 4
);
route = bOpen?kAudioSessionOverrideAudioRoute_Speaker:kAudioSessionOverrideAudioRoute_None;
error = AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(route), &route);
return true;
}
下面的方法也是设置输出频道
// Set AudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
/* Pick any one of them */
// 1. Overriding the output audio route
//UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
//AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);
// 2. Changing the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker, sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);
效果: