前言

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

百度语音

  

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

1.获取Access Token

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

1.获取Access Token

1.1.申请百度开发账号

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

  1. <!--百度人工智能平台访问配置-->
  2. <add key=" />
  3. <add key="BaiduAIPAPIKey" value="hUw1j0gFd5k0GVzM3m9dGGnL" />
  4. <add key="BaiduAIPSecretKey" value="YddydGN4NqbzHUGtFu1Gug8jhFXKf7vN" />

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

1.2.获取Access Token

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

1.2.1.初始化更新数据

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

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

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

1.2.2.获取token

  1. 判断是否需要更新获取Token
  1. //判断是否需要更新获取Token
  2. function needUpdateToken() {
  3. if(access_token == null || access_token == undefined || access_token.length == 0) {
  4. console.log("没有token,需要更新");
  5. return true;
  6. }
  7.  
  8. var now = new Date().getTime();
  9. if(token_timeout - now < 86400 * 1000) {
  10. console.log("token即将过期,需要更新");
  11. return true;
  12. }
  13.  
  14. console.log("token有效,无需更新:" + access_token);
  15. return false;
  16. }

//获取token

  1. //获取token
  2. function UpdateBaiduAipToken(entry) {
  3. var w = plus.nativeUI.showWaiting("请求中,请稍候...");
  4. var token_url = generateTokenUrl();
  5. mui.ajax(token_url, {
  6. data: '',
  7. type: 'post',
  8. contentType: "application/json; charset=utf-8",
  9. timeout: 5000,
  10. success: function(resp) {
  11. w.close();
  12. access_token = resp.access_token;
  13. var expires_in = resp.expires_in;
  14. var now = new Date();
  15. token_timeout = now.getTime() + expires_in * 1000;
  16. platform.SaveData("access_token", access_token);
  17. platform.SaveData("token_timeout", token_timeout);
  18. if(entry) {
  19. asr(entry);
  20. }
  21. },
  22. error: function(xhr, type, errorThrown) {
  23. w.close();
  24. alert("网络请求出错");
  25. }
  26. });
  27. }

//获取百度信息

  1. function get_baidu_api_key() {
  2. return platform.GetData("BaiduAIPAPIKey");
  3. }
  4.  
  5. function get_baidu_secret_key() {
  6. return platform.GetData("BaiduAIPSecretKey");
  7. }
  8.  
  9. function get_baidu_app_id() {
  10. return platform.GetData("BaiduAIPAppID");
  11. }

//获取token url

  1. var token_url_base = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials&client_id=";
  2. var asr_url_base = "http://vop.baidu.com/server_api"
  3. var len = 0;
  4. var app_id = get_baidu_app_id();
  5. var access_token = platform.GetData("access_token");
  6. var token_timeout = platform.GetData("token_timeout");
  7.  
  8. function generateTokenUrl() {
  9. var api_key = get_baidu_api_key();
  10. var secret_key = get_baidu_secret_key();
  11. console.log(token_url_base + api_key + "&client_secret=" + secret_key)
  12. return token_url_base + api_key + "&client_secret=" + secret_key;
  13. }

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

1.首先是获取录音

2.传给百度服务器

3.获取返回信息赋值

4.保存语音

2.1.首先是获取录音

