前言:近期研究了一下语音识别,从百度语音识别到讯飞语音识别;首先说一下个人针对两者的看法,讯飞毫无疑问比較专业。识别率也非常高真对语音识别是比較精准的,可是非常多开发人员和我一样期望离线识别,而讯飞离线是收费的;请求次数来讲。两者都能够申请高配额,针对用户较多的差点儿都一样。

基于免费而且支持离线我选择了百度离线语音识别。比較简单,UI设计多一点,以下写一下教程:

1.首先:须要的库

2.我是自己定义的UI所以以功能实现为主(头文件)

// 头文件

#import "BDVRCustomRecognitonViewController.h"

#import "BDVRClientUIManager.h"

#import "WBVoiceRecordHUD.h"

#import "BDVRViewController.h"

#import "MyViewController.h"

#import "BDVRSConfig.h"

3.须要知道的功能:能用到的例如以下:

//-------------------类方法------------------------

// 创建语音识别客户对像,该对像是个单例

+ (BDVoiceRecognitionClient *)sharedInstance;

// 释放语音识别客户端对像

+ (void)releaseInstance;

//-------------------识别方法-----------------------

// 推断能否够录音

- (BOOL)isCanRecorder;

// 開始语音识别,须要实现MVoiceRecognitionClientDelegate代理方法。并传入实现对像监听事件

// 返回值參考 TVoiceRecognitionStartWorkResult

- (int)startVoiceRecognition:(id)aDelegate;

// 说完了,用户主动完毕录音时调用

- (void)speakFinish;

// 结束本次语音识别

- (void)stopVoiceRecognition;

/**

* @brief 获取当前识别的採样率

*

* @return 採样率(16000/8000)

*/

- (int)getCurrentSampleRate;

/**

* @brief 得到当前识别模式(deprecated)

*

* @return 当前识别模式

*/

- (int)getCurrentVoiceRecognitionMode __attribute__((deprecated));

/**

* @brief 设置当前识别模式(deprecated)。请使用-(void)setProperty:(TBDVoiceRecognitionProperty)property;

*

* @param 识别模式

*

* @return 是否设置成功

*/

- (void)setCurrentVoiceRecognitionMode:(int)aMode __attribute__((deprecated));

// 设置识别类型

- (void)setProperty:(TBDVoiceRecognitionProperty)property __attribute__((deprecated));

// 获取当前识别类型

- (int)getRecognitionProperty __attribute__((deprecated));

// 设置识别类型列表, 除EVoiceRecognitionPropertyInput和EVoiceRecognitionPropertySong外

// 能够识别类型复合

- (void)setPropertyList: (NSArray*)prop_list;

// cityID仅对EVoiceRecognitionPropertyMap识别类型有效

- (void)setCityID: (NSInteger)cityID;

// 获取当前识别类型列表

- (NSArray*)getRecognitionPropertyList;

//-------------------提示音-----------------------

// 播放提示音。默觉得播放,录音開始,录音结束提示音

// BDVoiceRecognitionClientResources/Tone

// record_start.caf 录音開始声音文件

// record_end.caf 录音结束声音文件

// 声音资源须要加到项目project里。用户可替换资源文件,文件名称不能够变,建音提示音不宜过长,0。5秒左右。

// aTone 取值參考 TVoiceRecognitionPlayTones,如没有找到文件。则返回NO

- (BOOL)setPlayTone:(int)aTone isPlay:(BOOL)aIsPlay;

4.录音button相关动画(我自己定义的,大家能够借鉴)

// 录音button相关

@property (nonatomic, weak, readonly) UIButton *holdDownButton;// 说话button

/**

* 是否取消錄音

*/

@property (nonatomic, assign, readwrite) BOOL isCancelled;

/**

* 是否正在錄音

*/

@property (nonatomic, assign, readwrite) BOOL isRecording;

/**

* 当录音button被按下所触发的事件,这时候是開始录音

*/

- (void)holdDownButtonTouchDown;

/**

* 当手指在录音button范围之外离开屏幕所触发的事件。这时候是取消录音

*/

