代码改变世界

iOS,系统语音合成语音识别

  帅不过三秒  阅读(162)  评论(0编辑  收藏  举报

1.系统语音合成语音识别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
#import "ViewController.h"
//导入语音合成系统库
#import <AVFoundation/AVFoundation.h>
//导入语音识别系统库
#import <Speech/Speech.h>
 
@interface ViewController ()<AVSpeechSynthesizerDelegate,SFSpeechRecognitionTaskDelegate,NFCTagReaderSessionDelegate>
@property (nonatomic, strong) AVSpeechSynthesizer *synthesizer;//语音合成iOS7开始支持
 
//iOS语音识别
@property (nonatomic, strong) SFSpeechRecognizer *speechRecognizer;
@property (nonatomic, strong) AVAudioEngine *audioEngine;
@property (nonatomic, strong) SFSpeechAudioBufferRecognitionRequest *recognitionRequest;
 
@property (nonatomic, strong) UITextView *textView;
@property (nonatomic, strong) UIButton *recordBtn;
@property (nonatomic, assign) BOOL isRecord;
 
 
@end
 
@implementation ViewController
 
- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor whiteColor]];
    float left=20;
    self.textView=[[UITextView alloc] initWithFrame:CGRectMake(15, 44, self.view.frame.size.width-30, 120)];
    self.textView.text=@"iOS7新特性,语音合成测试用例";
    self.textView.textColor=[UIColor blackColor];
    self.textView.font=[UIFont systemFontOfSize:16.0f];
    self.textView.layer.borderWidth=1.0f;
    self.textView.layer.borderColor=[UIColor grayColor].CGColor;
    [self.view addSubview:self.textView];
     
    UIButton *goBtn=[[UIButton alloc] initWithFrame:CGRectMake(left, self.textView.frame.origin.y+self.textView.frame.size.height+10, self.view.frame.size.width-2*left, 50)];
    [goBtn setTitle:@"合成播放" forState:UIControlStateNormal];
    [goBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [goBtn setBackgroundColor:[UIColor grayColor]];
    [goBtn addTarget:self action:@selector(speakAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:goBtn];
     
    self.recordBtn=[[UIButton alloc] initWithFrame:CGRectMake(left, goBtn.frame.origin.y+goBtn.frame.size.height+10, self.view.frame.size.width-2*left, 50)];
    [self.recordBtn setTitle:@"录制识别" forState:UIControlStateNormal];
    [self.recordBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    [self.recordBtn setBackgroundColor:[UIColor grayColor]];
    [self.recordBtn addTarget:self action:@selector(recordAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:self.recordBtn];
    self.isRecord=NO;
}
 
//结束触摸
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    //isExclusiveTouch一个布尔值来指示接收机处理触摸事件。
    //没有触摸_textUser进入if内操作
    if (![self.textView isExclusiveTouch]) {
        //resignFirstResponder取消第一响应者状态的。如果对textfield使用的话,那么调用这个方法,textfield的第一响应者状态就会取消,然后键盘就消失了。
        [self.textView resignFirstResponder];
    }
}
 
 
-(void)recordAction{
     
    if (self.isRecord) {
        self.isRecord=NO;
        [self stopRecording];
        [self.recordBtn setTitle:@"录制识别" forState:UIControlStateNormal];
    }else{
        [SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
            NSLog(@"status %@", status == SFSpeechRecognizerAuthorizationStatusAuthorized ? @"授权成功" : @"授权失败");
            dispatch_async(dispatch_get_main_queue(), ^{
                if (status == SFSpeechRecognizerAuthorizationStatusAuthorized) {
                    [self startRecording];
        //            //block回调方式
        //            [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
        //
        //                    if (result.isFinal) {
        //                        NSLog(@"is final: %d  result: %@", result.isFinal, result.bestTranscription.formattedString);
        //                    }
        //            }];
                    self.isRecord=YES;
                    [self.recordBtn setTitle:@"停止录制" forState:UIControlStateNormal];
                    //delegate回调方式
                    [self.speechRecognizer recognitionTaskWithRequest:self.recognitionRequest delegate:self];
                }else{
                    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"没有语音识别权限" preferredStyle:UIAlertControllerStyleAlert];
                     
                    // 2.创建并添加按钮
                    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"暂不授权" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
 
                    }];
                    [alertController addAction:cancelAction];
                     
                    // 2.创建并添加按钮
                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"去授权" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                            #ifdef __IPHONE_8_0
                            NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                            if ([[UIApplication sharedApplication]canOpenURL:url]) {
                                [[UIApplication sharedApplication]openURL:url];
                            }
                            #endif
                    }];
                    [alertController addAction:okAction];
                    [self presentViewController:alertController animated:YES completion:nil];
                }
            });
 
        }];
    }
     
}
 