全局变量

  1. // 开始录音
  2. var r = null,
  3. t = 0,
  4. ri = null,
  5. rt = null;
  6.  
  7. var rate = 16000;
  8. var channel = 1;
  9. if(mui.os.android) {
  10. var format = "amr";
  11. } else if(mui.os.ios) {
  12. var format = "wav";
  13. }

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

  1. function startRecord() {
  2. var bt = $(this).attr("id");
  3. //console.log( "开始录音:" );
  4. r = plus.audio.getRecorder();
  5. //$$.alert(r.supportedFormats);
  6. if(r == null) {
  7. //console.log( "录音对象未获取" );
  8. return;
  9. }
  10. r.record({
  11. filename: "_doc/audio/",
  12. samplerate: rate
  13. }, function(p) {
  14. //console.log( "录音完成:"+p );
  15. plus.io.resolveLocalFileSystemURL(p, function(entry) {
  16. showMsic(entry.toLocalURL());//保存语音
  17. doASR(entry);//语音识别转换
  18. //createItem( entry );
  19. }, function(e) {
  20. //console.log( "读取录音文件错误:"+e.message );
  21. });
  22. }, function(e) {
  23. //console.log( "录音失败:"+e.message );
  24. });
  25. er.style.display = "block";
  26. t = 0;
  27. ri = setInterval(function() {
  28. t++;
  29. rt.innerText = timeToStr(t);
  30. }, 1000);
  31. }
  32.  
  33. function doASR(entry) {
  34. if(needUpdateToken()) {
  35. UpdateBaiduAipToken(entry);
  36. } else {
  37. asr(entr);
  38. }
  39. }

2.2.传给百度服务端

  1. //转换语音编码
  2. function asr(entry) {
  3. var w = plus.nativeUI.showWaiting("请求中,请稍候...");
  4. entry.file(function(file) {
  5. len = file.size;
  6. console.log("录音文件长度:" + len);
  7. var reader = new plus.io.FileReader();
  8. reader.onload = function(e) {
  9. var strResult = e.target.result;
  10. console.log("编码结果:" + strResult);
  11. var index = strResult.indexOf('base64,') + 7;
  12. var base64Str = strResult.slice(index, strResult.length);
  13. w.close();
  14. speech2txt(base64Str);
  15. }
  16. reader.readAsDataURL(file);
  17. }, function(e) {
  18. w.close();
  19. console.log("录音文件处理出错:" + e);
  20. })
  21. }
  22. //传给百度服务器
  23. function speech2txt(base64Str) {
  24. var w = plus.nativeUI.showWaiting("请求中,请稍候...");
  25. var data1 = {
  26. "format": format,
  27. "rate": rate,
  28. "dev_pid": 1536,
  29. "channel": channel,
  30. "token": access_token,
  31. "cuid": app_id,
  32. "len": len,
  33. "speech": base64Str
  34. };
  35. var dataStr = JSON.stringify(data1);
  36. console.log("json: " + dataStr);
  37. mui.ajax(asr_url_base, {
  38. data: dataStr,
  39. type: 'post',
  40. contentType: "application/json",
  41. timeout: 5000,
  42. success: function(resp) {
  43. w.close();
  44. if(resp.result == undefined || resp.result == '') {
  45. console.log("转换失败:" + resp.err_msg + " err_no: " + resp.err_no);
  46. return;
  47. }
  48. appendVoiceText(resp.result[0]);//赋值
  49. console.log("转换完成:" + resp.result[0]);
  50. },
  51. error: function(xhr, type, errorThrown) {
  52. w.close();
  53. if(type == 'timeout') {
  54. console.log("录音超时");
  55. } else {
  56. console.log("网络请求出错");
  57. }
  58. }
  59. });
  60. }

2.3.赋值

  1. function appendVoiceText(voicePath) {
  2. cv = $("#HTContent").val()//获取已有数据
  3. if(cv.length > 0) {
  4. cv = cv + " " + voicePath;
  5. } else {
  6. cv = voicePath;
  7. }
  8. $("#HTContent").val(cv);
  9. }

2.4.保存语音

  1. function showMsic(mic) { //显示图片
  2. if(mic) {
  3. if($("#image-list ul li").length <= 0) {
  4. $("#image-list ul").html("");
  5. }
  6. var mcount = $("#image-list ul .muivideo").length + 1;
  7. var pname = mic.substring(mic.lastIndexOf('/') + 1);
  8. var imgstr = "<li data-path=\"" + mic + "\" >" +
  9. "<div class=\"muivideo\">录音" + mcount + "</div>" +
  10. "<span class=\"mui-icon mui-icon-close imgdel\"></span>" +
  11. "</li>";
  12. $(imgstr).appendTo("#image-list ul");
  13. $("#sendvideo").focus();
  14. }
  15. }

