iOS中實現(xiàn)語音轉文字,除了一些第三方报强,如科大訊飛語音灸姊、百度語音等第三方的外(這種第三方的在其官方都有詳細的教程,這里就不在敘述了秉溉。特點是:百度語音支持離線并免費力惯。訊飛的也支持離線碗誉,雖然識別率很高也很精準,但是收費)父晶,蘋果官方也推出了自己的一套識別標準哮缺。
蘋果官方的文字轉語音支持iOS10之后
文字轉語音的需求:
1.創(chuàng)建一個按鈕用來控制啟動、關閉錄音
?2.創(chuàng)建一個語音控制器甲喝,一個語音識別器 尝苇。一個語音任務管理器,
?3.創(chuàng)建顯示轉換好的文字的控件
步驟:
?iOS語音轉文字:1.需要添加Speech.framework庫? ? 2.導入頭文件#import
?3.在info.plist文件里添加了兩個鍵值Privacy - Microphone Usage Description埠胖、Privacy - Speech Recognition Usage Description
具體代碼如下:
#import "ViewController.h"
#import<Speech/Speech.h>
#import<AVFoundation/AVFoundation.h>
@interface ViewController ()
@property (nonatomic,strong)UIButton *swicthBut;
@property (nonatomic,strong)UILabel *labText;
@property(nonatomic,strong)SFSpeechRecognizer*speechRecognizer;//語音識別器
@property (nonatomic,strong) SFSpeechAudioBufferRecognitionRequest *recognitionRequest;//語音識別請求
@property (nonatomic, strong) SFSpeechRecognitionTask *recognitionTask;//語音任務管理器
@property (nonatomic,strong) AVAudioEngine *audioEngine;//語音控制器
@end
@implementation ViewController
- (void)viewDidLoad {
? ? [super viewDidLoad];
? ? //發(fā)送語音認證請求(首先要判斷設備是否支持語音識別功能)
? ? [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
? ? ? ? boolisButtonEnabled =false;
? ? ? ? switch(status) {
? ? ? ? ? ? case SFSpeechRecognizerAuthorizationStatusAuthorized:
? ? ? ? ? ? ? ? isButtonEnabled =true;
? ? ? ? ? ? ? ? NSLog(@"可以語音識別");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case SFSpeechRecognizerAuthorizationStatusDenied:
? ? ? ? ? ? ? ? isButtonEnabled =false;
? ? ? ? ? ? ? ? NSLog(@"用戶未授權使用語音識別");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case SFSpeechRecognizerAuthorizationStatusRestricted:
? ? ? ? ? ? ? ? isButtonEnabled =false;
? ? ? ? ? ? ? ? NSLog(@"語音識別在這臺設備上受到限制");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case SFSpeechRecognizerAuthorizationStatusNotDetermined:
? ? ? ? ? ? ? ? isButtonEnabled =false;
? ? ? ? ? ? ? ? NSLog(@"語音識別未授權");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? }];
? ? // Do any additional setup after loading the view, typically from a nib.
? ? self.title=@"測試";
? ? self.view.backgroundColor = [UIColor whiteColor];
? ? [self.viewaddSubview:self.swicthBut];
? ? [self.viewaddSubview:self.labText];
}
- (void)speechRecognizer:(SFSpeechRecognizer*)speechRecognizer availabilityDidChange:(BOOL)available{
? ? if(available) {
? ? ? ? self.swicthBut.enabled=YES;
? ? ? ? ? [self.swicthBut setTitle:@"開始錄音" forState:UIControlStateNormal];
? ? }else{
? ? ? ? self.swicthBut.enabled=NO;
? ? ? ? ? [self.swicthBut setTitle:@"語音識別不可用" forState:UIControlStateNormal];
? ? }
}
#pragma mark----語音識別
- (SFSpeechRecognizer*)speechRecognizer{
? ? if (!_speechRecognizer) {
? ? ? ? NSLocale *cale = [[NSLocale alloc]initWithLocaleIdentifier:@"zh-CN"];
?? ? ? _speechRecognizer= [[SFSpeechRecognizeralloc]initWithLocale:cale];
? ? ? ? //設置代理
? ? ? ? _speechRecognizer.delegate = self;
? ? }
? ? return _speechRecognizer;
}
#pragma mark---停止錄音
- (void)endRecording{
? ? [self.audioEngine stop];
? ? if (_recognitionRequest) {
? ? ? ? [_recognitionRequest endAudio];
? ? }
? ? if (_recognitionTask) {
? ? ? ? [_recognitionTask cancel];
? ? ? ? _recognitionTask = nil;
? ? }
? ? self.swicthBut.enabled=NO;
}
#pragma? mark---開始錄音
- (void)startRecording{
? ? if (self.recognitionTask) {
? ? ? ? [self.recognitionTask cancel];
? ? ? ? self.recognitionTask = nil;
? ? }
? ? AVAudioSession *audioSession = [AVAudioSession sharedInstance];
? ? NSError*error;
? ? bool? audioBool = [audioSessionsetCategory:AVAudioSessionCategoryRecorderror:&error];
? ? NSParameterAssert(!error);
? ? bool? audioBool1= [audioSessionsetMode:AVAudioSessionModeMeasurementerror:&error];
? ? ? NSParameterAssert(!error);
? ? bool? audioBool2= [audioSessionsetActive:true withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error];
? ? ? NSParameterAssert(!error);
? ? if(audioBool || audioBool1||? audioBool2) {
? ? ? ? NSLog(@"可以使用");
? ? }else{
? ? ? ? NSLog(@"這里說明有的功能不支持");
? ? }
? ? self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc]init];
? ? AVAudioInputNode *inputNode = self.audioEngine.inputNode;
? ? NSAssert(inputNode,@"錄入設備沒有準備好");
? ? NSAssert(self.recognitionRequest, @"請求初始化失敗");
? ? self.recognitionRequest.shouldReportPartialResults = true;
?? ? __weaktypeof(self) weakSelf =self;
? ? //開始識別任務
? ? self.recognitionTask = [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
? ? ? ? __strongtypeof(weakSelf) strongSelf = weakSelf;
? ? ? ? boolisFinal =false;
? ? ? ? if(result) {
? ? ? ? ? ? strongSelf.labText.text= [[resultbestTranscription]formattedString];//語音轉文本
? ? ? ? ? ? isFinal = [resultisFinal];
? ? ? ? }
? ? ? ? if(error || isFinal) {
? ? ? ? ? ? [strongSelf.audioEnginestop];
? ? ? ? ? ? [inputNoderemoveTapOnBus:0];
? ? ? ? ? ? strongSelf.recognitionRequest=nil;
? ? ? ? ? ? strongSelf.recognitionTask=nil;
? ? ? ? ? ? [strongSelf.swicthButsetTitle:@"開始錄音"forState:UIControlStateNormal];
? ? ? ? ? ? strongSelf.swicthBut.enabled=true;
? ? ? ? }
? ? }];
? ? AVAudioFormat*recordingFormat = [inputNodeoutputFormatForBus:0];
? ? //在添加tap之前先移除上一個? 不然有可能報"Terminating app due to uncaught exception 'com.apple.coreaudio.avfaudio',"之類的錯誤
? ? [inputNoderemoveTapOnBus:0];
? ? [inputNodeinstallTapOnBus:0bufferSize:1024format:recordingFormatblock:^(AVAudioPCMBuffer*_Nonnullbuffer,AVAudioTime*_Nonnullwhen) {
?? ? ? ? __strongtypeof(weakSelf) strongSelf = weakSelf;
? ? ? ? if(strongSelf.recognitionRequest) {
? ? ? ? ? ? [strongSelf.recognitionRequestappendAudioPCMBuffer:buffer];
? ? ? ? }
? ? }];
? ? [self.audioEngine prepare];
? ? boolaudioEngineBool = [self.audioEnginestartAndReturnError:&error];
?? ? NSParameterAssert(!error);
? ? self.labText.text = @"正在錄音糠溜。。直撤。";
? ? NSLog(@"%d",audioEngineBool);
}
#pragma mark---創(chuàng)建錄音引擎
- (AVAudioEngine*)audioEngine{
? ? if (!_audioEngine) {
? ? ? ? _audioEngine= [[AVAudioEnginealloc]init];
? ? }
? ? return _audioEngine;
}
#pragma mark----顯示控件
- (UILabel*)labText{
? ? if(!_labText) {
? ? ? ? _labText= [[UILabelalloc]init];
? ? ? ? _labText.frame = CGRectMake(0, 140, [UIScreen mainScreen].bounds.size.width, 50);
? ? ? ? _labText.font= [UIFontsystemFontOfSize:13.0f];
? ? ? ? _labText.numberOfLines = 0;
? ? ? ? _labText.textAlignment = NSTextAlignmentCenter;
? ? ? ? _labText.textColor = [UIColor yellowColor];
? ? }
? ? return _labText;
}
#pragma mark----開關
- (UIButton*)swicthBut{
? ? if (!_swicthBut) {
? ? ? ? _swicthBut= [[UIButtonalloc]init];
? ? ? ? _swicthBut.frame=CGRectMake(50,100,80,30);
? ? ? ? _swicthBut.titleLabel.textAlignment = NSTextAlignmentCenter;
? ? ? ? [_swicthBut setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
? ? ? ? [_swicthBut addTarget:self action:@selector(switchOn:) forControlEvents:UIControlEventTouchUpInside];
? ? ? ? [_swicthBut setTitle:@"開始錄音" forState:UIControlStateNormal];
? ? }
? ? return _swicthBut;
}
- (void)switchOn:(id)sender{
? ? if([self.audioEngineisRunning]) {
? ? ? ? [self endRecording];
?? ? ? [_swicthBut setTitle:@"開始錄音" forState:UIControlStateNormal];
? ? }else{
? ? ? ? [self startRecording];
?? ? ? ? [_swicthBut setTitle:@"關閉" forState:UIControlStateNormal];
? ? }
}
#pragma mark---識別本地音頻文件
- (void)recognizeLocalAudioFile:(UIButton*)sender {
? ? NSLocale *local =[[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];
? ? SFSpeechRecognizer *localRecognizer =[[SFSpeechRecognizer alloc] initWithLocale:local];
? ? NSURL *url =[[NSBundle mainBundle] URLForResource:@"錄音.m4a" withExtension:nil];
? ? if(!url)return;
? ? SFSpeechURLRecognitionRequest *res =[[SFSpeechURLRecognitionRequest alloc] initWithURL:url];
? ? __weak typeof(self) weakSelf = self;
? ? [localRecognizerrecognitionTaskWithRequest:resresultHandler:^(SFSpeechRecognitionResult*_Nullableresult,NSError*_Nullableerror) {
? ? ? ? if(error) {
? ? ? ? ? ? NSLog(@"語音識別解析失敗,%@",error);
? ? ? ? }
? ? ? ? else
? ? ? ? {
? ? ? ? ? ? weakSelf.labText.text = result.bestTranscription.formattedString;
? ? ? ? }
? ? }];
}
- (void)didReceiveMemoryWarning {
? ? [super didReceiveMemoryWarning];
? ? // Dispose of any resources that can be recreated.
}
@end