- (void)holdDownButtonTouchUpOutside;

/**

* 当手指在录音button范围之内离开屏幕所触发的事件,这时候是完毕录音

*/

- (void)holdDownButtonTouchUpInside;

/**

* 当手指滑动到录音button的范围之外所触发的事件

*/

- (void)holdDownDragOutside;

5.初始化系统UI

#pragma mark - layout subViews UI

/**

* 依据正常显示和高亮状态创建一个button对象

*

* @param image 正常显示图

* @param hlImage 高亮显示图

*

* @return 返回button对象

*/

- (UIButton *)createButtonWithImage:(UIImage *)image HLImage:(UIImage *)hlImage ;

- (void)holdDownDragInside;

- (void)createInitView; // 创建初始化界面。播放提示音时会用到

- (void)createRecordView; // 创建录音界面

- (void)createRecognitionView; // 创建识别界面

- (void)createErrorViewWithErrorType:(int)aStatus; // 在识别view中显示具体错误信息

- (void)createRunLogWithStatus:(int)aStatus; // 在状态view中显示具体状态信息

- (void)finishRecord:(id)sender; // 用户点击完毕动作

- (void)cancel:(id)sender; // 用户点击取消动作

- (void)startVoiceLevelMeterTimer;

- (void)freeVoiceLevelMeterTimerTimer;

6.最重要的部分

// 录音完毕

[[BDVoiceRecognitionClient sharedInstance] speakFinish];

// 取消录音

[[BDVoiceRecognitionClient sharedInstance] stopVoiceRecognition];

7.两个代理方法

- (void)VoiceRecognitionClientWorkStatus:(int)aStatus obj:(id)aObj

{

switch (aStatus)

{

case EVoiceRecognitionClientWorkStatusFlushData: // 连续上屏中间结果

{

NSString *text = [aObj objectAtIndex:0];

if ([text length] > 0)

{

// [clientSampleViewController logOutToContinusManualResut:text];

UILabel *clientWorkStatusFlushLabel = [[UILabel alloc]initWithFrame:CGRectMake(kScreenWidth/2 - 100,64,200,60)];

clientWorkStatusFlushLabel.text = text;

clientWorkStatusFlushLabel.textAlignment = NSTextAlignmentCenter;

clientWorkStatusFlushLabel.font = [UIFont systemFontOfSize:18.0f];

clientWorkStatusFlushLabel.numberOfLines = 0;

clientWorkStatusFlushLabel.backgroundColor = [UIColor whiteColor];

[self.view addSubview:clientWorkStatusFlushLabel];

}

break;

}

case EVoiceRecognitionClientWorkStatusFinish: // 识别正常完毕并获得结果

{

[self createRunLogWithStatus:aStatus];

if ([[BDVoiceRecognitionClient sharedInstance] getRecognitionProperty] != EVoiceRecognitionPropertyInput)

{

// 搜索模式下的结果为数组,演示样例为

// ["公园", "公元"]

NSMutableArray *audioResultData = (NSMutableArray *)aObj;

NSMutableString *tmpString = [[NSMutableString alloc] initWithString:@""];

for (int i=0; i < [audioResultData count]; i++)

{

[tmpString appendFormat:@"%@ ",[audioResultData objectAtIndex:i]];

}

clientSampleViewController.resultView.text = nil;

[clientSampleViewController logOutToManualResut:tmpString];

}

else

{

NSString *tmpString = [[BDVRSConfig sharedInstance] composeInputModeResult:aObj];

[clientSampleViewController logOutToContinusManualResut:tmpString];

}

if (self.view.superview)

{

[self.view removeFromSuperview];

}

break;

}

case EVoiceRecognitionClientWorkStatusReceiveData:

{

// 此状态仅仅有在输入模式下使用

// 输入模式下的结果为带置信度的结果,示比例如以下:

// [

// [

// {

// "百度" = "0.6055192947387695";

// },

// {

// "摆渡" = "0.3625582158565521";

// },

// ]

// [

// {

// "一下" = "0.7665404081344604";

// }

// ],

// ]

//临时关掉 -- 否则影响跳转结果

// NSString *tmpString = [[BDVRSConfig sharedInstance] composeInputModeResult:aObj];

// [clientSampleViewController logOutToContinusManualResut:tmpString];

break;

}

case EVoiceRecognitionClientWorkStatusEnd: // 用户说话完毕,等待server返回识别结果

{

[self createRunLogWithStatus:aStatus];

if ([BDVRSConfig sharedInstance].voiceLevelMeter)

{

[self freeVoiceLevelMeterTimerTimer];

}

[self createRecognitionView];

break;

}

case EVoiceRecognitionClientWorkStatusCancel:

{

if ([BDVRSConfig sharedInstance].voiceLevelMeter)

{

[self freeVoiceLevelMeterTimerTimer];

}

[self createRunLogWithStatus:aStatus];

if (self.view.superview)

{

[self.view removeFromSuperview];

}

break;

}

case EVoiceRecognitionClientWorkStatusStartWorkIng: // 识别库開始识别工作,用户能够说话

{

if ([BDVRSConfig sharedInstance].playStartMusicSwitch) // 假设播放了提示音。此时再给用户提示能够说话

{

[self createRecordView];

}

if ([BDVRSConfig sharedInstance].voiceLevelMeter) // 开启语音音量监听

{

[self startVoiceLevelMeterTimer];

}

[self createRunLogWithStatus:aStatus];

break;

}

case EVoiceRecognitionClientWorkStatusNone:

case EVoiceRecognitionClientWorkPlayStartTone:

case EVoiceRecognitionClientWorkPlayStartToneFinish:

case EVoiceRecognitionClientWorkStatusStart:

case EVoiceRecognitionClientWorkPlayEndToneFinish:

case EVoiceRecognitionClientWorkPlayEndTone:

{

[self createRunLogWithStatus:aStatus];

break;

}

case EVoiceRecognitionClientWorkStatusNewRecordData:

{

break;

}

default:

{

[self createRunLogWithStatus:aStatus];

if ([BDVRSConfig sharedInstance].voiceLevelMeter)

{

[self freeVoiceLevelMeterTimerTimer];

}

if (self.view.superview)

{

[self.view removeFromSuperview];

}

break;

}

}

}