3.其他

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

  1. // 播放文件相关对象
  2. var p = null,
  3. pt = null,
  4. pp = null,
  5. ps = null,
  6. pi = null;
  7. // 开始播放
  8. function startPlay(url) {
  9. ep.style.display = "block";
  10. var L = pp.clientWidth;
  11. p = plus.audio.createPlayer(url);
  12. p.play(function() {
  13. //console.log("播放完成!" );
  14. // 播放完成
  15. pt.innerText = timeToStr(d) + "/" + timeToStr(d);
  16. ps.style.webkitTransition = "all 0.3s linear";
  17. ps.style.width = L + "px";
  18. stopPlay();
  19. }, function(e) {
  20. //console.log( "播放音频文件\""+url+"\"失败:"+e.message );
  21. });
  22. // 获取总时长
  23. var d = p.getDuration();
  24. if(!d) {
  25. pt.innerText = "00:00:00/" + timeToStr(d);
  26. }
  27. pi = setInterval(function() {
  28. if(!d) { // 兼容无法及时获取总时长的情况
  29. d = p.getDuration();
  30. }
  31. var c = p.getPosition();
  32. if(!c) { // 兼容无法及时获取当前播放位置的情况
  33. return;
  34. }
  35. pt.innerText = timeToStr(c) + "/" + timeToStr(d);
  36. var pct = Math.round(L * c / d);
  37. if(pct < 8) {
  38. pct = 8;
  39. }
  40. ps.style.width = pct + "px";
  41. }, 1000);
  42. }
  43.  
  44. // 停止播放
  45. function stopPlay() {
  46. clearInterval(pi);
  47. pi = null;
  48. setTimeout(resetPlay, 500);
  49. // 操作播放对象
  50. if(p) {
  51. p.stop();
  52. p = null;
  53. }
  54. }
  55.  
  56. // 重置播放页面内容
  57. function resetPlay() {
  58. ep.style.display = "none";
  59. ps.style.width = "8px";
  60. ps.style.webkitTransition = "all 1s linear";
  61. pt.innerText = "00:00:00/00:00:00";
  62. }
  63.  
  64. function timeToStr(ts) {
  65. if(isNaN(ts)) {
  66. return "--:--:--";
  67. }
  68. var h = parseInt(ts / 3600);
  69. var m = parseInt((ts % 3600) / 60);
  70. var s = parseInt(ts % 60);
  71. if(s > 20) {
  72. stopRecord(); //超过20秒退出
  73. }
  74. return(ultZeroize(h) + ":" + ultZeroize(m) + ":" + ultZeroize(s));
  75. };
  76.  
  77. function ultZeroize(v, l) {
  78. var z = "";
  79. l = l || 2;
  80. v = String(v);
  81. for(var i = 0; i < l - v.length; i++) {
  82. z += "0";
  83. }
  84. return z + v;
  85. };

  

