之前做的项目中有语音识别的需求, 是用讯飞语音SDK实现的。 有很多服务商提供声音转文字的服务,有收费的有免费。

2016年苹果在发布的上iOS10增加了一个语音识别功能,并且将其封装到了SpeechFramework库中。苹果手机上Siri的语音识别就是基于Speech实现的。

下面就开始动手敲代码实践录音和Speech的用法吧

1. 引入Speech 和AVFoundation

#import // 录音

#import // 语音识别

2. 申请用户权限

想要使用录音和语音识别功能必须先配置info.plist文件,在其中增加麦克风和语音识别授权属性

NSMicrophoneUsageDescription

App需要您的同意,才能使用麦克风

NSSpeechRecognitionUsageDescription

App需要您的同意,才能使用语音识别

加完之后是这样的

3. 录音

激活AVAudioSession

_session = [AVAudioSession sharedInstance];

NSError *categoryError = nil;

//设置为播放和录音状态,以便可以在录制完之后播放录音

[_session setCategory:AVAudioSessionCategoryPlayAndRecord error:&categoryError];

if (_session) {

[_session setActive:YES error:nil]; // 此处手动激活

}

else {

NSLog(@"Error creating session: %@",[categoryError description]);

}

创建录音器, 设置代理(可以监听录制的状态)

- (void)createAudioRecorder

{

// 实例化录音器对象

NSError *errorRecord = nil;

_recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath:_filePath] settings:[self getAudioSetting] error:&errorRecord];

_recorder.delegate = self;

_recorder.meteringEnabled = YES; //如果要监控声波则必须设置为YES

// 准备录音

[_recorder prepareToRecord];

}

实例化录音对象, 要设置音频的编码参数

- (NSDictionary *)getAudioSetting

{

//录音设置

NSMutableDictionary *recordSettings = [[NSMutableDictionary alloc] init];

//音频质量,采样质量

[recordSettings setValue:[NSNumber numberWithInt:AVAudioQualityMax] forKey:AVEncoderAudioQualityKey];

//通道数 编码时每个通道的比特率

[recordSettings setValue:[NSNumber numberWithInt:2] forKey: AVNumberOfChannelsKey];

//录音格式 无法使用

// [recordSettings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey: AVFormatIDKey];

//LinearPCM 是iOS的一种无损编码格式,但是体积较为庞大

//采样率

[recordSettings setValue:[NSNumber numberWithFloat:44100.0] forKey: AVSampleRateKey];//44100.0

//线性采样位数

[recordSettings setValue:[NSNumber numberWithInt:32] forKey: AVLinearPCMBitDepthKey];

// 编码时的比特率,是每秒传送的比特(bit)数单位为bps(Bit Per Second),比特率越高传送数据速度越快值是一个整数

[recordSettings setValue:[NSNumber numberWithInt:128000] forKey:AVEncoderBitRateKey];

return recordSettings;

}

开始录制

- (void)recorderSoundStart:(NSString *)path

{

// 停止播放

[self stopPlayRecorderSound];

// 停止之前的录音

if ([_recorder isRecording]) {

[_recorder stop];

}

// 删除旧的录音文件

[APPUtil deleteFile:path];

// 不删除也可以, 同一会路径下会被覆盖

if (!_recorder) {

// 实例化录音对象

[self createAudioRecorder];

}

if (![_recorder isRecording]){

[_recorder record];

// 设定 录制 最长时间 60s

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

[self recorderSoundEnd];

});

}

}

由于设置了最长录制时间60s, 所以要加上下面录制完成代理代码

#pragma mark - AVAudioRecorderDelegate 录音机代理方法

- (void)audioRecorderDidFinishRecording:(AVAudioRecorder *)recorder successfully:(BOOL)flag

{

NSLog(@"录音完成!");

[self recorderSoundEnd];

}

停止录制 , 在停止录制之前, 可能会有暂停录制,此处略过

- (void)recorderSoundEnd

{

// 停止录音

if ([_recorder isRecording]) {

[_recorder stop];

// [_recorder pause]; // 暂停录制

}

// 更新UI按钮

_recodeSound.selected = NO;

}

开始播放及停止播放

// 播放

- (void)recorderSoundPlay:(NSString *)path

{

// 先停止录音

if (_recorder) {

[_recorder stop];

}

if (!_player) {

// 创建播放器

[self createAudioPlayer];

}

[_session setCategory:AVAudioSessionCategoryPlayback error:nil];

// 播放

[_player play];

}

