前言

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

百度语音

  

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

1.获取Access Token

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

1.获取Access Token

1.1.申请百度开发账号

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

   <!--百度人工智能平台访问配置-->
    <add key=" />
    <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";
    }

利用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;
    };

  

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. day65 Django模板语言

      常用语法 只需要记两种特殊符号: {{  }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 变量 {{ 变量名 }} 变量名由字母数字和下划线组成. 点(.)在模板语言中有特殊的含 ...

  2. Django(app的概念、ORM介绍及编码错误问题)

    day61 Django中的APP:         什么是APP?以及为什么要用APP?                  project  --> 项目  (老男孩教育大学校)        ...

  3. Spring JdbcTemplate源码阅读报告

    写在前面 spring一直以删繁就简为主旨,所以设计出非常流行的bean管理模式,简化了开发中的Bean的管理,少写了很多重复代码.而JdbcTemplate的设计更令人赞叹,轻量级,可做ORM也可如 ...

  4. Swift 里字符串(三)small String

     small string, 只有两个 UInt64 的字,这里面存储了所有的信息. 内存布局如下:  第二个 UInt64 存储了标记位和长度信息,以及部分字符串的值 // Get an int ...

  5. Python小白学习之路(二)—【Pycharm安装与配置】【创建项目】【运算符】【数据类型】

    写在前面: 第二天的学习,感觉比昨天学习相对轻松一些,但是对于我这个编程语言功底很弱的人来说,还是稍稍微有些.....哈尔滨的天气一天天冷了下来,还飘着小雨,不过还是挺有意境的.充实而又忙碌的生活,让 ...

  6. 下载一个vue项目执行npm install 后运行项目npm run dev后出错 - 问题解决

    在SVN上拉下来一个vue项目,上面没有提交项目里面的node_modules文件夹,所以要自己执行 npm install 安装,但安装完后运行项目后却报错了: $ npm run dev > ...

  7. leetcode-917-仅仅反转字母

    题目描述: 给定一个字符串 S,返回 “反转后的” 字符串,其中不是字母的字符都保留在原地,而所有字母的位置发生反转. 示例 1: 输入:"ab-cd" 输出:"dc-b ...

  8. 【xsy1201】 随机游走 高斯消元

    题目大意:你有一个$n*m$的网格(有边界),你从$(1,1)$开始随机游走,求走到$(n,m)$的期望步数. 数据范围:$n≤10$,$m≤1000$. 我们令 $f[i][j]$表示从$(1,1) ...

  9. NOIP2017滚粗记【下】

    (续上篇) Day1: 下午,全竞赛队的人都在竞赛室颓~,再次吐槽下我校网管科的,下午普及考试又把竞赛室的网络切掉了,还好我们机制地准别了一堆单机游戏.普及组考完后,网络又恢复正常了,但晚上9点左右又 ...

  10. POJ 1013

    #include"string.h"char left[3][7],right[3][7],result[3][5];bool isHeavy(char x ){    int i ...