首先,导入讯飞语音库(友情提示在讯飞语音官方平台申请过的识别次数无上限,没有申请过的app每日500次),在delegate.m注册讯飞语音appKey,然后接入如下:
.h文件.
#import <UIKit/UIKit.h>
#import "IATConfig.h"
#import "ISRDataHelper.h"
#import <iflyMSC/iflyMSC.h>
@class IFlySpeechRecognizer;
@interface ListenView : UIView<IFlySpeechRecognizerDelegate,UIGestureRecognizerDelegate>
//显示的文本框
@property(strong,nonatomic)UILabel *WordsLB;
//麦克风图标
@property(strong,nonatomic)UIButton*IconBtn;
//提示:按住说话
@property(strong,nonatomic)UILabel*TipLB;
//确定
@property(strong,nonatomic)UIButton *SureBtn;
//删除
@property(strong,nonatomic)UIButton *ClearBtn;
//讯飞语音要求接入的lb,好扯淡的审核
@property(strong,nonatomic)UILabel *XFTipLB;
//显示,前提是已经有这个实例了,就是已经alloc,init了
-(void)ShowListenView;
//隐藏,前提是已经有这个实例了,就是已经alloc,init了
-(void)HideListenView;
//横竖屏切换需调用
//show跟hideblock是出现和隐藏的时候调用,一般是,showblock里边,消失掉直播间声音,hideblock重新播放声音
@property(nonatomic,copy)void (^ShowBlock)();
@property(nonatomic,copy)void (^HideBlock)();
-(void)ChangeFrameToWhatLand1OrVertical2:(NSInteger)Land1OrVertical2;
//不带界面的识别对象
@property (nonatomic, strong) IFlySpeechRecognizer *iFlySpeechRecognizer;
//录音路径,暂时没有用到
@property (nonatomic, strong) NSString *pcmFilePath;//音频文件路径
//识别结果,暂时没有用到,直接添加在textview
@property (nonatomic, strong) NSString * result;
//是否继续录音
@property(assign,nonatomic)BOOL StopListen;
//外部vc消失时候调用,防止特殊情况的没有释放speechrecognizer,造成内存泄漏
-(void)ShouldDelete;
//确定按钮按下,调用的方法,参数是textview的text,在这里需要将text放到直播间的输入框,活着直接发送等
@property(nonatomic,copy)void (^SureBlock)(NSString*Words);
//点击文字的,调用方法,参数是textview的text,在这里需要将words写到输入框,并且让用户在直播间编辑
@property(nonatomic,copy)void (^ClickWordsBlock)(NSString*Words);
//点击语音的block
@property(nonatomic,copy)void (^TouchUpVoiceImgBlock)();
//取消点击语音图片的block
@property(nonatomic,copy)void (^TouchCancelVoiceImgBlock)();
-(void)ShowWordSLB;
@property(nonatomic,copy)void (^NoWordRecognizeBlock)();
//是否是喇叭发言
@property(assign,nonatomic)BOOL IsAnnounce;
//发言中的提示
@property(strong,nonatomic)UIView* ListenTipView;
@end
.m文件代码:
#import "ListenView.h"
@implementation ListenView
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor whiteColor];
UITapGestureRecognizer *tapWordsLB = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(TapWordsLB)];
[self addGestureRecognizer:tapWordsLB];
//frame宽度必须大于300,确定的是图片半径100
//高度是165-50
self.WordsLB = [[UILabel alloc] initWithFrame:CGRectMake(13, 13, 0, 0)];
self.WordsLB.numberOfLines = 0;
self.WordsLB.textAlignment = NSTextAlignmentLeft;
[self.WordsLB setFont:[UIFont systemFontOfSize:15]];
self.WordsLB.textColor = [UIColor blackColor];
[self addSubview:self.WordsLB];
self.IconBtn = [UIButton buttonWithType:UIButtonTypeCustom];
self.IconBtn.adjustsImageWhenHighlighted = NO;
self.IconBtn.frame = CGRectMake(frame.size.width/2-50, 165-50, 100, 100);
self.IconBtn.userInteractionEnabled = YES;
[self.IconBtn setImage:[UIImage imageNamed:@"YBkxNoListenImg"] forState:UIControlStateNormal];
[self.IconBtn addTarget:self action:@selector(touchInIcon:) forControlEvents:UIControlEventTouchDown];
[self.IconBtn addTarget:self action:@selector(touchOutOrCancelIcon:) forControlEvents:UIControlEventTouchUpInside];
[self.IconBtn addTarget:self action:@selector(touchOutOrCancelIcon:) forControlEvents:UIControlEventTouchCancel];
[self.IconBtn addTarget:self action:@selector(touchOutOrCancelIcon:) forControlEvents:UIControlEventTouchUpOutside];
[self addSubview:self.IconBtn];
self.TipLB = [[UILabel alloc] initWithFrame:CGRectMake(0, self.IconBtn.frame.origin.y-35, frame.size.width, 20)];
self.TipLB.text = @"按住说话";
self.TipLB.textAlignment = NSTextAlignmentCenter;
self.TipLB.font = [UIFont systemFontOfSize:14];
self.TipLB.textColor = [UIColor blackColor];
self.TipLB.textAlignment = NSTextAlignmentCenter;
[self addSubview:self.TipLB];
//默认隐藏
//语音开始是要显示的视图
//140宽高
UIView* TipBgView = [[UIView alloc] initWithFrame:CGRectMake(kYBScreenWidth/2-70, (kYBScreenHeight/2-70)-frame.origin.y, 140, 140)];
TipBgView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.7];
TipBgView.layer.cornerRadius = 5;
TipBgView.layer.masksToBounds = YES;
TipBgView.userInteractionEnabled = YES;
[self addSubview:TipBgView];
self.ListenTipView = TipBgView;
UIImageView* TipImageView = [[UIImageView alloc] initWithFrame:CGRectMake((TipBgView.frame.size.width-40)/2, (TipBgView.frame.size.width-50-30)/3, 40, 50)];
TipImageView.image = [UIImage imageNamed:@"KXInVoice2"];
[TipBgView addSubview:TipImageView];
UILabel* TipLB1 = [[UILabel alloc] initWithFrame:CGRectMake(0, TipImageView.frame.size.height+TipImageView.frame.origin.y+(TipBgView.frame.size.width-50-30)/3, TipBgView.frame.size.width, 15)];
TipLB1.text = @"语音识别中";
TipLB1.font = [UIFont systemFontOfSize:12];
TipLB1.textColor = [UIColor whiteColor];
TipLB1.textAlignment =NSTextAlignmentCenter;
[TipBgView addSubview:TipLB1];
UILabel* TipLB2 = [[UILabel alloc] initWithFrame:CGRectMake(0, TipLB1.frame.size.height+TipLB1.frame.origin.y, TipLB1.frame.size.width, 15)];
TipLB2.text = @"请保持周边安静";
TipLB2.font = [UIFont systemFontOfSize:12];
TipLB2.textColor = [UIColor whiteColor];
TipLB2.textAlignment =NSTextAlignmentCenter;
[TipBgView addSubview:TipLB2];
//默认,没有点击语音,隐藏
[TipBgView setHidden:YES];
//frame-80 然后/2 100是按钮的宽度,80是语音图片的宽度
//最窄300,可以放下
self.ClearBtn = [[UIButton alloc] initWithFrame:CGRectMake(((frame.size.width-self.IconBtn.frame.size.width)/2-100)/2, self.IconBtn.frame.origin.y+20, 100, 20)];
[self.ClearBtn setTitle:@"清空" forState:UIControlStateNormal];
[self.ClearBtn setTitleColor:UIColorFromRGB(0x999999) forState:UIControlStateNormal];
[self.ClearBtn.titleLabel setFont:[UIFont systemFontOfSize:15]];
[self addSubview:self.ClearBtn];
[self.ClearBtn addTarget:self action:@selector(ClickBtnS:) forControlEvents:UIControlEventTouchUpInside];
self.SureBtn = [[UIButton alloc] initWithFrame:CGRectMake(frame.size.width- ((frame.size.width-self.IconBtn.frame.size.width)/2-100)/2-100,self.IconBtn.frame.origin.y+20, 100, 20)];
[self.SureBtn setTitle:@"发送" forState:UIControlStateNormal];
[self.SureBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.SureBtn.titleLabel setFont:[UIFont systemFontOfSize:15]];
[self addSubview:self.SureBtn];
[self.SureBtn addTarget:self action:@selector(ClickBtnS:) forControlEvents:UIControlEventTouchUpInside];
//科大讯飞的审核需要的,醉了,要明确显示技术来自讯飞
UILabel *XunFeiLB = [[UILabel alloc] initWithFrame:CGRectMake(0, frame.size.height-20, frame.size.width, 15)];
NSString *normalStr = [NSString stringWithFormat:@"语音核心技术由科大讯飞提供"];
XunFeiLB.textAlignment = NSTextAlignmentCenter;
NSMutableAttributedString *XFstr = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@",normalStr]];
[XFstr addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(0x333333) range:NSMakeRange(7, 4)];
[XFstr addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(0x999999) range:NSMakeRange(0, 7)];
[XFstr addAttribute:NSForegroundColorAttributeName value:UIColorFromRGB(0x999999) range:NSMakeRange(11, 2)];
[XFstr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:13] range:NSMakeRange(7, 4)];
[XFstr addAttribute:NSUnderlineStyleAttributeName value:[NSNumber numberWithInteger:NSUnderlineStyleSingle] range:NSMakeRange(7, 4)];
[XFstr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:NSMakeRange(0, 7)];
[XFstr addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:12] range:NSMakeRange(11, 2)];
self.XFTipLB = XunFeiLB;
self.XFTipLB.attributedText = XFstr;
[self addSubview:XunFeiLB];
//语音识别调用相关配置
//单例模式,无UI的实例
if (_iFlySpeechRecognizer == nil) {
_iFlySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];
[_iFlySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
//设置听写模式
[_iFlySpeechRecognizer setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
}
_iFlySpeechRecognizer.delegate = self;
if (_iFlySpeechRecognizer != nil) {
IATConfig *instance = [IATConfig sharedInstance];
//设置最长录音时间
[_iFlySpeechRecognizer setParameter:instance.speechTimeout forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];
//设置后端点
[_iFlySpeechRecognizer setParameter:instance.vadEos forKey:[IFlySpeechConstant VAD_EOS]];
//设置前端点
[_iFlySpeechRecognizer setParameter:instance.vadBos forKey:[IFlySpeechConstant VAD_BOS]];
//网络等待时间
[_iFlySpeechRecognizer setParameter:@"20000" forKey:[IFlySpeechConstant NET_TIMEOUT]];
//设置采样率,推荐使用16K
[_iFlySpeechRecognizer setParameter:instance.sampleRate forKey:[IFlySpeechConstant SAMPLE_RATE]];
//设置语言
[_iFlySpeechRecognizer setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
//设置方言
[_iFlySpeechRecognizer setParameter:instance.accent forKey:[IFlySpeechConstant ACCENT]];
//设置是否返回标点符号
[_iFlySpeechRecognizer setParameter:instance.dot forKey:[IFlySpeechConstant ASR_PTT]];
}
//默认停止识别
self.StopListen = YES;
//默认不显示,删除,确认按钮
self.ClearBtn.hidden = YES;
self.SureBtn.hidden = YES;
//
self.userInteractionEnabled = YES;
//防止“null”+字符串,初始化字符串为“”
self.WordsLB.text = @"";
self.IsAnnounce = NO;
}
return self;
}
-(void)ChangeFrameToWhatLand1OrVertical2:(NSInteger)Land1OrVertical2{
if (Land1OrVertical2==1) {
self.frame = CGRectMake(0, kYBScreenHeight-self.frame.size.height, kYBScreenWidth, self.frame.size.height);
self.WordsLB.frame = CGRectMake(13, 13, self.WordsLB.frame.size.width, self.WordsLB.frame.size.height);
self.IconBtn.frame = CGRectMake(self.frame.size.width/2-50, 165-50, 100, 100);
self.TipLB.frame = CGRectMake(0, self.IconBtn.frame.origin.y-35, self.frame.size.width, 20);
self.ClearBtn.frame = CGRectMake(((self.frame.size.width-self.IconBtn.frame.size.width)/2-100)/2, self.IconBtn.frame.origin.y+20, 100, 20);
self.SureBtn.frame = CGRectMake(self.frame.size.width- ((self.frame.size.width-self.IconBtn.frame.size.width)/2-100)/2-100,self.IconBtn.frame.origin.y+20, 100, 20);
self.XFTipLB.frame = CGRectMake(0, self.frame.size.height-20, self.frame.size.width, 15);
self.ListenTipView.frame = CGRectMake(kYBScreenWidth/2-70, (kYBScreenHeight/2-70)-self.frame.origin.y, 140, 140);
}else if(Land1OrVertical2==2){
self.frame = CGRectMake(0, kYBScreenHeight-self.frame.size.height, kYBScreenWidth, self.frame.size.height);
self.WordsLB.frame = CGRectMake(13, 13, self.WordsLB.frame.size.width, self.WordsLB.frame.size.height);
self.IconBtn.frame = CGRectMake(self.frame.size.width/2-50, 165-50, 100, 100);
self.TipLB.frame = CGRectMake(0, self.IconBtn.frame.origin.y-35, self.frame.size.width, 20);
self.ClearBtn.frame = CGRectMake(((self.frame.size.width-self.IconBtn.frame.size.width)/2-100)/2, self.IconBtn.frame.origin.y+20, 100, 20);
self.SureBtn.frame = CGRectMake(self.frame.size.width- ((self.frame.size.width-self.IconBtn.frame.size.width)/2-100)/2-100,self.IconBtn.frame.origin.y+20, 100, 20);
self.XFTipLB.frame = CGRectMake(0, self.frame.size.height-20, self.frame.size.width, 15);
self.ListenTipView.frame = CGRectMake(kYBScreenWidth/2-70, (kYBScreenHeight/2-70)-self.frame.origin.y, 140, 140);
}
}
-(void)ClickBtnS:(UIButton*)btn{
WeakObj(self)
if (btn == self.ClearBtn) {
self.WordsLB.text = @"";
self.ClearBtn.hidden = YES;
self.SureBtn.hidden = YES;
}else if(btn == self.SureBtn){
if (self.SureBlock) {
self.SureBlock(selfWeak.WordsLB.text);
}
}
}
-(void)TapWordsLB{
WeakObj(self)
if (self.ClickWordsBlock) {
self.ClickWordsBlock(selfWeak.WordsLB.text);
}
}
-(void)touchInIcon:(UIButton*)btn{
//点下
//开始语音中
self.StopListen = NO;
//self.IconBtn.image = [UIImage imageNamed:@"YBkxListeningImg"];
[self.IconBtn setImage:[UIImage imageNamed:@"YBkxListeningImg"] forState:UIControlStateNormal];
if ([self.iFlySpeechRecognizer isListening]) {
[self.iFlySpeechRecognizer cancel];
}
[self.iFlySpeechRecognizer startListening];
// self.TipLB.text = @"识别中...";
if (self.TouchUpVoiceImgBlock) {
self.TouchUpVoiceImgBlock();
}
//隐藏可操作控件
//self.WordsLB.hidden = YES;
self.TipLB.hidden = YES;
self.ClearBtn.hidden = YES;
self.SureBtn.hidden = YES;
}
-(void)touchOutOrCancelIcon:(UIButton*)btn{
//点下取消
//滑倒区域外,等其他特殊情况,中断监听
//结束语音后
self.StopListen = YES;
//self.IconBtn.image = [UIImage imageNamed:@"YBkxNoListenImg"];
[self.IconBtn setImage:[UIImage imageNamed:@"YBkxNoListenImg"] forState:UIControlStateNormal];
// if ([self.iFlySpeechRecognizer isListening]) {
// [self.iFlySpeechRecognizer cancel];
//
// }
//停止本次录音并识别
//[self.iFlySpeechRecognizer stopListening];
self.TipLB.text = @"按住说话";
if (self.TouchCancelVoiceImgBlock) {
self.TouchCancelVoiceImgBlock();
}
//显示可操作控件
//不要等识别有结果在显示,直接取消按下的时候就判断是否有文字
self.TipLB.hidden = NO;
if (self.WordsLB.text.length>0) {
self.WordsLB.hidden = NO;
self.ClearBtn.hidden = NO;
self.SureBtn.hidden = NO;
}
}
-(void)ShowListenView{
[UIView setAnimationsEnabled:YES];
self.alpha= 1;
[UIView animateWithDuration:.3 animations:^{
self.frame = CGRectMake(0, kYBScreenHeight-self.frame.size.height, self.frame.size.width, self.frame.size.height);
} completion:nil];
if (self.ShowBlock) {
self.ShowBlock();
}
[self ShowWordSLB];
}
-(void)HideListenView{
[UIView setAnimationsEnabled:YES];
self.alpha= 1;
[UIView animateWithDuration:.3 animations:^{
self.frame = CGRectMake(0, kYBScreenHeight, self.frame.size.width, self.frame.size.height);
} completion:^(BOOL finished) {
if (finished) {
self.alpha = 0;
}
}];
//隐藏默认就是,关闭语音监听
self.StopListen = YES;
//self.IconBtn.image = [UIImage imageNamed:@"YBkxNoListenImg"];
[self.IconBtn setImage:[UIImage imageNamed:@"YBkxNoListenImg"] forState:UIControlStateNormal];
if ([self.iFlySpeechRecognizer isListening]) {
[self.iFlySpeechRecognizer cancel];
}
self.WordsLB.text = @"";
self.SureBtn.hidden = YES;
self.ClearBtn.hidden = YES;
if (self.HideBlock) {
self.HideBlock();
}
}
-(void)onResults:(NSArray *)results isLast:(BOOL)isLast{
//接收到一段录音并且转换成文字
//shu
NSMutableString *resultString = [[NSMutableString alloc] init];
NSDictionary *dic = results[0];
for (NSString *key in dic) {
[resultString appendFormat:@"%@",key];
}
_result =[NSString stringWithFormat:@"%@%@", self.WordsLB.text,resultString];
NSString * resultFromJson = [ISRDataHelper stringFromJson:resultString];
NSString *subStr = [NSString stringWithFormat:@"%@%@", self.WordsLB.text,resultFromJson];
if (subStr.length>20) {
//超过20字,应该提示下的
self.WordsLB.text = [subStr substringWithRange:NSMakeRange(0, 20)];
}else{
//没超过,直接显示
self.WordsLB.text = subStr;
}
//根据总的字体长度,来决定是否隐藏两个按钮
if (self.WordsLB.text.length>0) {
//根据当前文本信息,重新绘制label的frame.
CGSize lblSize = [self.WordsLB.text boundingRectWithSize:CGSizeMake(self.frame.size.width-13*2, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil].size;
self.WordsLB.frame = CGRectMake(self.WordsLB.frame.origin.x, self.WordsLB.frame.origin.y, lblSize.width, lblSize.height);
}
if (self.StopListen == YES) {
[self.iFlySpeechRecognizer cancel];
if (self.NoWordRecognizeBlock) {
self.NoWordRecognizeBlock();
}
//显示可操作控件
self.TipLB.hidden = NO;
if (self.WordsLB.text.length>0) {
self.WordsLB.hidden = NO;
self.ClearBtn.hidden = NO;
self.SureBtn.hidden = NO;
}
}
if (isLast){
NSLog(@"听写结果(json):%@测试", self.result);
}
NSLog(@"_result=%@",_result);
NSLog(@"resultFromJson=%@",resultFromJson);
NSLog(@"isLast=%d,_textView.text=%@",isLast,self.WordsLB.text);
}
-(void)ShowWordSLB{
self.TipLB.hidden = NO;
if (self.WordsLB.text.length>0) {
self.SureBtn.hidden = NO;
self.ClearBtn.hidden = NO;
self.WordsLB.hidden = NO;
//根据当前文本信息,重新绘制label的frame.
CGSize lblSize = [self.WordsLB.text boundingRectWithSize:CGSizeMake(self.frame.size.width-13*2, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:15]} context:nil].size;
self.WordsLB.frame = CGRectMake(self.WordsLB.frame.origin.x, self.WordsLB.frame.origin.y, lblSize.width, lblSize.height);
}
}
-(void)onEndOfSpeech{
if (self.StopListen) {
//取消的情况下,识别完毕,就停止
[self.iFlySpeechRecognizer cancel];
if (self.NoWordRecognizeBlock) {
self.NoWordRecognizeBlock();
}
//显示可操作控件
self.TipLB.hidden = NO;
if (self.WordsLB.text.length>0) {
self.WordsLB.hidden = NO;
self.ClearBtn.hidden = NO;
self.SureBtn.hidden = NO;
}
}else{
//按着的情况下,重复调用
[self.iFlySpeechRecognizer startListening];
}
}
-(void)onError:(IFlySpeechError *)errorCode{
//可提示用户识别不到语音
//暂不操作
//现在onerror的逻辑和OnEndOfSpeech逻辑一样
if (self.StopListen) {
//取消的情况下,识别完毕,就停止
[self.iFlySpeechRecognizer cancel];
if (self.NoWordRecognizeBlock) {
self.NoWordRecognizeBlock();
}
//显示可操作控件
self.TipLB.hidden = NO;
if (self.WordsLB.text.length>0) {
self.WordsLB.hidden = NO;
self.ClearBtn.hidden = NO;
self.SureBtn.hidden = NO;
}
}else{
//按着的情况下,重复调用
[self.iFlySpeechRecognizer startListening];
}
}
//父级视图dealloc时调用
-(void)ShouldDelete{
if (self.iFlySpeechRecognizer) {
self.StopListen = YES;
if ([self.iFlySpeechRecognizer isListening]) {
[self.iFlySpeechRecognizer cancel];
}
}
}
- (void)dealloc {
NSLog(@"function %s-%d",__FUNCTION__,__LINE__);
}
@end
在需要调用的,地方initwithframe。另外提醒下,我一直以为可以直接说完一段语音,然后再开始识别语音输出出结果;但实际上讯飞语音应该没有这么做,它是边接收语音,边识别数出结果的形式(有点略坑).
代码有些乱,不过大体上需求都是这个模子,改下就好
好了,还有不懂的小伙伴,请加QQ群一起讨论:565191947