每日更新关注: 新浪微博
原文地址:
前言:最近研究了一下语音识别,从百度语音识别到讯飞语音识别;首先说一下个人针对两者的看法,讯飞毫无疑问比较专业,识别率也很高真对语音识别是比较精准的,但是很多开发者和我一样期望离线识别,而讯飞离线是收费的;请求次数来讲,两者都可以申请高配额,真对用户较多的几乎都一样。基于免费并且支持离线我选择了百度离线语音识别。比较简单,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;
-
-
-
- - (int)startVoiceRecognition:(id<MVoiceRecognitionClientDelegate>)aDelegate;
-
-
- - (void)speakFinish;
-
-
- - (void)stopVoiceRecognition;
-
-
-
-
-
-
- - (int)getCurrentSampleRate;
-
-
-
-
-
-
- - (int)getCurrentVoiceRecognitionMode __attribute__((deprecated));
-
-
-
-
-
-
-
-
- - (void)setCurrentVoiceRecognitionMode:(int)aMode __attribute__((deprecated));
-
-
- - (void)setProperty:(TBDVoiceRecognitionProperty)property __attribute__((deprecated));
-
-
- - (int)getRecognitionProperty __attribute__((deprecated));
-
-
-
- - (void)setPropertyList: (NSArray*)prop_list;
-
-
- - (void)setCityID: (NSInteger)cityID;
-
-
- - (NSArray*)getRecognitionPropertyList;
-
-
-
-
-
-
-
-
- - (BOOL)setPlayTone:(int)aTone isPlay:(BOOL)aIsPlay;
4.录音按钮相关动画(我自定义的,大家可以借鉴)
每日更新关注: 新浪微博
-
- @property (nonatomic, weak, readonly) UIButton *holdDownButton;
-
-
-
- @property (nonatomic, assign, readwrite) BOOL isCancelled;
-
-
-
-
- @property (nonatomic, assign, readwrite) BOOL isRecording;
-
-
-
- - (void)holdDownButtonTouchDown;
-
-
-
-
- - (void)holdDownButtonTouchUpOutside;
-
-
-
-
- - (void)holdDownButtonTouchUpInside;
-
-
-
-
- - (void)holdDownDragOutside;
5.初始化系统UI
- #pragma mark - layout subViews UI
-
-
-
-
-
-
-
-
-
- - (UIButton *)createButtonWithImage:(UIImage *)image HLImage:(UIImage *)hlImage ;
- - (void)holdDownDragInside;
- - (void)createInitView;
- - (void)createRecordView;
- - (void)createRecognitionView;
- - (void)createErrorViewWithErrorType:(int)aStatus;
- - (void)createRunLogWithStatus:(int)aStatus;
-
- - (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)
- {
-
-
- 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:@"%@\r\n",[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:
- {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- break;
- }
- case EVoiceRecognitionClientWorkStatusEnd:
- {
- [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.录音按钮的一些操作
每日更新关注: 新浪微博
- #pragma mark ------ 关于按钮操作的一些事情-------
- - (void)holdDownButtonTouchDown {
-
- _disPlayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(delayAnimation)];
- _disPlayLink.frameInterval = 40;
- [_disPlayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
-
- self.isCancelled = NO;
- self.isRecording = NO;
-
-
- 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];
- 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 {
-
-
- if (self.isRecording) {
-
-
-
- } 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);
-
- 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.涉及到授权文件相关并不复杂,工程Bundle Identifier只需要设置百度的离线授权一致即可,如下图:
最终效果如下:
有不懂或不明白的地方可以微博联系我:
每日更新关注: 新浪微博