公司项目需要开发一个类似QQ、微信的即时IM聊天功能,做到实时监控消息,需要用的技术是websocket,今天整理下语言聊天这块;其实语言聊天,包含两部分,录音和音乐播放,关于简单语言聊天功能如下图:
录音
在AVFoundation框架中有一个AVAudioRecorder类专门处理录音操作,它同样支持多种音频格式。与AVAudioPlayer类似,你完全可以将它看成是一个录音机控制类,下面是常用的属性和方法:
先来了解下AVAudioRecorder的常用属性:
@property (readonly, getter=isRecording) BOOL recording;//是否正在录音 @property (readonly) NSDictionary<NSString *, id> *settings;//录音配置 @property (readonly) NSURL *url;//录音文件存放URL @property (readonly) NSTimeInterval currentTime;//录音时长 @property (getter=isMeteringEnabled) BOOL meteringEnabled;//是否监控声波
常用对象方法:
- (BOOL)prepareToRecord;//为录音准备缓冲区 - (BOOL)record;//录音开始,暂停后调用会恢复录音 - (BOOL)recordAtTime:(NSTimeInterval)time;//在指定时间后开始录音 - (BOOL)recordForDuration:(NSTimeInterval) duration;//按指定时长录音 - (BOOL)recordAtTime:(NSTimeInterval)time forDuration:(NSTimeInterval)duration;//上面2个的合体 - (void)pause; //中断录音 - (void)stop; //停止录音 - (BOOL)deleteRecording;//删除录音,必须先停止录音再删除
常用的代理方法:
//录音完成后调用 - (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag;//录音编码发送错误时调用 - (void)audioRecorderEncodeErrorDidOccur:(AVAudioRecorder *)recorder error:(NSError *)error;
音频
如果播放较大的音频或者要对音频有精确的控制则System Sound Service可能就很难满足实际需求了,通常这种情况会选择使用AVFoundation.framework中的AVAudioPlayer来实现。AVAudioPlayer可以看成一个播放器,它支持多种音频格式,而且能够进行进度、音量、播放速度等控制
AVAudioPlayer的使用比较简单:
1.初始化AVAudioPlayer对象,此时通常指定本地文件路径。
2.设置播放器属性,例如重复次数、音量大小等。
3.调用play方法播放。
具体实现代码
#import <AVFoundation/AVFoundation.h> #define kRecordAudioFile @"myRecord.caf" @interface ViewController ()<AVAudioRecorderDelegate> { NSString *dateName; } @property (weak, nonatomic) IBOutlet UITableView *table; @property (nonatomic,strong) AVAudioRecorder *audioRecorder;//音频录音机 @property (nonatomic,strong) AVAudioPlayer *audioPlayer;//音频播放器,用于播放录音文件 @property(nonatomic,strong) NSMutableArray *spaceData; @end @implementation ViewController #pragma mark - 私有方法 /** * 设置音频会话 */ -(void)setAudioSession{ AVAudioSession *audioSession=[AVAudioSession sharedInstance]; //设置为播放和录音状态,以便可以在录制完之后播放录音 [audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil]; [audioSession setActive:YES error:nil]; } /** * 取得录音文件设置 * * @return 录音设置 */ -(NSDictionary *)getAudioSetting{ NSMutableDictionary *dicM=[NSMutableDictionary dictionary]; //设置录音格式 [dicM setObject:@(kAudioFormatLinearPCM) forKey:AVFormatIDKey]; //设置录音采样率,8000是电话采样率,对于一般录音已经够了 [dicM setObject:@(8000) forKey:AVSampleRateKey]; //设置通道,这里采用单声道 [dicM setObject:@(1) forKey:AVNumberOfChannelsKey]; //每个采样点位数,分为8、16、24、32 [dicM setObject:@(8) forKey:AVLinearPCMBitDepthKey]; //是否使用浮点数采样 [dicM setObject:@(YES) forKey:AVLinearPCMIsFloatKey]; //....其他设置等 return dicM; } /** * 取得录音文件保存路径 * * @return 录音文件路径 */ -(NSURL *)getPlayPath:(NSString *)title{ // static int index = 0; NSString *urlStr=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; urlStr=[urlStr stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%@",title,kRecordAudioFile]]; NSLog(@"play file path:%@",urlStr); NSURL *url=[NSURL fileURLWithPath:urlStr]; return url; } /** * 以日期为title,来保存录音 * * @return <#return value description#> */ - (NSString *) convertDateFromString { NSDate *date = [NSDate date]; // NSLog(@"%@--askl",date); // NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; //zzz表示时区,zzz可以删除,这样返回的日期字符将不包含时区信息。 [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; NSString *destDateString = [dateFormatter stringFromDate:date]; return destDateString; }
长按录音,松开停止
- (void)setClikeSpaceState:(NSString *)aState { NSLog(@"点击语音---"); if([aState isEqualToString:@"begin"]) { NSLog(@"begin---"); dateName = [self convertDateFromString]; //创建录音文件保存路径 NSURL *url=[self getPlayPath:dateName]; //创建录音格式设置 NSDictionary *setting=[self getAudioSetting]; //创建录音机 NSError *error=nil; _audioRecorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:&error]; _audioRecorder.delegate=self; _audioRecorder.meteringEnabled=YES;//如果要监控声波则必须设置为YES if (![self.audioRecorder isRecording]) { [self.audioRecorder record];//首次使用应用时如果调用record方法会询问用户是否允许使用麦克风 // self.timer.fireDate=[NSDate distantPast]; NSLog(@"111"); } }else { NSLog(@"end---"); /** 停止录音*/ [self.audioRecorder stop]; /** 录音地址*/ NSURL *url = [self getPlayPath:dateName]; /** 加载数据*/ AVAudioPlayer *audioPlayer1 = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; Model *model = [[Model alloc]init]; model.duration = [NSString stringWithFormat:@"%.f",audioPlayer1.duration]; model.spacePath = dateName; /** table 刷新*/ [self.spaceData addObject:model]; [self.table reloadData]; /** table 滚动到当前row*/ [self.table selectRowAtIndexPath:[NSIndexPath indexPathForRow:(self.spaceData.count - 1) inSection:0] animated:YES scrollPosition:UITableViewScrollPositionTop]; } }
点击table 播放
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ Model *model = self.spaceData[indexPath.row]; /** 播放录音*/ NSURL *url=[self getPlayPath:model.spacePath]; NSError *error=nil; _audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error]; _audioPlayer.numberOfLoops=0; [_audioPlayer prepareToPlay]; [self.audioPlayer play]; NSLog(@"%.0f---aaaa",_audioPlayer.duration); /** UIImage动画数组*/ NSMutableArray *imgData = [NSMutableArray array]; for(int i=0;i<4;i++) { UIImage *aImage = [UIImage imageNamed:[NSString stringWithFormat:@"chat_receiver_audio_playing00%d",i]]; [imgData addObject:aImage]; } TwoTableViewCell *twoCell = [self.table cellForRowAtIndexPath:indexPath]; /** 点击动画*/ [twoCell.speak setAnimationImages:imgData]; // [twoCell.speak setAnimationRepeatCount:1]; [twoCell.speak setAnimationDuration:1]; [twoCell.speak startAnimating]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)([model.duration intValue] * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [twoCell.speak stopAnimating]; }); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本示例将演示如何使用 easySwoole 进行WebSocket聊天室开发,阅读本篇前,请先阅读文档相关部分。 本示例依赖Redis,请自行安装Redis及Redis扩展 本文所有文件命名空间及文件结构请自行根据业务情况修改。 一、创建WebSocket服务器 配置Config.php 在easySwoole的根目录中,Config.php是easySwoole的配置文件,可以使用Config对
本文向大家介绍基于Node.js + WebSocket打造即时聊天程序嗨聊,包括了基于Node.js + WebSocket打造即时聊天程序嗨聊的使用技巧和注意事项,需要的朋友参考一下 前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术。像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端。瞬间就有了一统天下的感觉,来往穿梭于前后端之间代码
本文向大家介绍使用WebSocket实现即时通讯(一个群聊的聊天室),包括了使用WebSocket实现即时通讯(一个群聊的聊天室)的使用技巧和注意事项,需要的朋友参考一下 随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端
本文向大家介绍基于进程内通讯的python聊天室实现方法,包括了基于进程内通讯的python聊天室实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了基于进程内通讯的python聊天室实现方法。分享给大家供大家参考。具体如下: 希望本文所述对大家的Python程序设计有所帮助。
本文向大家介绍php基于websocket搭建简易聊天室实践,包括了php基于websocket搭建简易聊天室实践的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php基于websocket搭建简易聊天室实践。分享给大家供大家参考。具体如下: 1、前言 公司游戏里面有个简单的聊天室,了解了之后才知道是node+websocket做的,想想php也来做个简单的聊天室。于是搜集各种资料看文档、
日期: 2019-11-19 创盛视联数码科技(北京)有限公司 聊天组件的核心类是CCChatManager; //在工程需要的地方引入头文件 #import <CCChatLibrary/CCChatLibrary.h> //1、类的实例化 + (instancetype)sharedChat; //2、与BaseSDK建立联系 - (void)addBasicClient:(CCStrea