// 停止

- (void)stopPlayRecorderSound

{

if ([_player isPlaying]) {

[_player stop];

}

// 更新UI播放按钮

_playSound.selected = NO;

}

4. 语音识别

语音识别是iOS10增加的新特性,Xcode8之前的版本没有SpeechFramework库,所以此功能只能在Xcode8以上和iOS10以上运行。

请求语音识别权限

// 请求语音识别权限

[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {

NSLog(@"status %@", status == SFSpeechRecognizerAuthorizationStatusAuthorized ? @"语音识别权限授权成功" : @"语音识别权限授权失败"); }];

所谓语音识别, 就是用户说话然后马上把用户说的话转成文字显示!这才是理想中的语音识别, 当然也是支持识别一个本地音频文件

打开Speech kit库,找到语音识别请求文件 SFSpeechRecognitionRequest.h, 发现 识别请求的API有两种 SFSpeechAudioBufferRecognitionRequest 和 SFSpeechURLRecognitionRequest 都继承于SFSpeechRecognitionRequest类

SFSpeechAudioBufferRecognitionRequest 实时识别音频流 也就是现说现译

SFSpeechURLRecognitionRequest 识别路径URL的音频文件

既然语音识别配置工作上面都已经做好了, 下面就看下这两种识别请求吧 ()

5. 语音识别--现说现译

激活AVAudioSession

_session = [AVAudioSession sharedInstance];

[_session setCategory:AVAudioSessionCategoryRecord mode:AVAudioSessionModeMeasurement options:AVAudioSessionCategoryOptionDuckOthers error:nil];

[_session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];

AVAudioSessionCategoryRecord : 设置录音(现说现译, 要录制说的话)

AVAudioSessionModeMeasurement:减少系统提供信号对应用程序输入和/或输出音频信号的影响

AVAudioSessionCategoryOptionDuckOthers: 在实时通话的场景,降低别的声音。比如QQ音乐,当进行视频通话的时候,会发现QQ音乐自动声音降低了,此时就是通过设置这个选项来对其他音乐App进行了压制

AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation:判断当前是否有其他App在播放音频

多媒体引擎的建立

- (void)createAudioEngine

{

if (!_speechRecognizer) {

// 设置语言

NSLocale *locale = [NSLocale localeWithLocaleIdentifier:@"zh-CN"];

_speechRecognizer = [[SFSpeechRecognizer alloc] initWithLocale:locale];

}

// 初始化引擎

if (!_audioEngine) {

_audioEngine = [[AVAudioEngine alloc] init];

}

}

创建语音识别请求, 创建并开启语音识别任务

// 创建语音识别请求

- (void)createSpeechRequest

{

if (_speechRequest) {

[_speechRequest endAudio];

_speechRequest = nil;

}

_speechRequest = [[SFSpeechAudioBufferRecognitionRequest alloc] init];

_speechRequest.shouldReportPartialResults = YES; // 实时翻译

__weak typeof(self) weakSelf = self;

// 建立语音识别任务, 并启动. block内为语音识别结果回调

[_speechRecognizer recognitionTaskWithRequest:_speechRequest resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {

// 语音识别结果回调

__strong typeof(weakSelf) strongSelf = weakSelf;

if (error) {

NSLog(@"语音识别解析失败,%@",error);

}

else {

// 识别的内容

NSString *text = result.bestTranscription.formattedString;

// 实时打印说话的内容

NSLog(@"is final: %d result: %@", result.isFinal, result.bestTranscription.formattedString);

if (result.isFinal) { // 结束时 显示内容

// 显示说话的内容

strongSelf.content.text = text;

// 多次说话的内容拼接到一起显示

// strongSelf.content.text = [NSString stringWithFormat:@"%@%@", strongSelf.content.text, text];

}

}

}];

}

语音识别任务及回调结果有2中实现方法, 一种是代理, 一种block, 此处选择了block

// Recognize speech utterance with a request

// If request.shouldReportPartialResults is true, result handler will be called

// repeatedly with partial results, then finally with a final result or an error.

- (SFSpeechRecognitionTask *)recognitionTaskWithRequest:(SFSpeechRecognitionRequest *)request

resultHandler:(void (^)(SFSpeechRecognitionResult * __nullable result, NSError * __nullable error))resultHandler;

