app语音聊天方案
来源:互联网 发布:java遍历json 编辑:程序博客网 时间:2024/06/10 02:31
目前,市面上的语音聊天方案很多,但是大多按日活跃收费,算下来很不划算。如果自己做,带宽的压力又大,花费更多。
可以使用oss来做,目前提供这种服务的有阿里云,七牛云,腾讯云等。即将语音在本地app录好后进行压缩,再上传到oss,然后app服务端将存有语音的oss地址发到同一个房间,或者同一个工会的人,然后其他人就根据这个地址到oss去下载语音进行播放。
这个方案既可以android平台,也可以在ios平台使用,唯一不同的是android平台是把wav压缩成mp3,ios是把aac压缩成mp3,但是都是使用lame库进行压缩
以ios/七牛为例,将这些功能封装成了一个sdk,另外,因为没有将全部代码拿出来,所以单纯看下面的代码,里面可能有一些变量没有声明,或者一些函数没有实现等等,但是大部分逻辑都包含了。
- 初始化
- 开始录音
- 停止录音并压缩成mp3
- 播放
- 上传七牛oss
- 下载
初始化:
- (int)initSdk{ if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) { //7.0第一次运行会提示,是否允许使用麦克风 AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *sessionError; //AVAudioSessionCategoryPlayAndRecord用于录音和播放 [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError]; if(session == nil) NSLog(@"Error creating session: %@", [sessionError description]); else [session setActive:YES error:nil]; } return 0;}
开始录音
-(void)startRecord:(NSString*)name{//配置录音参数 NSDictionary* recorderSettingsDict =[[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithInt:AVAudioQualityMin],AVEncoderAudioQualityKey, [NSNumber numberWithInt:44100],AVSampleRateKey, [NSNumber numberWithInt:2],AVNumberOfChannelsKey, [NSNumber numberWithInt:16],AVEncoderBitRateKey, nil]; if ([self canRecord]) { //用canRecord判断麦克风是否打开等等 NSError *error = nil; NSString *documentPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0]; //设置录音文件的路径 NSString *FileName=[documentPath stringByAppendingPathComponent:TEMP_RECORD_FILE]; _mRecorder = [[AVAudioRecorder alloc] initWithURL:[NSURL URLWithString:FileName] settings:recorderSettingsDict error:&error]; if (_mRecorder) { _mFileName = [[NSString alloc] initWithString:name]; _mRecorder.meteringEnabled = YES; [_mRecorder prepareToRecord]; [_mRecorder record]; } else { int errorCode = CFSwapInt32HostToBig ([error code]); NSLog(@"Error: %@ [%4.4s])" , [error localizedDescription], (char*)&errorCode); } }}-(BOOL)canRecord{ __block BOOL bCanRecord = YES; if ([[[UIDevice currentDevice] systemVersion] compare:@"7.0"] != NSOrderedAscending) { AVAudioSession *audioSession = [AVAudioSession sharedInstance]; if ([audioSession respondsToSelector:@selector(requestRecordPermission:)]) { [audioSession performSelector:@selector(requestRecordPermission:) withObject:^(BOOL granted) { if (granted) { bCanRecord = YES; } else { bCanRecord = NO; dispatch_async(dispatch_get_main_queue(), ^{ [[[UIAlertView alloc] initWithTitle:nil message:@"app需要访问您的麦克风。\n请启用麦克风-设置/隐私/麦克风" delegate:nil cancelButtonTitle:@"关闭" otherButtonTitles:nil] show]; }); } }]; } } return bCanRecord;}
停止录音,并压缩成mp3
-(void)stopRecord{ [_mRecorder stop]; _mRecorder = nil; if([self PCMtoMp3:_mFileName]){ // success, you can do something, eg. upload the .mp3 to qiniu oss }else{ // failed }}-(bool)PCMtoMp3:(NSString*)name{ NSString *documentPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0]; NSString *cafFilePath = [documentPath stringByAppendingPathComponent:TEMP_RECORD_FILE];// NSString *mp3FilePath=[documentPath stringByAppendingPathComponent:name];//存储mp3文件的路径 NSFileManager* fileManager=[NSFileManager defaultManager]; if([fileManager removeItemAtPath:mp3FilePath error:nil]) { NSLog(@"删除"); } @try { int read, write; FILE *pcm = fopen([cafFilePath cStringUsingEncoding:1], "rb"); //source 被转换的音频文件位置 if(pcm == NULL) { NSLog(@"file not found"); } else { fseek(pcm, 4*1024, SEEK_CUR); //skip file header FILE *mp3 = fopen([mp3FilePath cStringUsingEncoding:1], "wb"); //output 输出生成的Mp3文件位置 const int PCM_SIZE = 8192; const int MP3_SIZE = 8192; short int pcm_buffer[PCM_SIZE*2]; unsigned char mp3_buffer[MP3_SIZE]; lame_t lame = lame_init(); //设置压缩参数 lame_set_num_channels(lame,1);//设置1为单通道,默认为2双通道 lame_set_in_samplerate(lame, 44100.0);//11025.0 lame_set_VBR(lame, vbr_default); lame_set_brate(lame,8); //lame_set_mode(lame,3); lame_set_quality(lame,2); /* 2=high 5 = medium 7=low 音质*/ lame_init_params(lame); do { read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm); if (read == 0){ write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE); } else{ write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE); } fwrite(mp3_buffer, write, 1, mp3); } while (read != 0); lame_close(lame); fclose(mp3); fclose(pcm); return YES; } return NO; } @catch (NSException *exception) { NSLog(@"%@",[exception description]); return NO; }@finally { NSLog(@"执行完成"); }}
播放
-(void)playRecord:(NSString*)name{ NSString *documentPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0]; NSString *filePath = [documentPath stringByAppendingPathComponent:name]; NSURL* url = [NSURL URLWithString:filePath]; _mPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [_mPlayer play];}
上传七牛oss
这个里面用到了七牛的sdk,具体可以参考七牛官网
-(NSString*) storeOnCloud:(NSString*)filePath withCloudPath:(NSString*)cloudPath withToken:(NSString*)token{ _mUrlUploadId=[[NSString alloc] initWithString:StringUtil::getTimestamp()]; //根据文件名生成路径 NSString *documentPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0]; NSString *FileName=[documentPath stringByAppendingPathComponent:filePath]; //上传文件 QNUploadManager *upManager = [[QNUploadManager alloc] init]; [upManager putFile:FileName key:cloudPath token:token complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) { if(info.ok){ // upload success } else{ // upload failed } NSLog(@"%@", info); NSLog(@"%@", resp); [_mUrlUploadId release]; _mUrlUploadId = nil; } option:nil]; return _mUrlUploadId;}
下载
就是普通的url下载,使用NSURLRequest NSURLConnection ,并实现NSURLConnectionDataDelegate 即可,需要注意的是下载的文件应该存在
NSString *documentPath =[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0]; NSString *FileName=[documentPath stringByAppendingPathComponent:_mUrlDownloadFilePath];
其实在上面的很多函数中都用到过,这个documentPath就是ios为每个app准备的空间,专门用于存放app的一些数据/配置文件等等
0 0
- app语音聊天方案
- 语音聊天
- 语音聊天
- 语音聊天
- 仿微信语音语音聊天
- 语音方案
- android 局域网实时语音聊天音频流用什么编解码方案?
- java语音聊天程序
- 语音聊天实现(Delphi)
- 实现语音聊天
- C++实现语音聊天
- C# 语音聊天系统
- 语音聊天机器人
- 谈谈语音视频聊天
- LAN 语音聊天
- IOS语音聊天实现
- Android实时语音聊天
- IM语音聊天
- PAT 1042. Shuffling Machine (20)
- 108-记录锁(继承与释放)
- tensorflow 函数接口的理解
- 有效括号
- Java多线程系列--“基础篇”03之 Thread中start()和run()的区别
- app语音聊天方案
- 关于游戏制作过程中遇到的几个问题记录
- Activity启动流程(源码分析)
- 赋值运算符函数
- 关于我
- HTML+CSS基础入门-第四天(HTML-图片标记)
- java程序设计测试题
- C++函数重定义、重载、重写
- 牛客网[编程题] DNA合成(Java实现)