- (void)VoiceRecognitionClientNetWorkStatus:(int) aStatus

{

switch (aStatus)

{

case EVoiceRecognitionClientNetWorkStatusStart:

{

[self createRunLogWithStatus:aStatus];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

break;

}

case EVoiceRecognitionClientNetWorkStatusEnd:

{

[self createRunLogWithStatus:aStatus];

[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

break;

}

}

}

8.录音button的一些操作

#pragma mark ------ 关于button操作的一些事情-------

- (void)holdDownButtonTouchDown {

// 開始动画

_disPlayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(delayAnimation)];

_disPlayLink.frameInterval = 40;

[_disPlayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

self.isCancelled = NO;

self.isRecording = NO;

// 開始语音识别功能,之前必须实现MVoiceRecognitionClientDelegate协议中的VoiceRecognitionClientWorkStatus:obj方法

int startStatus = -1;

startStatus = [[BDVoiceRecognitionClient sharedInstance] startVoiceRecognition:self];

if (startStatus != EVoiceRecognitionStartWorking) // 创建失败则报告错误

{

NSString *statusString = [NSString stringWithFormat:@"%d",startStatus];

[self performSelector:@selector(firstStartError:) withObject:statusString afterDelay:0.3]; // 延迟0.3秒。以便能在出错时正常删除view

return;

}

// "按住说话-松开搜索"提示

[voiceImageStr removeFromSuperview];

voiceImageStr = [[UIImageView alloc]initWithFrame:CGRectMake(kScreenWidth/2 - 40, kScreenHeight - 153, 80, 33)];

voiceImageStr.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"searchVoice"]];

[self.view addSubview:voiceImageStr];

}