mui 百度语音识别转换文字的更多相关文章

  1. Python 百度语音识别与合成REST API及ffmpeg使用

    操作系统:Windows Python:3.5 欢迎加入学习交流QQ群:657341423 百度语音识别官方文档 百度语音合成官方文档 注意事项:接口支持 POST 和 GET两种方式,个人支持用po ...

  2. 百度语音识别API初探

    近期想做个东西把大段对话转成文字.用语音输入法太慢,所以想到看有没有现成的API,网上一搜,基本就是百度和讯飞. 这里先看百度的 笔者使用的是Java版本号的 下载地址:http://bos.nj.b ...

  3. 基于百度语音识别API的Python语音识别小程序

    一.功能概述 实现语音为文字,可以扩展到多种场景进行工作,这里只实现其基本的语言接收及转换功能. 在语言录入时,根据语言内容的多少与停顿时间,自动截取音频进行转换. 工作示例: 二.软件环境 操作系统 ...

  4. python +百度语音识别+图灵对话

    https://github.com/Dongvdong/python_Smartvoice 上电后,只要周围声音超过 2000,开始录音5S 录音上传百度识别,并返回结果文字输出 继续等待,周围声音 ...

  5. 百度语音识别vs科大讯飞语音识别

    一.结果 从笔者试验的结果来看,科大讯飞的语音识别技术远超百度语音识别 二.横向对比   科大讯飞语音识别 百度语音识别 费用 各功能的前5小时免费 全程免费 转换精准率 非常高 比较低 linux ...

  6. 百度语音识别REST API——通过使用Http网络请求方式获得语音识别功能

    百度语音识别通过REST API的方式给开发人员提供一个通用的HTTP接口,基于该接口,开发人员能够轻松的获取语音识别能力,本文档描写叙述了使用语音识别服务REST API的方法. 长处: 较之开发人 ...

  7. 一篇文章搞定百度OCR图片文字识别API

    一篇文章搞定百度OCR图片文字识别API https://www.jianshu.com/p/7905d3b12104

  8. python调用百度语音识别接口实时识别

    1.本文直接上干货 奉献代码:https://github.com/wuzaipei/audio_discern/tree/master/%E8%AF%AD%E9%9F%B3%E8%AF%86%E5% ...

  9. python录音并调用百度语音识别接口

    #!/usr/bin/env python import requests import json import base64 import pyaudio import wave import os ...

随机推荐

  1. C# 读取Excel,一波华丽的操作

    C# 读取Excel,其实有很多方法.但是今天要来一波华丽的操作. 先看效果: 以上这波操作使用了 ExcelDataReader 和 ExcelDataReader.DataSet 完成的. Exc ...

  2. C#winfrom最简DBHelp(数据库连接操作)

    代码如下: //需引用命名空间 using System.Data; using System.Data.SqlClient; class DBHelper { //定义数据库连接语句,连接语句书写方 ...

  3. HTML5 canvas 学习

    一.canvas简介 ​ <canvas> 是 HTML5 新增的,一个可以使用脚本(通常为JavaScript)在其中绘制图像的 HTML 元素.它可以用来制作照片集或者制作简单(也不是 ...

  4. 关于EF中使用Migrations的一些小提示

    在运行正常的情况下,EF的数据迁移功能非常强大.但是当它出现状况时,试图找到问题发生的原因时通常都很让人郁闷(没法调试,提示信息很模糊等等原因).我花了很多时间来确保在我的迁移能工作正常,然后我整理了 ...

  5. “全栈2019”Java多线程第二十七章:Lock获取lock/释放unlock锁

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. 前端ajax传数据成功发送,但后端接收不到

    前几天遇到这样的问题,找了好久,是在ajax     contentType属性设置的问题. contentType默认是application/x-www-form-urlencoded    但是 ...

  7. [JavaScript] 获取数组中相同元素的个数

    /** * 获取数组中相同元素的个数 * @param val 相同的元素 * @param arr 传入数组 */ function getSameNum(val,arr){ processArr ...

  8. Memcached 查看列出所有key方法

    Memcached没有一个比较简单的方法可以直接象Redis那样keys *列出所有的Session key,并根据key get对应的session内容,但是还是可以查看的 memcached 查看 ...

  9. 如何让IE 低版本下支持 css3属性

    依赖源  该文件为  ie-css3.htc    (特别提示.htc为二进制文件,只会在ie中识别,让IE浏览器支持CSS3的一些属性) 以下为依赖文件源码 通过源码我们可以看到 该文件在一定程度上 ...

  10. Vim编辑器与shell脚本

      目录                                                          Vim文本编辑器 Shell脚本 Shell编程变量 流程控制语句 计划任务 ...