-(void)speakAction{
    [self speakString:self.textView.text];
}
 
 
 
-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
     
    // 请求识别权限info.plist
//    <key>NSSpeechRecognitionUsageDescription</key>
//    <string>请允许语音识别</string>
//    <key>NSMicrophoneUsageDescription</key>
//    <string>请允许麦克风</string>
     
 
     
    return;
     
   
}
 
- (void)initEngine {
    if (!self.speechRecognizer) {
        // 设置语言
        NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"zh-CN"];
        self.speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];
    }
    if (!self.audioEngine) {
        self.audioEngine = [[AVAudioEngine alloc] init];
    }
     
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    [audioSession setCategory:AVAudioSessionCategoryRecord mode:AVAudioSessionModeMeasurement options:AVAudioSessionCategoryOptionDuckOthers error:nil];
    [audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
     
    if (self.recognitionRequest) {
        [self.recognitionRequest endAudio];
        self.recognitionRequest = nil;
    }
    self.recognitionRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];
    self.recognitionRequest.shouldReportPartialResults = YES;
}
- (void)startRecording{
    [self initEngine];
     
    AVAudioFormat *recordingFormat = [[self.audioEngine inputNode] outputFormatForBus:0];
    [[self.audioEngine inputNode] installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {
        [self.recognitionRequest appendAudioPCMBuffer:buffer];
    }];
    [self.audioEngine prepare];
    [self.audioEngine startAndReturnError:nil];
     
}
 
- (void)stopRecording{
    [[self.audioEngine inputNode] removeTapOnBus:0];
    [self.audioEngine stop];
    [self.recognitionRequest endAudio];
    self.recognitionRequest = nil;
}
 
 
-(void)speakString:(NSString *)string{
    //避免手机静音合成语音不能播放
    NSError *setCategoryErr = nil;
    NSError *activationErr = nil;
    [[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
    //magic is here
    [[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
     
    //语音合成
      //设置语言类别( 不能被识别,返回值为nil)
    AVSpeechSynthesisVoice *voiceType = [AVSpeechSynthesisVoice voiceWithLanguage:@"zh-CN"];
    AVSpeechUtterance *utterance = [AVSpeechUtterance speechUtteranceWithString:string];
    utterance.voice =  voiceType;
    utterance.rate *=1.0;//设置语速
    utterance.volume =1.0;//设置音量
    [self.synthesizer speakUtterance:utterance];
}
 
#pragma mark  SFSpeechRecognitionTaskDelegate
- (void)speechRecognitionTask:(SFSpeechRecognitionTask *)task didFinishRecognition:(SFSpeechRecognitionResult *)recognitionResult{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (recognitionResult.isFinal) {
            NSLog(@"is final: %d  result: %@", recognitionResult.isFinal, recognitionResult.bestTranscription.formattedString);
            self.textView.text=recognitionResult.bestTranscription.formattedString;
        }else{
            self.textView.text=@"识别失败";
        }
    });
 
}
#pragma mark AVSpeechSynthesizerDelegate
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didStartSpeechUtterance:(AVSpeechUtterance *)utterance{
 
NSLog(@"语音合成开始");
 
}
 
-(void)speechSynthesizer:(AVSpeechSynthesizer *)synthesizer didFinishSpeechUtterance:(AVSpeechUtterance *)utterance{
 
NSLog(@"语音合成完成");
 
}
 
#pragma mark lazyloading
/**
 @author Vie 2022年06月23日15:11:43
 @初始化懒加载alertTipView
 @return alertTipView
 */
-(AVSpeechSynthesizer *)synthesizer{
    if (!_synthesizer) {
        //语音合成
        // 语音合成器会生成音频
        _synthesizer = [[AVSpeechSynthesizer alloc] init];
        _synthesizer.delegate=self;
    }
    return _synthesizer;
}
@end

 

相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示