我的地址: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);
效果:
源代码地址