- (void)holdDownButtonTouchUpOutside {

// 结束动画

[self.view.layer removeAllAnimations];

[_disPlayLink invalidate];

_disPlayLink = nil;

// 取消录音

[[BDVoiceRecognitionClient sharedInstance] stopVoiceRecognition];

if (self.view.superview)

{

[self.view removeFromSuperview];

}

}

- (void)holdDownButtonTouchUpInside {

// 结束动画

[self.view.layer removeAllAnimations];

[_disPlayLink invalidate];

_disPlayLink = nil;

[[BDVoiceRecognitionClient sharedInstance] speakFinish];

}

- (void)holdDownDragOutside {

//假设已經開始錄音了, 才须要做拖曳出去的動作, 否則仅仅要切換 isCancelled, 不讓錄音開始.

if (self.isRecording) {

// if ([self.delegate respondsToSelector:@selector(didDragOutsideAction)]) {

// [self.delegate didDragOutsideAction];

// }

} else {

self.isCancelled = YES;

}

}

#pragma mark - layout subViews UI

- (UIButton *)createButtonWithImage:(UIImage *)image HLImage:(UIImage *)hlImage {

UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(kScreenWidth/2 -36, kScreenHeight - 120, 72, 72)];

if (image)

[button setBackgroundImage:image forState:UIControlStateNormal];

if (hlImage)

[button setBackgroundImage:hlImage forState:UIControlStateHighlighted];

return button;

}

#pragma mark ----------- 动画部分 -----------

- (void)startAnimation

{

CALayer *layer = [[CALayer alloc] init];

layer.cornerRadius = [UIScreen mainScreen].bounds.size.width/2;

layer.frame = CGRectMake(0, 0, layer.cornerRadius * 2, layer.cornerRadius * 2);

layer.position = CGPointMake([UIScreen mainScreen].bounds.size.width/2,[UIScreen mainScreen].bounds.size.height - 84);

// self.view.layer.position;

UIColor *color = [UIColor colorWithRed:arc4random()%10*0.1 green:arc4random()%10*0.1 blue:arc4random()%10*0.1 alpha:1];

layer.backgroundColor = color.CGColor;

[self.view.layer addSublayer:layer];

CAMediaTimingFunction *defaultCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];

_animaTionGroup = [CAAnimationGroup animation];

_animaTionGroup.delegate = self;

_animaTionGroup.duration = 2;

_animaTionGroup.removedOnCompletion = YES;

_animaTionGroup.timingFunction = defaultCurve;

CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];

scaleAnimation.fromValue = @0.0;

scaleAnimation.toValue = @1.0;

scaleAnimation.duration = 2;

CAKeyframeAnimation *opencityAnimation = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];

opencityAnimation.duration = 2;

opencityAnimation.values = @[@0.8,@0.4,@0];

opencityAnimation.keyTimes = @[@0,@0.5,@1];

opencityAnimation.removedOnCompletion = YES;

NSArray *animations = @[scaleAnimation,opencityAnimation];

_animaTionGroup.animations = animations;

[layer addAnimation:_animaTionGroup forKey:nil];

[self performSelector:@selector(removeLayer:) withObject:layer afterDelay:1.5];

}

- (void)removeLayer:(CALayer *)layer

{

[layer removeFromSuperlayer];

}

- (void)delayAnimation

{

[self startAnimation];

}

完毕以上操作,就大功告成了!

温馨提示:

1.因为是语音识别,须要用到麦克风相关权限。模拟器会爆12个错误。使用真机能够解决;

2.涉及到授权文件相关并不复杂,projectBundle Identifier仅仅须要设置百度的离线授权一致就可以。例如以下图:

终于效果例如以下:

有不懂或不明确的地方能够微博联系我:

iOS开发人员交流群:446310206