// Advanced API: Recognize a custom request with with a delegate

// The delegate will be weakly referenced by the returned task

- (SFSpeechRecognitionTask *)recognitionTaskWithRequest:(SFSpeechRecognitionRequest *)request

delegate:(id )delegate;

开始语音识别

- (IBAction)stardRecorder:(UIButton *)sender

{

// 开始录音前清空显示的内容, 如果需要拼接多次录音的内容,不要清空,

_content.text = @"";

// 创建新的语音识别请求

[self createSpeechRequest];

__weak typeof(self) weakSelf = self;

// 录音格式配置 -- 监听输出流 并拼接流文件

AVAudioFormat *recordingFormat = [[_audioEngine inputNode] outputFormatForBus:0];

// 创建一个Tap,(创建前要先删除旧的)

// 文档注释: Create a "tap" to record/monitor/observe the output of the node.

[[_audioEngine inputNode] installTapOnBus:0 bufferSize:1024 format:recordingFormat block:^(AVAudioPCMBuffer * _Nonnull buffer, AVAudioTime * _Nonnull when) {

__strong typeof(weakSelf) strongSelf = weakSelf;

// 拼接流文件

[strongSelf.speechRequest appendAudioPCMBuffer:buffer];

}];

// 准备并启动引擎

[_audioEngine prepare];

NSError *error = nil;

if (![_audioEngine startAndReturnError:&error]) {

NSLog(@"%@",error.userInfo);

};

[sender setTitle:@"语音识别中..." forState:UIControlStateNormal];

}

重置多媒体引擎

- (void)releaseEngine

{

// 销毁tap

[[_audioEngine inputNode] removeTapOnBus:0];

[_audioEngine stop];

[_speechRequest endAudio];

_speechRequest = nil;

}

到这里 现说现译-语音识别就完成了。

6. 语音识别--本地音频文件

这个需要个音频文件, 上面做的录音功能, 就可以录制语音caf文件, 那就直接在录音功能基础上, 加个语音识别吧。这样就集录制、播放、语音识别于一体了。

直接看代码

- (IBAction)speechSound:(UIButton *)sender

{

// 识别的录音文件是否存在

NSFileManager* manager = [NSFileManager defaultManager];

if (![manager fileExistsAtPath:_filePath]){

NSLog(@"音频文件不存在");

return ;

}

_speechContent.text = @"";

//转化过后的MP3文件位置

// NSString *mp3Path = [NSString stringWithFormat:@"%@/%@", [APPUtil speechPath], @"lame.mp3"];

// [APPUtil lameCafToMp3:_filePath mp3:mp3Path];

// [self speechSoundRecord:mp3Path]; // 语音识别失败

// 不转成mp3也可以 识别成功

[self speechSoundRecord:_filePath]; // 能识别成功

}

- (void)speechSoundRecord:(NSString *)path

{

// 设置语言中文

NSLocale *local = [[NSLocale alloc] initWithLocaleIdentifier:@"zh_CN"];

SFSpeechRecognizer *localRecognizer =[[SFSpeechRecognizer alloc] initWithLocale:local];

NSURL *url = [NSURL fileURLWithPath:path];

if (!url) return;

SFSpeechURLRecognitionRequest *res =[[SFSpeechURLRecognitionRequest alloc] initWithURL:url];

__weak typeof(self) weakSelf = self;

[localRecognizer recognitionTaskWithRequest:res resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {

__strong typeof(weakSelf) strongSelf = weakSelf;

if (error) {

NSLog(@"语音识别解析失败,%@",error);

}

else {

// 显示 识别的内容

NSString *text = result.bestTranscription.formattedString;

strongSelf.speechContent.text = text;

}

}];

}

历时一天半终于写完了实现录音和语音识别功能的代码 , 现在运行看下效果吧,

直接看图:

录音.png

语音识别.png

可以看到, 录音和语音识别功能, 除了识别内容会有些错别字, 效果还是挺完美的。

