cocos2dx之 android/ios语音交互(二)

前端之家收集整理的这篇文章主要介绍了cocos2dx之 android/ios语音交互(二)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

经过一番折腾,终于找到了一种第三方库来转换android与iOS录音播放格式不兼容的问题。
思路:android/iOS手机录音传给服务器,参数(录音数据+手机端口类型),然后等到服务器广播数据给玩家,判断端口是android,将数据保存为为.amr格式,否则保存为.aac格式。不同手机端口调用相应端口函数
1、设置端口录音格式:
android–>.amr

  1. public void record(){
  2. if (isRecording == true ) return;
  3.  
  4. recondPath = Environment.getExternalStorageDirectory().getAbsolutePath();
  5. recondPath += "/ione1.amr"; //录音格式
  6.  
  7. File dirs = new File(recondPath);
  8. if (dirs.exists()){
  9. dirs.delete();
  10. }
  11.  
  12. stopRecorder();
  13. isRecording = true;
  14.  
  15. mRecorder = new MediaRecorder();
  16. //设置音源为Micphone
  17. mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
  18. //设置封装格式
  19. mRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
  20. //设置编码格式
  21. mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  22. mRecorder. setAudioEncodingBitRate(8);//设置音频编码录音比特率
  23. mRecorder.setAudioChannels(1);//设置录制的音频通道数
  24. mRecorder.setAudioSamplingRate(8000); //设置音频采样率记录
  25. mRecorder.setOutputFile(recondPath);
  26.  
  27. try {
  28. mRecorder.prepare();
  29. } catch (IOException e) {
  30. Log.e(TAG,"prepare() Failed");
  31. }
  32. //录音
  33. mRecorder.start();
  34. }
  35. public boolean stopRecorder() {
  36. if( mRecorder == null ) return false;
  37.  
  38. try{
  39. mRecorder.stop();
  40. mRecorder.reset();
  41. mRecorder.release();
  42. mRecorder = null;
  43. }catch ( IllegalStateException e){
  44. e.printStackTrace();
  45. }
  46.  
  47. return false;
  48. }

ios–>.aac

  1. -(void)startAudioRecording
  2. {
  3. if(!isRecording)
  4. {
  5. [self init];
  6.  
  7. isRecording = YES;
  8. NSLog(@"正在录音");
  9.  
  10. NSMutableDictionary *dicM=[NSMutableDictionary dictionary];
  11. //设置录音格式
  12. [dicM setObject:@(kAudioFormatMPEG4AAC) forKey:AVFormatIDKey];//录音格式
  13. //设置录音采样率,8000是电话采样率,对于一般录音已经够了
  14. [dicM setObject:@(1600) forKey:AVSampleRateKey];
  15. //设置通道,这里采用单声道
  16. [dicM setObject:@(1) forKey:AVNumberOfChannelsKey];
  17. //每个采样点位数,分为8、16、24、32
  18. [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey];
  19. //录音的质量
  20. [dicM setValue:[NSNumber numberWithInt:AVAudioQualityMin] forKey:AVEncoderAudioQualityKey];
  21. //是否使用浮点数采样
  22. [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey];
  23.  
  24. recorder = [[AVAudioRecorder alloc] initWithURL:recordedFile settings:dicM error:nil];
  25.  
  26. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
  27. [[AVAudioSession sharedInstance] setActive:YES error:nil];
  28. [self setSoundSession];
  29. [recorder peakPowerForChannel:0];
  30.  
  31. [recorder prepareToRecord];
  32. [recorder record];
  33. }
  34. }

2、接收服务器传来的需要播放的录音数据,根据不同端口录的音保存为数据相同录音格式:
android–>.amr
ios–>.aac

  1. //服务器传来录音数据,保存在表voiceTab中 //voiceTab[index] = event.data
  2. function MainScene:startPlayVoice()
  3. if self.isStartRecond == false then -- 没有在录音
  4. if device.platform == "android" or device.platform == "ios" then --播放录音
  5. local len = #voiceTab
  6. if len >= 1 then
  7. voicePlay( data )
  8. else
  9. print(" 录音播放完了 ")
  10. end
  11. end
  12. end
  13. end
  1. function voicePlay(data)
  2. if device.platform == "android" then
  3. local function callback(result)
  4. -- print("录音播放完成 " )
  5. ReturnRecordingPlayChange(result)
  6. end
  7.  
  8. local path = writefileCheckRecond( data.voicebin,data.content )
  9. print("开始播放了 voicePlay ")
  10. local args = { 1,path,callback }
  11. local sigs = "(ILjava/lang/String;I)I"
  12. local luaj = require "cocos.cocos2d.luaj"
  13. local className = "com/cocos2dx/sample/LuaJavaBridge"
  14. local ok,ret = luaj.callStaticMethod(className,"sendLuaToJavaAudioRecorPlay",args,sigs)
  15. if not ok then
  16. print("luaj error:",ret)
  17. else
  18. print("The ret is:",ret)
  19. end
  20. elseif device.platform == "ios" then
  21. local path = writefileCheckRecond( data.voicebin,data.content )
  22. print("开始播放了 voicePlay ",path)
  23. local i = iosAudioStartPlay( path )
  24. end
  25. end
  1. function writefileCheckRecond( data,platform )
  2. local path = device.writablePath.."netSprite/" --获取本地存储目录
  3. if not io.exists(path) then
  4. lfs.mkdir(path) --目录不存在,创建此目录
  5. end
  6.  
  7. if platform == "android" then
  8. path = path.."recond.amr"
  9. elseif platform == "ios" then
  10. path = path.."recond.aac"
  11. else
  12. return;
  13. end
  14.  
  15. print("写入完成:"..path)
  16.  
  17. return path;
  18. end

