Cocos Creator 有内置的语音, 既然可以实现为什么不能自己实现呢? 好吧,实现开始. 对比了三端语音的格式最后选定M4A格式的音频. 总体的思路是直接传文件流, 直接播放文件流, 而不进行保存下载, 跳过不必要的下载保存流程, 这样语音播放更加流畅. 亲测很快. 与实时音视频几乎没有差别.
具体怎么来实现呢. Creator跟iOS互相调用可以看我之前的简书这里就不多说, 直接主题录制视频 上代码
- (void)startRecord{
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"text.caf"];
NSURL *url = [NSURL URLWithString:path];
// setting:录音的设置项
NSDictionary *configDic = @{// 编码格式
AVFormatIDKey:@(kAudioFormatLinearPCM),
// 采样率
AVSampleRateKey:@(8000),
// 通道数
AVNumberOfChannelsKey:@(1),
// 录音质量
AVEncoderAudioQualityKey:@(AVAudioQualityMin)
};
NSError *error = nil;
[[AVAudioSession sharedInstance]
// 在创建recorder之前加上这两行,可以解决播放无声音的问题
setCategory:@"AVAudioSessionCategoryPlayAndRecord" error:nil];
[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
_record = [[AVAudioRecorder alloc]initWithURL:url settings:configDic error:&error];
if (error) {
NSLog(@"error:%@",error);
}
// 准备录音(系统会给我们分配一些资源)
[_record prepareToRecord];
[self.record record];
NSLog(@"开始录音");
}
因为苹果录制的视频是caf格式, 所以需要对音频的格式进行转换,转换成M4A
- (NSString *)stopVideo{
if (self.record.currentTime > 2) {
[self.record stop];
} else {
// 删除录音文件
//如果想要删除录音文件,必须先停止录音
[self.record stop];
[self.record deleteRecording];
}
NSLog(@"结束录音");
NSString *pathuLu = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"text.caf"];
NSString *path1 = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"aaaa.m4a"];
[zhuanHuanM4a convetCafToM4a:pathuLu destUrl:path1 completed:^(NSError * _Nonnull error) {
NSData *mp3Data = [NSData dataWithContentsOfFile:path1];
NSString *data = [mp3Data base64Encoding];
std::string strRet1 = [data UTF8String];
std::string strRet = "onRecordFinish";
std::string jsCallStr = cocos2d::StringUtils::format("native2Cocos(\"%s\",'%s');", strRet.c_str(),strRet1.c_str());
se::Value *ret = new se::Value();
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"aaaa.m4a"];
NSFileManager*fileManager = [NSFileManager defaultManager];
[fileManager removeItemAtPath:path error:nil];
}];
return @"wait";
}
转换完成之后把文件流转成base64发给Creator
这样就完成了第一步, 把音频文件发给Creator. 然后经过Creator的广播把这段音频再分发给在这个房间的每一个人.
- (void)playVoiceData:(NSString *)data{
// Base64形式的字符串为data
NSData *videoMy = [[NSData alloc] initWithBase64EncodedString:data options:NSDataBase64DecodingIgnoreUnknownCharacters];
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
//默认情况下扬声器播放
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
self.player = [[AVAudioPlayer alloc] initWithData:videoMy error:nil];
self.player.numberOfLoops = 0;
self.player.delegate = self;
CGFloat currentVol = audioSession.outputVolume;
//设置播放器声音
self.player.volume = currentVol;
[self.player play];
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
std::string strRet = "onPlayFinish";
std::string jsCallStr = cocos2d::StringUtils::format("native2Cocos(\"%s\");", strRet.c_str());
se::Value *ret = new se::Value();
se::ScriptEngine::getInstance()->evalString(jsCallStr.c_str() , -1 , ret);
}
最后调取播放音频的方法把Creator给你传的文件流播放就可以了.
网友评论