音频录制和Speech语音识别(ios10)相关推荐

  1. AVFoundation 文本转语音和音频录制 播放

    现在你应该对AVFoundation有了比较深入的了解,并且对数字媒体的细节也有了一定认识,下面介绍一下 AVFoundation的文本转语音功能 AVSpeechSynthesizer 开发者可以使 ...

  2. .NET NAudio音频录制方法 2021-02-13

    .NET NAudio音频录制方法 写在前面 文章主要内容 说明 检测录音电平 调节录音电平 开始录音 调整音频 保存音频 关于作者 讨论 SomeONe Clint Nate Greenwood C ...

  3. audiorecord怎么释放_Android 开发 AudioRecord音频录制

    前言 Android SDK 提供了两套音频采集的API,分别是:MediaRecorder 和 AudioRecord,前者是一个更加上层一点的API,它可以直接把手机麦克风录入的音频数据进行编码压 ...

  4. 有关于iphone 音频 录制 播发

    有关于iphone 音频 录制 播发 1,音频格式相关: http://www.raywenderlich.com/204/audio-101-for-iphone-developers-file-a ...

  5. Android多媒体学习八:调用Android自带的音频录制程序,实现录制

    Android中有自带的音频录制程序,我们可以通过指定一个Action为MediaStore.Audio.Media.RECORD_SOUND_ACTION的Intent来 启动它就可以了.然后在on ...

  6. 如何进行音频录制?实用的音频录制方法合集

    音频录制是一种重要的技能,可以用于各种场合,比如我们可以使用音频录制技术录制不同乐器和声音的音频,并在后期进行处理和混音,制作出完整的音乐作品等等.但是,要想录制出高质量的音频并不容易,需要掌握一些专 ...

  7. 如何录制音频文件mp3?给你推荐好用的几款音频录制软件

        其实我们生活中对于音频录制的需求是比较大的,比如开会的时候为了防止漏掉要点,又或者在上课的时候老师语速过快我们来不及记笔记,这些情况出现的时候我们都可以用录音来解决这些问题.那今天在这里我也跟 ...

  8. android Q屏幕录制,设备音频录制无声

    Android q 之后google添加了音频录制的api 在状态栏中可以开启录制功能. 使用中发现,选择音源为设备内部音频的时候,录制的视频无声. 内部音乐录制时android Q版本之后googl ...

  9. android AudioRecord 音频录制 噪音消除

    android AudioRecord 音频录制 噪音消除  因为公司APP做适配,一些低端机的噪音比较严重,所以再一些低端机上做了简单除噪音功能, 1,由于APP使用场景的限制,所以一般噪音基本上都 ...

最新文章

  1. cpythonjava解释xml_详解python使用lxml操作xml格式文件
  2. 【Groovy】集合遍历 ( 使用 for 循环遍历集合 | 使用集合的 each 方法遍历集合 | 集合的 each 方法返回值分析 )
  3. 数据库开发——MySQL——数据的增删改查
  4. Java库可以软件著作权,(最新整理)软件著作权-源代码范本
  5. 调用python接口并画图_【PySpark源码解析】教你用Python调用高效Scala接口
  6. Codeforces 671C Ultimate Weirdness of an Array 线段树 (看题解)
  7. c语言模拟试题快速排序,快速排序(东软喜欢考类似的算法填空题,又如堆排序的算法等)...
  8. CubeMX 的使用实例详细(04.6)- STM32F103的 - 定时器设定 - callback调用 - 实现1S的定时更新LED灯
  9. poj 1325 Machine Schedule 解题报告
  10. axios.post请求出错:Request header field content-type is not allowed by Access-Control-Allow-Headers in……
  11. 非阻塞IO发送http请求
  12. Mysql表的过滤查询
  13. Java丨基础:十三、集合
  14. niceScroll相关配置参数
  15. 计算机毕业设计JAVA便利店系统mybatis+源码+调试部署+系统+数据库+lw
  16. 条令考试小程序辅助器_微信小程序条令考试刷分 微信小程序答题刷分软件
  17. 编出个区块链:数据结构的序列化,看看数字货币如何传输数据
  18. python 线程锁_Python线程锁的实现
  19. 网页生成pdf文件。(html转pdf)(带效果图)
  20. WCF学习经验分享,如何更好地学习WCF?

热门文章

  1. CodeForces - 937D Sleepy Game
  2. php array_merge和“+”的区别和使用《细说php2》
  3. MVC下c#对接微信公众平台开发者模式
  4. NGUI中的Table自定义排序
  5. [搬家]新域名 akagi201.org
  6. 设置隔离级别实现并发控制
  7. Bailian2996 选课【置换】
  8. Bailian2806 公共子序列【最长公共子序列+DP】
  9. HDU2089 不要62【数位DP+记忆化搜索】
  10. HDU1874 畅通工程续【Dijkstra算法】