3、分析两端口录音互相播放的情况(A端口录音–>B端口播放)
android–>android:android玩家录音为.amr传给服务器,android玩家接收录音二进制数据保存的也是.amr格式,播放OK。

  1. public void startPlay(String filePath,int luaFunc){
  2. if( isPlay == true)
  3. {
  4. Log.d("tag","正在播放中");
  5. return;
  6. }
  7.  
  8. try {
  9. stopPlay();
  10.  
  11. isPlay = true;
  12. playLuaFun = luaFunc;
  13.  
  14. mPlayer = MediaPlayer.create(Cocos2dxActivity.getInstance(),Uri.parse(filePath));
  15. mPlayer.start();// 开始播放
  16.  
  17. mPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
  18. @Override
  19. public void onCompletion(MediaPlayer m) {
  20. Log.d("tag","播放完毕");
  21. LuaJavaBridge.callbackLuaFun("1","ReturnRecordingPlayChange",index++);
  22. buySuccessJava(1);
  23. Log.d(TAG,"playLuaFun = " + playLuaFun);
  24.  
  25. isPlay = false;
  26. stopPlay();
  27. }
  28. });
  29.  
  30. }catch(Exception e){
  31. Log.e(TAG,"prepare() Failed");
  32. }
  33. }

android–>iOS:android玩家录音为.amr传给服务器,iOS玩家接收录音二进制数据保存为.amr格式,调用第三方库将格式.amr转.mav格式就播放OK。

  1. -(void)playAudio
  2. {
  3. if(!isPlay)
  4. {
  5. if([player isPlaying])
  6. {
  7. NSLog(@"停止录音播放");
  8. [player pause];
  9. }
  10. else
  11. {
  12. NSString *documentsDirectory= [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
  13. audioRecoderSavePath=[NSString stringWithFormat:@"%@/%@",documentsDirectory,@"netSprite/"];
  14. recoderName= [NSString stringWithFormat:@"%@",@"recond.amr"];
  15. tempRecoderPath=[NSString stringWithFormat:@"%@%@",audioRecoderSavePath,recoderName];
  16.  
  17. fm = [NSFileManager defaultManager]; //创建文件管理对象
  18. if([fm fileExistsAtPath:tempRecoderPath] == NO)//判断文件是否存在
  19. {
  20. NSLog(@"文件不存在");
  21.  
  22. recoderName= [NSString stringWithFormat:@"%@",@"recond.aac"];
  23. tempRecoderPath=[NSString stringWithFormat:@"%@%@",recoderName];
  24. isIos = true;
  25. [self startPlayAudio];
  26. return;
  27. }
  28. else
  29. {
  30. isIos = false;
  31. NSLog(@"文件存在");
  32. }
  33.  
  34. NSString *recoderWavName= [NSString stringWithFormat:@"%@",@"recond.wav"];
  35. tempWavRecoderPath =[NSString stringWithFormat:@"%@%@",recoderWavName];
  36. //第三方库AudioConverter
  37. [AudioConverter convertAmrToWavAtPath:tempRecoderPath wavSavePath:tempWavRecoderPath asynchronize:YES completion:^(BOOL success,NSString * _Nullable resultPath) {
  38. if (success) {
  39. NSLog(@"amr转wav成功!");
  40.  
  41. _wavFilePath = resultPath;
  42.  
  43. [self startPlayAudio];
  44. } else {
  45. NSLog(@"amr转wav失败!");
  46. }
  47. }];
  48. }
  49. }
  50. }

iOS –>android:ios玩家录音为.aac格式传给服务器,android玩家接收录音二进制数据保存为.aac格式,
android玩家播iOS录的.aac格式OK。

iOS–>iOS:ios玩家录音为.aac格式传给服务器,ios玩家接收录音二进制数据保存为.aac格式,ios玩家播iOS录的.aac格式OK。

参考:
http://www.jb51.cc/article/p-mcdpwusb-bpt.html
http://blog.csdn.net/adalu1986/article/details/50502387
http://www.jianshu.com/p/7dc01b48f8fc

猜你在找的Cocos2d-x相关文章