这阵子公司一直想要搞个语音发送命令!本来科达讯飞用的好好的,但是!价格简直有点小贵了!!8000元人民币识别2000台机子!四元一台的成本,公司舍不得钱所以!!!:
speech是iOS10.0新出的开源框架!如果你需要使用的话建议你先更新XCODE,swift也可以使用哟!不过我的项目没有用到swift,所以没有贴出来,总之!功能还是相当强大的!也很好用,不过此框架比较呆,只能使用本地的文件,很有局限性!而且我看网上很多教程基本都是识别的本地的文件!!! EXM? 很LOW有没有! 所以如果你的需求本不是一个.MP3 识别音乐中的内容的话!可以看下去!如果是只需要识别.MP3的话,看到语音识别就能满足你的需求了!
speechframework可以识别出MP3的语音。而且仅仅只能识别.MP3文件这种本地的音频文件(可播放的那种),但是我们需要的功能是识别麦克风自己说话的声音,所以还需要先获取麦克风的声音,使用AVAudioRecorder或许到本地的音频数据流。用AVAudioSession进行录制,再将录制得到的caf数据流转成MP3格式!存入字典上次本地的文件:
MP3生成成功: /var/mobile/Containers/Data/Application/5E32CD4F-6644-40BD-8AC7-6AC9836A65DD/Documents/myRecord.mp3
需要注意的是URL的使用方式不能用write!下面这种是识别不出来的:
[NSURL URLWithString:Str];
以下两种是可行的URL:
1.NSURL *url = [[NSBundle mainBundle] URLForResource:@"你好.mp3" withExtension:nil];
2.NSURL *url= [NSURL fileURLWithPath:self.mp3PathStr];
分享一段CAF转MP3代码免走弯路:
@try {
int read, write;
FILE *pcm = fopen([self.cafPathStr cStringUsingEncoding:1], "rb"); //source被转换的音频文件位置
fseek(pcm, 4*1024, SEEK_CUR); //skip file header
FILE *mp3 = fopen([self.mp3PathStr cStringUsingEncoding:1], "wb"); //output输出生成的Mp3文件位置
const int PCM_SIZE = 8192;
const int MP3_SIZE = 8192;
short int pcm_buffer[PCM_SIZE*2];
unsigned char mp3_buffer[MP3_SIZE];
lame_t lame = lame_init();
lame_set_in_samplerate(lame, 11025.0);
lame_set_VBR(lame, vbr_default);
lame_init_params(lame);
do {
read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
if (read == 0)
write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
else
write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
fwrite(mp3_buffer, write, 1, mp3);
} while (read != 0);
lame_close(lame);
fclose(mp3);
fclose(pcm);
}
@catch (NSException *exception) {
NSLog(@"%@",[exception description]);
}
}
@finally {
NSLog(@"MP3生成成功: %@",self.mp3PathStr);
开发者若要在自己的App中使用语音识别功能,需要获取用户的同意。首先需要在工程的Info.plist文件中添加一个Privacy-Speech Recognition Usage Description键,其实需要对应一个String类型的值,这个值将会在系统获取权限的警告框中显示,Info.plist文件中。使用SFSpeechRecognize类的requestAuthorization方法来进行用户权限的申请,用户的反馈结果会在这个方法的回调block中传入。
//申请用户语音识别权限
[SFSpeechRecognizer requestAuthorization:^(SFSpeechRecognizerAuthorizationStatus status) {
}];
如果申请用户语音识别权限成功,开发者可以通过SFSpeechRecognizer操作类来进行语音识别请求,示例如下:
1
2
3
4
5
6
7
8
9
//创建语音识别操作类对象
SFSpeechRecognizer * rec = [[SFSpeechRecognizer alloc]init];
//通过一个音频路径创建音频识别请求
SFSpeechRecognitionRequest * request = [[SFSpeechURLRecognitionRequest alloc]initWithURL:[[NSBundle mainBundle] URLForResource:@"7011" withExtension:@"m4a"]];
//进行请求
[rec recognitionTaskWithRequest:request resultHandler:^(SFSpeechRecognitionResult * _Nullable result, NSError * _Nullable error) {
//打印语音识别的结果字符串
NSLog(@"%@",result.bestTranscription.formattedString);
}];
测试代码,发现会出现自动识别多个。有汉字数字各种!反复测试代码,猜测原因有两个
1.代码重复:传过来的MP3文件出现多次传入的问题
2.识别多次:框架会自动识别几个。
// A recognized utterance, corresponding to a segment of recorded audio with speech and containing one
API_AVAILABLE(ios(10.0))
@interface SFSpeechRecognitionResult :NSObject <NSCopying,NSSecureCoding>
@property (nonatomic,readonly, copy) SFTranscription*bestTranscription; //按升序识别,从识别的最好的开始!
// Hypotheses for possible transcriptions, sorted in decending order of confidence (more likely first)
@property (nonatomic,readonly, copy)NSArray<SFTranscription *>*transcriptions; //按降序识别。
// True if the hypotheses will not change; speech processing is complete.
@property (nonatomic,readonly, getter=isFinal)BOOL final;//判断是否是最终完成的语音识别
进行判断
if (result.isFinal)即可!
至此离线语音识别已经完成!
后期代码我会板上来的!因为项目还在做,有需要的可以加群!群号:622492955 !