iOS中 语音识别功能/语音转文字教程具体解释 韩俊强的博客相关推荐

  1. iOS中 语音识别功能/语音转文字教程详解 韩俊强的博客

    原文地址:http://blog.csdn.net/qq_31810357/article/details/51111702 前言:最近研究了一下语音识别,从百度语音识别到讯飞语音识别:首先说一下个人 ...

  2. iOS中 最新微信支付/最全的微信支付教程详解 韩俊强的博客

    亲们, 首先让我们来看一下微信支付的流程吧. 1. 注册微信开放平台,创建应用获取appid,appSecret,申请支付功能,申请成功之后会返回一些参数. 2. 下载微信支付sdk 3. 客户端请求 ...

  3. iOS中 Realm的学习与使用 韩俊强的博客

    iOS开发者交流QQ群:446310206  有问题或技术交流可以咨询!欢迎加入! 这篇直接搬了一份官方文档过来看的 由于之前没用markdown搞的乱七八糟的 所以重新做了一份 后面看到官网的中文文 ...

  4. iOS中 流媒体播放和下载 韩俊强的博客

    iOS中关于流媒体的简介:介于下载本地播放与实时流媒体之间的一种播放形式,下载本地播放必须全部将文件下载完成后才能播放,而渐进式下载不必等到全部下载完成后再播放,它可以一边下载一边播放,在完成播放内容 ...

  5. iOS中 Animation 动画大全 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! iOS开发者交流QQ群: 446310206 1.iOS中我们能看到的控件都是UIView的子类,比如UIButt ...

  6. iOS中 本地通知/本地通知详解 韩俊强的博客

    布局如下:(重点讲本地通知) iOS开发者交流QQ群: 446310206 每日更新关注:http://weibo.com/hanjunqiang  新浪微博 Notification是智能手机应用编 ...

  7. iOS中 Bugly iOS 符号表手动配置详细教程 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博!iOS开发者交流QQ群: 446310206 官方教程 官方的符号表工具iOS文档版­使用指南不是很详细,于是自己动 ...

  8. iOS开发中的零碎知识点笔记 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 1.关联 objc_setAssociatedObject关联是指把两个对象相互关联起来,使得其中的一个对象作为另外 ...

  9. iOS中 为 iOS 建立 Travis CI 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang新浪微博! 你是否曾经试着为 iOS 项目搭建一台支持持续集成的服务器,从我的个人经验而言,这可不是一个轻松的活.首先需要准备一台 ...

最新文章

  1. ​“后进生”数学学科上演完美逆袭,成最具竞争力专业之一
  2. SAP-PM-预防性维护-01-概览
  3. currency类型_让我们一起走进VBA基本语法的世界,先了解一下数据类型有哪些
  4. Linux下基于socket多线程并发通信的实现
  5. ###STL学习--标准模板库
  6. 一路踩坑,被迫聊聊 C# 代码调试技巧和远程调试
  7. emacs python ide_Emacs Python IDE win7 x64
  8. fortran 读整行_我整周读过的最有趣的东西
  9. jar 工程我怎么在网页上url访问某一个方法_Java高级编程之URL处理
  10. 国家地理相关资源数据库
  11. centos 7.6上面安装向日葵远程连接软件
  12. jquery ajax回调函数带入参数
  13. [恒指赵鑫] 为什么恒指是2019年最火最受欢迎的交易品种?
  14. Echarts一些社区网站,亲测可用,新更新了Antv(阿里旗下)
  15. 零基础学Java需要多长时间?
  16. 车路协同、智慧交管、自动驾驶场景应有尽有,智能交通行业实战课火爆开启...
  17. vue中使用echarts词云
  18. Online Tools
  19. 您的基于云的应用程序可能是有利可图的产品
  20. python下载安装教程-python安装教程

热门文章

  1. SQL语句和EF Group by 用法
  2. falsk 请求钩子
  3. Hadoop伪分布式搭建(本人新手,欢迎大家多多指导和关照)
  4. Unix中$$、$@、$#、$*的意思
  5. dubbo/dubbox部署资料收集
  6. 心路历程(四)-我的2015
  7. 房费制——报表(1)
  8. UVA10120 ZOJ1229 Gift?!【DFS+BFS】
  9. UVA10074 Take the Land【最大子段和+DP】
  10. hard-negative mining 及伪代码实现