精华内容
下载资源
问答
  • 语音识别转文字

    2018-12-20 14:45:51
    科大讯飞、百度云、腾讯云的语音识别,将把语音文件转换为文字,基于.net平台
  • 主要介绍了小程序实现语音识别转文字功能,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
  • “最近为小程序增加语音识别转文字的功能,坑路不断,特此记录。”微信开发者工具开发者工具上的录音文件与移动端格式不同,暂时只可在工具上进行播放调试,无法直接播放或者在客户端上播放。debug的时候发现,工具...

    5a0f06d79c6da59b27a03c001874fc96.png

    “最近为小程序增加语音识别转文字的功能,坑路不断,特此记录。”

    微信开发者工具

    开发者工具上的录音文件与移动端格式不同,暂时只可在工具上进行播放调试,无法直接播放或者在客户端上播放。

    debug的时候发现,工具上录音的路径http://tmp/xxx.mp3,客户端上录音是wxfile://xxx.mp3。

    其实呢,不是格式不同,是映射路径不同。
    虽然这里做个兼容也不难,但是每次提示一行文字,很影响美观。

    采样率与编码码率限制

    每种采样率有对应的编码码率范围有效值,设置不合法的采样率或编码码率会导致录音失败。

    详细看这个:https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.start.html
    一开始没有留意,导致录音不成功。在试过几次后,再次采用这样的配置,感觉录音识别率和体积之间比较好平衡:

    sampleRate: 16000, //采样率
    numberOfChannels: 1, //录音通道数
    encodeBitRate: 96000, //编码码率

    单通道基本是必选的。因为asr只支持单通道。frameSize也是可以的,但是要考虑截断对识别的影响,这里暂时没有用上。

    录音优化

    微信录音文件支持mp3aac。这2种格式文件都比较小,aac文件体积更小。这对上传来说是件好事情,速度更快。


    但是对语音识别转文字就不友好了。因为百度、阿里云ASR、讯飞的语音转文字接口都不支持aac和mp3,通常要求是pcm或者wav格式


    如果微信录音能提供wav格式,那么就不用服务器做格式转换了,但是wav格式体积是mp3、aac的5到10倍,至少短期是没戏了,这也是很多人吐槽的地方。

    服务器转换录音文件格式

    可以用java第三方库转换,也可以用Process调用ffmpeg转换。

    要注意的是,根据识别API的要求来做转换。比如阿里云asr的要求是:

    支持音频编码格式:pcm(无压缩的pcm文件或wav文件)、opus,16bit采样位数的单声道(mono);

    支持音频采样率:8000Hz、16000Hz;

    java ProcessBuilder要

    转换音视频,我习惯用ffmpeg。安装完ffmpeg之后,用java新建进程调用。

    Process = new ProcessBuilder("ffmpeg -i in.mp3 out.wav").start();

    系统一直提示CreateProcess error。 后来看文档才发现,要以数组的形式传入参数。

    Process = new ProcessBuilder("ffmpeg -i in.mp3 out.wav").start();

    这样就启动成功了。

    关于java启动进程,不是本文重点,以后再写篇文章总结。

    阿里云asr sdk使用问题

    这个问题困扰了我很长时间。问题表现是微信录制的语音很多都识别不了。

    最初是直接把录音mp3文件转换为pcm文件,本地能播放,但是用阿里云asr sdk却识别不了。一开始以为是文件编码问题。特意查了asr支持的文件格式,用ffprobe检查,potplayer看属性,都没有看出问题。我甚至把启动ffmpeg进程转换也改了,用了java的库去做,还是不行。

    后来为了方便测试问题,用asr的restful接口测试录音文件,发现都能识别。 看起来似乎是sdk的问题。于是我打开官方文档例子对比。发现用的是sdk 2.x,复制粘贴过来的代码竟然少了,确实让人欲哭无泪。这里也少了对sampleRate的设置。

    // TODO  重要提示:这里是用读取本地文件的形式模拟实时获取语音流并发送的,因为read很快,所以这里需要sleep
    // TODO  如果是真正的实时获取语音,则无需sleep, 如果是8k采样率语音,第二个参数改为8000
    int deltaSleep = getSleepDelta(len, sampleRate);
    Thread.sleep(deltaSleep);

    原文作者:Rolan
    原文地址:http://www.wxapp-union.com/article-5461-1.html

    展开全文
  • iOS 语音识别转文字

    千次阅读 2017-02-22 23:48:33
    语音文字科大讯飞语音识别技术,支持英文,中文,方言等。识别效率十分迅速,而且准确率官网能够达到97%以上。 在使用过程中,也确实发现,可以商用,或者利用其API进行开发。使用场景,包含英语学习,单词朗读...

    语音转成文字

    这里写图片描述

    科大讯飞语音识别技术,支持英文,中文,方言等。识别效率十分迅速,而且准确率官网能够达到97%以上。
    在使用过程中,也确实发现,可以商用,或者利用其API进行开发。

    使用场景,包含英语学习,单词朗读,语音评测等。

    本文介绍如何使用 语音转成文字 的功能

    Demo 地址:https://git.coding.net/Xoxo_x/IFlyDemo.git

    使用讯飞的SDK,需要进行注册,并添加项目,其SDK与申请的APPID有关,不同的SDK和不同的APPID不能通用

    本文的APPID:57d22af3
    说明:该id没有被审核,每天使用次数有限

    原demo中含有不必要的文件,这里进行了处理。
    使用这几个文件,就可以进行语音识别了。

    结构如下:

    这里写图片描述

    /**
    语音听写demo
    使用该功能仅仅需要四步
    1.创建识别对象;
    2.设置识别参数;
    3.有选择的实现识别回调;
    4.启动识别
    */

    导入 #import “iflyMSC/iflyMSC.h”

    //
    //  ViewController.h
    //  IFlyDemo
    //
    //  Created by fsk-0-1-n on 17/2/21.
    //  Copyright © 2017年 Xoxo. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    #import "iflyMSC/iflyMSC.h"
    
    @class IFlySpeechRecognizer;
    @class IFlyPcmRecorder;
    
    @interface ViewController : UIViewController<IFlySpeechRecognizerDelegate,IFlyRecognizerViewDelegate,IFlyPcmRecorderDelegate>
    @property (nonatomic, strong) NSString *pcmFilePath;//音频文件路径
    @property (nonatomic, strong) IFlySpeechRecognizer *iFlySpeechRecognizer;//不带界面的识别对象
    
    
    
    
    @property (nonatomic, strong) NSString * result;
    @property (nonatomic, assign) BOOL isCanceled;
    
    @property (nonatomic,strong) IFlyPcmRecorder *pcmRecorder;//录音器,用于音频流识别的数据传入
    
    @end
    
    

    demo录音文件保存路径

    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
        NSString *cachePath = [paths objectAtIndex:0];
        _pcmFilePath = [[NSString alloc] initWithFormat:@"%@",[cachePath stringByAppendingPathComponent:@"asr.pcm"]];
    }

    /**
    设置识别参数
    **/

    
    -(void)initRecognizer
    {
        NSLog(@"%s",__func__);
    
    
            //单例模式,无UI的实例
            if (_iFlySpeechRecognizer == nil) {
                _iFlySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];
    
                [_iFlySpeechRecognizer setParameter:@"" forKey:[IFlySpeechConstant PARAMS]];
    
                //设置听写模式
                [_iFlySpeechRecognizer setParameter:@"iat" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
            }
            _iFlySpeechRecognizer.delegate = self;
    
            if (_iFlySpeechRecognizer != nil) {
                IATConfig *instance = [IATConfig sharedInstance];
    
                //设置最长录音时间
                [_iFlySpeechRecognizer setParameter:instance.speechTimeout forKey:@"2000"];
                //设置后端点
                [_iFlySpeechRecognizer setParameter:instance.vadEos forKey:@"1000"];
                //设置前端点
                [_iFlySpeechRecognizer setParameter:instance.vadBos forKey:@"1000"];
                instance.vadBos = @"1000";
                instance.vadEos = @"1000";
                //网络等待时间
                [_iFlySpeechRecognizer setParameter:@"10000" forKey:[IFlySpeechConstant NET_TIMEOUT]];
    
                //设置采样率,推荐使用16K
                [_iFlySpeechRecognizer setParameter:instance.sampleRate forKey:[IFlySpeechConstant SAMPLE_RATE]];
                //设置语言
                [instance setLanguage:[IATConfig english]];
                if ([instance.language isEqualToString:[IATConfig chinese]]) {
                    //设置语言
                    [_iFlySpeechRecognizer setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
                    //设置方言
                    [_iFlySpeechRecognizer setParameter:instance.accent forKey:[IFlySpeechConstant ACCENT]];
                }else if ([instance.language isEqualToString:[IATConfig english]]) {
                    [_iFlySpeechRecognizer setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
                }
                //设置是否返回标点符号
                [_iFlySpeechRecognizer setParameter:instance.dot forKey:[IFlySpeechConstant ASR_PTT_NODOT]];
                instance.dot = [IFlySpeechConstant ASR_PTT_NODOT];
            }
    
            //初始化录音器
            if (_pcmRecorder == nil)
            {
                _pcmRecorder = [IFlyPcmRecorder sharedInstance];
            }
    
            _pcmRecorder.delegate = self;
    
            [_pcmRecorder setSample:[IATConfig sharedInstance].sampleRate];
    
            [_pcmRecorder setSaveAudioPath:nil];    //不保存录音文件
    
    }
    
    /**
     音量回调函数
     volume 0-30
     ****/
    - (void) onVolumeChanged: (int)volume
    {
        if (self.isCanceled) {
            return;
        }
    
        NSString * vol = [NSString stringWithFormat:@"音量:%d",volume];
        NSLog(@"音量回调 : %@",vol);
    }
    
    /**
     开始识别回调
     ****/
    - (void) onBeginOfSpeech
    {
        NSLog(@"onBeginOfSpeech");
    
    }
    
    
    /**
     停止录音回调
     ****/
    - (void) onEndOfSpeech
    {
        NSLog(@"停止录音");
    
        [_pcmRecorder stop];
         NSLog(@"停止录音");
    }
    
    /**
     听写结束回调(注:无论听写是否正确都会回调)
     error.errorCode =
     0     听写正确
     other 听写出错
     ****/
    - (void) onError:(IFlySpeechError *) error
    {
        NSLog(@"%s",__func__);
    
        if ([IATConfig sharedInstance].haveView == NO ) {
    
    
    
            NSString *text ;
    
            if (self.isCanceled) {
                text = @"识别取消";
    
            } else if (error.errorCode == 0 ) {
                if (_result.length == 0) {
                    text = @"无识别结果";
                }else {
                    text = @"识别成功";
                    //清空识别结果
                    _result = nil;
                }
            }else {
                text = [NSString stringWithFormat:@"发生错误:%d %@", error.errorCode,error.errorDesc];
                NSLog(@"%@",text);
            }
    
            NSLog(@"%@",text);
    
        }else {
    //        NSLog(@"识别结束");
    
            NSLog(@"errorCode:%d",[error errorCode]);
        }
    
     }
    /**
     无界面,听写结果回调
     results:听写结果
     isLast:表示最后一次
     ****/
    - (void) onResults:(NSArray *) results isLast:(BOOL)isLast
    {
    
    
        GetJSONResult *result = [[GetJSONResult alloc]init];
    
        NSString * resultFromJson =  [result onResultsOC:results isLastOC:isLast];
    
    
        NSLog(@"识别结果 --  %@",resultFromJson);
    }

    GetJSONResult 关于这个文件是从原文抽离的。是对返回的结果,进行解析,已到达显示的目的。
    如下:

    #import <Foundation/Foundation.h>
    
    @interface GetJSONResult : NSObject
    - (NSString *) onResultsOC:(NSArray *) results isLastOC:(BOOL)isLast;
    @end
    
    //
    //  GetJSONResult.m
    //  WordLightFSK
    //
    //  Created by fsk-0-1-n on 16/10/31.
    //  Copyright © 2016年 Xoxo. All rights reserved.
    //
    
    #import "GetJSONResult.h"
    #import "ISRDataHelper.h"
    
    @implementation GetJSONResult{
        NSString *result;
    }
    - (instancetype)init{
        self = [super init];
        return self;
    }
    - (NSString *) onResultsOC:(NSArray *) results isLastOC:(BOOL)isLast
    {
    
        NSMutableString *resultString = [[NSMutableString alloc] init];
        NSDictionary *dic = results[0];
        for (NSString *key in dic) {
            [resultString appendFormat:@"%@",key];
        }
    
        result =[NSString stringWithFormat:@"%@%@", result,resultString];
        NSString * resultFromJson =  [ISRDataHelper stringFromJson:resultString];
    
        if (isLast){
            NSLog(@"听写结果(json):%@测试",  result);
        }
        NSLog(@"_result=%@",result);
        NSLog(@"resultFromJson=%@",resultFromJson);
        return resultFromJson;
    
    }
    @end
    

    IATConfig 是语音识别的配置文件,可以设置前端点,后端点,语种,是否返回标点符号,网络连接等待时间等。

    ISRDataHelper 是解析json数据的

    /**
     解析听写json格式的数据
     params例如:
     {"sn":1,"ls":true,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"w":"白日","sc":0}]},{"bg":0,"cw":[{"w":"依山","sc":0}]},{"bg":0,"cw":[{"w":"尽","sc":0}]},{"bg":0,"cw":[{"w":"黄河入海流","sc":0}]},{"bg":0,"cw":[{"w":"。","sc":0}]}]}
     ****/
    + (NSString *)stringFromJson:(NSString*)params
    {
        if (params == NULL) {
            return nil;
        }
    
        NSMutableString *tempStr = [[NSMutableString alloc] init];
        NSDictionary *resultDic  = [NSJSONSerialization JSONObjectWithData:    //返回的格式必须为utf8的,否则发生未知错误
                                    [params dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
    
        if (resultDic!= nil) {
            NSArray *wordArray = [resultDic objectForKey:@"ws"];
    
            for (int i = 0; i < [wordArray count]; i++) {
                NSDictionary *wsDic = [wordArray objectAtIndex: i];
                NSArray *cwArray = [wsDic objectForKey:@"cw"];
    
                for (int j = 0; j < [cwArray count]; j++) {
                    NSDictionary *wDic = [cwArray objectAtIndex:j];
                    NSString *str = [wDic objectForKey:@"w"];
                    [tempStr appendString: str];
                }
            }
        }
        return tempStr;
    }
    

    log信息:

    2017-02-22 21:58:58.404424 IFlyDemo[9843:3111103] _result=(null){"sn":1,"ls":false,"bg":0,"ed":0,"ws":[{"bg":0,"cw":[{"sc":0.00,"w":"Good"}]}]}
    2017-02-22 21:58:58.404567 IFlyDemo[9843:3111103] resultFromJson=Good
    2017-02-22 21:58:58.404663 IFlyDemo[9843:3111103] 识别结果 --  Good
    2017-02-22 21:58:58.405082 IFlyDemo[9843:3111103] 音量回调 : 音量:0
    2017-02-22 21:58:58.406661 IFlyDemo[9843:3111103] 音量回调 : 音量:0
    2017-02-22 21:58:58.409720 IFlyDemo[9843:3111103] 音量回调 : 音量:0
    2017-02-22 21:58:58.412686 IFlyDemo[9843:3111103] 音量回调 : 音量:0

    识别结果 – Good。成功识别了英语。

    本文介绍到此结束。

    Demo 地址:https://git.coding.net/Xoxo_x/IFlyDemo.git

    展开全文
  • 最近为小程序增加语音识别转文字的功能,坑路不断,特此记录。 微信开发者工具 开发者工具上的录音文件与移动端格式不同,暂时只可在工具上进行播放调试,无法直接播放或者在客户端上播放 debug的时候发现,...

    最近为小程序增加语音识别转文字的功能,坑路不断,特此记录。

    微信开发者工具

    开发者工具上的录音文件与移动端格式不同,暂时只可在工具上进行播放调试,无法直接播放或者在客户端上播放

    debug的时候发现,工具上录音的路径是http://tmp/xxx.mp3,客户端上录音是wxfile://xxx.mp3。 忽悠呢,不是格式不同,是映射路径不同。
    其实做个兼容也不难,每次提示一行文字,很丑。

    采样率与编码码率限制

    每种采样率有对应的编码码率范围有效值,设置不合法的采样率或编码码率会导致录音失败。详细看这个
    https://developers.weixin.qq.com/miniprogram/dev/api/media/recorder/RecorderManager.start.html

    一开始没有留意,导致录音不成功。
    试过几次后,采用这样的配置,感觉录音识别率和体积之间比较好平衡:

    1
    2
    3
    
    sampleRate: 16000, //采样率
    numberOfChannels: 1, //录音通道数
    encodeBitRate: 96000, //编码码率
    

    单通道基本是必选的。因为asr只支持单通道。frameSize也是可以的,但是要考虑截断对识别的影响。暂时没有用上。

    录音优化

    因为可能误按,于是对小于500ms的录音直接忽略。
    另外,松开录音按键后,再延迟一点时间才真正stop录音。

    录音文件格式

    微信录音文件支持mp3和aac。这2种格式文件都比较小,aac文件体积更小。这对上传来说是件好事情,速度更快。
    但是对语音识别转文字就不友好了。因为百度、阿里云ASR、讯飞的语音转文字接口都不支持aac和mp3,通常要求是pcm或者wav格式。
    如果微信录音能提供wav格式,那么就不用服务器做格式转换了,但是wav格式体积是mp3、aac的5到10倍,至少短期是没戏了,这也是很多人吐槽的地方。

    服务器转换录音文件格式

    可以用java第三方库转换,也可以用Process调用ffmpeg转换。要注意的是,根据识别API的要求来做转换。比如阿里云asr的要求是:

    支持音频编码格式:pcm(无压缩的pcm文件或wav文件)、opus,16bit采样位数的单声道(mono);
    支持音频采样率:8000Hz、16000Hz;

    java ProcessBuilder要使用数组传参

    转换音视频,习惯用ffmpeg。安装完ffmpeg之后,用java新建进程调用。

    1
    
    Process = new ProcessBuilder("ffmpeg -i in.mp3 out.wav").start();
    

    一直提示CreateProcess error。 后来看文档才发现,要以数组的形式传入参数。

    1
    
    Process = new ProcessBuilder("ffmpeg", "-y", "-i", "in.mp3", "out.wav").start();
    

    这样就启动成功了。
    关于java启动进程,不是本文重点,以后再写篇文章总结。

    阿里云asr sdk使用问题

    这个问题困扰了一天时间,回想起来真是吐血。
    问题表现是微信录制的语音很多都识别不了。
    最初是直接把录音mp3文件转换为pcm文件,本地能播放,但是用阿里云asr sdk却识别不了。 一开始以为是文件编码问题。特意查了asr支持的文件格式,用ffprobe检查,potplayer看属性,都没有看出问题。
    甚至把启动ffmpeg进程转换也改了,用了java的库去做,还是不行。
    后来为了方便测试问题,用asr的restful接口测试录音文件,都能识别! 似乎是sdk的问题。于是打开官方文档例子对比。发现用的是sdk 2.x,老铁啊你复制粘贴过来的代码竟然少了!欲哭无泪。

    1
    2
    3
    4
    
    // TODO  重要提示:这里是用读取本地文件的形式模拟实时获取语音流并发送的,因为read很快,所以这里需要sleep
    // TODO  如果是真正的实时获取语音,则无需sleep, 如果是8k采样率语音,第二个参数改为8000
    int deltaSleep = getSleepDelta(len, sampleRate);
    Thread.sleep(deltaSleep);
    

    也少了对sampleRate的设置。

    阿里云asr token过期

    因为用的是免费版asr,没有给福报厂充值,因此token一天失效,导致联调的时候突然报错。
    最后实在受不了,写了个定时任务每小时更新token。
    这,就是beggar VIP?

    wx.uploadFile返回值

    封装了一个接口parseResponse,统一解析查询结果(文本、语音)。发现奇怪的问题:

    • 用文本查询的,可以正常解析结果
    • 用语音查询的,明明已经返回了结果,却解析不了!

    只能console.log()打印出来对比

    第一行是wx.request()发起文本查询。
    第二行是wx.uploadFile()上传语音文件后直接语音转文字,并且查询。

    wx.request返回值是json对象。
    wx.uploadFile返回值是“字符串”!
    wx.uploadFile返回值是“字符串”!
    wx.uploadFile返回值是“字符串”!
    重要的事情要说3遍。尽管Content-Type: "application/json; charset=utf8",但是微信根本不做转换!非常坑爹!

    解决:对wx.uploadFile返回值进行JSON.parse(res.data),得到json对象。

    更换appid和secret

    因为正式小程序项目账号一直拖着没有申请,所以这段时间用的是我个人的appid和secret进行开发。
    等正式账号准备好了,更新了小程序项目的appid,并且发出内部体验包。

    此时已经深夜1点半,头脑有点发懵。只更新了小程序appid,竟然忘了更新服务器的appid和secret。。。
    于是乎反复报错登录失败。
    过了一会才反映过来,更新服务器的appi的secret,但是还是用户。才想起忘了还有storage缓存没有清除?,里面放着自定义的session。这下真机体验没问题了。
    但是微信开发者工具又是登录失败。反复摸索后发现:更换小程序appid后,清除所有数据,关闭开发者工具,重新打开,这就正常了。应该是微信开发者工具的bug。

    结论:深夜不宜加班写bug?。

     

    https://ycwu314.github.io/p/miniapp-speech-to-text-experience/

    展开全文
  • 前言  用mui混合开发的APP,...通过官方文档我们大致可以确定如果想要实现语音识别,要做到以下几点: 1.获取Access Token 2.获取录音 REST API的形式传给百度服务器,返回文字 1.获取Access Token 1.1.申请百...

    前言

      用mui混合开发的APP,现有一个功能需求就是语音转换成文字,并把语音进行保存。对此考虑两种选择讯飞和百度。最终选择了百度语音。

    百度语音

     

      

    通过官方文档我们大致可以确定如果想要实现语音识别,要做到以下几点:

    1.获取Access Token

    2.获取录音 REST API的形式传给百度服务器,返回文字

    1.获取Access Token

    1.1.申请百度开发账号

    我是把百度信息放到系统中的配置文件中,每次使用的时候调用接口即可。如果有所修改便于维护。

       <!--百度人工智能平台访问配置-->
        <add key="BaiduAIPAppID" value="22465672" />
        <add key="BaiduAIPAPIKey" value="hUw1j0gFd5k0GVzM3m9dGGnL" />
        <add key="BaiduAIPSecretKey" value="YddydGN4NqbzHUGtFu1Gug8jhFXKf7vN" />

    ps:以上百度账号不能正常使用,自己如果要用请自行申请。

    1.2.获取Access Token

    从官网上我们可以知道access Token 是有有效期的。但在有效期下多次提交申请获得Access Token是相同的,所以我在同步到手机缓存是设置了有效期。在判断是否存在或者是否过期而做出是否重新申请的判断。

    1.2.1.初始化更新数据

    下载安装app后,把百度账号存入手机缓存中,以便于后期直接使用。

       /*
         * 更新百度人工智能平台访问配置 
         */
        function UpdateBaiduAipConfig(){
        //代用服务器接口获取百度账号相应信息保存到手机缓存中
            platform.ajax("MBase/GetBaiduAipConfig",null,function(data){
                if(data){
                    var currentAppID = platform.GetData('BaiduAIPAppID') ;
                    console.log(currentAppID)
                    if (currentAppID != data.AppID) {//判断是否已存在相关数据
                        console.log("AppID变化,更新配置");
                        platform.SaveData("BaiduAIPAppID", data.AppID)//此方法是封装的H5存储页面缓存在这不再过多叙述
                        platform.SaveData("BaiduAIPAPIKey", data.APIKey)
                        platform.SaveData("BaiduAIPSecretKey", data.SecretKey)
                        // 强制刷新token;
                        platform.SaveData("token_timeout", new Date().getTime())
                    }else{
                        console.log("AppID没有变化,无需更新");
                    }
                }      
            },"post");
        }

    以上把百度账号存进了到了手机页面缓存中,一直有效。

    1.2.2.获取token

    判断是否需要更新获取Token
    //判断是否需要更新获取Token
    function needUpdateToken() {
            if(access_token == null || access_token == undefined || access_token.length == 0) {
                console.log("没有token,需要更新");
                return true;
            }
    
            var now = new Date().getTime();
            if(token_timeout - now < 86400 * 1000) {
                console.log("token即将过期,需要更新");
                return true;
            }
    
            console.log("token有效,无需更新:" + access_token);
            return false;
        }

    //获取token

    //获取token
    function UpdateBaiduAipToken(entry) {
            var w = plus.nativeUI.showWaiting("请求中,请稍候...");
            var token_url = generateTokenUrl();
            mui.ajax(token_url, {
                data: '',
                type: 'post',
                contentType: "application/json; charset=utf-8",
                timeout: 5000,
                success: function(resp) {
                    w.close();
                    access_token = resp.access_token;
                    var expires_in = resp.expires_in;
                    var now = new Date();
                    token_timeout = now.getTime() + expires_in * 1000;
                    platform.SaveData("access_token", access_token);
                    platform.SaveData("token_timeout", token_timeout);
                    if(entry) {
                        asr(entry);
                    }
                },
                error: function(xhr, type, errorThrown) {
                    w.close();
                    alert("网络请求出错");
                }
            });
        }

    //获取百度信息

     

    function get_baidu_api_key() {
            return platform.GetData("BaiduAIPAPIKey");
        }
    
        function get_baidu_secret_key() {
            return platform.GetData("BaiduAIPSecretKey");
        }
    
        function get_baidu_app_id() {
            return platform.GetData("BaiduAIPAppID");
        }

     

    //获取token url

    var token_url_base = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=";
        var asr_url_base = "http://vop.baidu.com/server_api"
        var len = 0;
        var app_id = get_baidu_app_id();
        var access_token = platform.GetData("access_token");
        var token_timeout = platform.GetData("token_timeout");
    
        function generateTokenUrl() {
            var api_key = get_baidu_api_key();
            var secret_key = get_baidu_secret_key();
            console.log(token_url_base + api_key + "&client_secret=" + secret_key)
            return token_url_base + api_key + "&client_secret=" + secret_key;
        }

    2.获取录音 REST API的形式传给百度服务器,返回文字

     

    1.首先是获取录音

    2.传给百度服务器

    3.获取返回信息赋值

    4.保存语音

    2.1.首先是获取录音

    全局变量

    // 开始录音
        var r = null,
            t = 0,
            ri = null,
            rt = null;
    
        var rate = 16000;
        var channel = 1;
        if(mui.os.android) {
            var format = "amr";
        } else if(mui.os.ios) {
            var format = "wav";
        }
    View Code

    利用MUI H5+获取录音  r = plus.audio.getRecorder(); 

    function startRecord() {
            var bt = $(this).attr("id");
            //console.log( "开始录音:" );
            r = plus.audio.getRecorder();
            //$$.alert(r.supportedFormats);
            if(r == null) {
                //console.log( "录音对象未获取" );
                return;
            }
            r.record({
                filename: "_doc/audio/",
                samplerate: rate
            }, function(p) {
                //console.log( "录音完成:"+p );
                plus.io.resolveLocalFileSystemURL(p, function(entry) {
                        showMsic(entry.toLocalURL());//保存语音
                        doASR(entry);//语音识别转换
                    //createItem( entry );
                }, function(e) {
                    //console.log( "读取录音文件错误:"+e.message );
                });
            }, function(e) {
                //console.log( "录音失败:"+e.message );
            });
            er.style.display = "block";
            t = 0;
            ri = setInterval(function() {
                t++;
                rt.innerText = timeToStr(t);
            }, 1000);
        }
    
        function doASR(entry) {
            if(needUpdateToken()) {
                UpdateBaiduAipToken(entry);
            } else {
                asr(entr);
            }
        }

    2.2.传给百度服务端

    //转换语音编码
    function asr(entry) {
            var w = plus.nativeUI.showWaiting("请求中,请稍候...");
            entry.file(function(file) {
                len = file.size;
                console.log("录音文件长度:" + len);
                var reader = new plus.io.FileReader();
                reader.onload = function(e) {
                    var strResult = e.target.result;
                    console.log("编码结果:" + strResult);
                    var index = strResult.indexOf('base64,') + 7;
                    var base64Str = strResult.slice(index, strResult.length);
                    w.close();
                    speech2txt(base64Str);
                }
                reader.readAsDataURL(file);
            }, function(e) {
                w.close();
                console.log("录音文件处理出错:" + e);
            })
        }
    //传给百度服务器
    function speech2txt(base64Str) {
            var w = plus.nativeUI.showWaiting("请求中,请稍候...");
            var data1 = {
                "format": format,
                "rate": rate,
                "dev_pid": 1536,
                "channel": channel,
                "token": access_token,
                "cuid": app_id,
                "len": len,
                "speech": base64Str
            };
            var dataStr = JSON.stringify(data1);
            console.log("json: " + dataStr);
            mui.ajax(asr_url_base, {
                data: dataStr,
                type: 'post',
                contentType: "application/json",
                timeout: 5000,
                success: function(resp) {
                    w.close();
                    if(resp.result == undefined || resp.result == '') {
                        console.log("转换失败:" + resp.err_msg + "  err_no: " + resp.err_no);
                        return;
                    }
                    appendVoiceText(resp.result[0]);//赋值
                    console.log("转换完成:" + resp.result[0]);
                },
                error: function(xhr, type, errorThrown) {
                    w.close();
                    if(type == 'timeout') {
                        console.log("录音超时");
                    } else {
                        console.log("网络请求出错");
                    }
                }
            });
        }

    2.3.赋值

    function appendVoiceText(voicePath) {
            cv = $("#HTContent").val()//获取已有数据
                if(cv.length > 0) {
                    cv = cv + " " + voicePath;
                } else {
                    cv = voicePath;
                }
                $("#HTContent").val(cv);
        }

    2.4.保存语音

    function showMsic(mic) { //显示图片
            if(mic) {
                if($("#image-list ul li").length <= 0) {
                    $("#image-list ul").html("");
                }
                var mcount = $("#image-list ul .muivideo").length + 1;
                var pname = mic.substring(mic.lastIndexOf('/') + 1);
                var imgstr = "<li data-path=\"" + mic + "\" >" +
                    "<div class=\"muivideo\">录音" + mcount + "</div>" +
                    "<span class=\"mui-icon mui-icon-close imgdel\"></span>" +
                    "</li>";
                $(imgstr).appendTo("#image-list ul");
                $("#sendvideo").focus();
            }
        }

    3.其他

    停止录音,播放相应文件,停止播放,上传语音长度

    // 播放文件相关对象
        var p = null,
            pt = null,
            pp = null,
            ps = null,
            pi = null;
        // 开始播放
        function startPlay(url) {
            ep.style.display = "block";
            var L = pp.clientWidth;
            p = plus.audio.createPlayer(url);
            p.play(function() {
                //console.log("播放完成!" );
                // 播放完成
                pt.innerText = timeToStr(d) + "/" + timeToStr(d);
                ps.style.webkitTransition = "all 0.3s linear";
                ps.style.width = L + "px";
                stopPlay();
            }, function(e) {
                //console.log( "播放音频文件\""+url+"\"失败:"+e.message );
            });
            // 获取总时长
            var d = p.getDuration();
            if(!d) {
                pt.innerText = "00:00:00/" + timeToStr(d);
            }
            pi = setInterval(function() {
                if(!d) { // 兼容无法及时获取总时长的情况
                    d = p.getDuration();
                }
                var c = p.getPosition();
                if(!c) { // 兼容无法及时获取当前播放位置的情况
                    return;
                }
                pt.innerText = timeToStr(c) + "/" + timeToStr(d);
                var pct = Math.round(L * c / d);
                if(pct < 8) {
                    pct = 8;
                }
                ps.style.width = pct + "px";
            }, 1000);
        }
    
        // 停止播放
        function stopPlay() {
            clearInterval(pi);
            pi = null;
            setTimeout(resetPlay, 500);
            // 操作播放对象
            if(p) {
                p.stop();
                p = null;
            }
        }
    
        // 重置播放页面内容
        function resetPlay() {
            ep.style.display = "none";
            ps.style.width = "8px";
            ps.style.webkitTransition = "all 1s linear";
            pt.innerText = "00:00:00/00:00:00";
        }
    
        function timeToStr(ts) {
            if(isNaN(ts)) {
                return "--:--:--";
            }
            var h = parseInt(ts / 3600);
            var m = parseInt((ts % 3600) / 60);
            var s = parseInt(ts % 60);
            if(s > 20) {
                stopRecord(); //超过20秒退出
            }
            return(ultZeroize(h) + ":" + ultZeroize(m) + ":" + ultZeroize(s));
        };
    
        function ultZeroize(v, l) {
            var z = "";
            l = l || 2;
            v = String(v);
            for(var i = 0; i < l - v.length; i++) {
                z += "0";
            }
            return z + v;
        };
    View Code

     

     

     

     

     

     

      

     

    转载于:https://www.cnblogs.com/kmonkeywyl/p/10234186.html

    展开全文
  • 语音识别转文字python

    2019-11-08 08:46:54
    装机激活和python办公 含人脸识别自动锁屏,语音转文字,图片的文字识别抓取,加密翻译记事本,vn, dg等,详见内部readme。 :https://pan.baidu.com/s/1cekF1rOtzDfYudvPIskN4w 提码:36a2 Bofey媒体办公硬件驱动...
  • 谷歌在其开源博客中宣布开源 Android语音识别转录工具——Live Transcribe的语音引擎,它可以将语音或对话实时转录为文字,还能够为听障人士提供帮助。Live Transcribe 是谷歌于今年2月推出的一款Android应用程序,...
  • uni-app使用百度语音识别转文字

    万次阅读 2020-04-09 16:58:26
    recorderManager.start({ sampleRate: 16000 // 必须设置是后台设置的参数,不然百度语音识别不了 }); }, endRecord() { console.log('录音结束'); _this = this; recorderManager.stop(); }, playVoice() { ...
  • 昨日,谷歌在其开源博客中宣布开源 Android语音识别转录工具——Live Transcribe的语音引擎(Live Transcribe Speech Engine),它旨在将语音或对话实时转录为文字,还能够为听障人士提供帮助。Live Transcribe 是...
  • 讯飞听见智能会议系统是基于科大讯飞业界领先的语音识别技术所研发,可满足公司发布会、电视节目直播、大型会议、培训等一系列需要进行实时文字转写的场景。本文档主要介绍了讯飞听见智能会议系统的研发背景、设计...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,320
精华内容 528
关键字:

语音识别转文字