前言

  用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. .NET Entity Framework (with Oracle ODP.NET)

    一.前言 1.Entity Framework是什么? Entity Framework是微软对ORM框架的实现.类似的实现也有其它方式,如DevExpress 的XPO(eXpress Persis ...

  2. VisualStudio、NETFramework及C#版本关系

    1.Visual Studio..NET Framework 及C#版本搭载关系介绍 Visual Studio版本 .NET Framework版本 C#版本 增加功能 Visual Studio ...

  3. ASP.net MVC4/MVC5 错误处理及设置

    很无聊的记录下.首先IIS 7以上的版本测试才成功 首先 //全局ErrorHandler public static void RegisterGlobalFilters(GlobalFilterC ...

  4. Zimbra无需登录RCE漏洞利用

    2019年3月13号,一名国外的安全研究员在他的博客上公布了zimbra RCE漏洞相关信息,但其中并未提到一些漏洞利用细节. 经过一段时间努力,根据网上各位大牛的分析和我自己的理解,在此我将整个漏洞 ...

  5. FFMpeg的一些基础配置

    一 . CMakeLists.txt文件的使用 1.添加头文件的相对路径 : include_directories(include(这里面就是文件的名字)) 2.设置ffmpeg的库的路径(v7a或 ...

  6. kubernetes traefik multiple namespaces

    官方文档在此 https://docs.traefik.io/user-guide/kubernetes/ 官方文档在配置 RBAC 时使用了 ClusterRoleBinding, 当你想用多命名空 ...

  7. [bug] JS sort 函数在 ios 中无效

    首先,请原谅我做一次标题党: 但我觉得从发现问题到最后解决问题的过程还是蛮有意思的,特此记录一下: 背景 近两天开发的航班延误宝是内嵌在客户端(android.ios)webview 中的 H5 页面 ...

  8. [Swift实际操作]七、常见概念-(6)日期Date和DateFormatter日期的格式化

    本文将为你演示日期类型的使用,以及如何对日期进行格式化. 首先引入需要使用到的界面框架 import UIKit 初始化一个日期对象,它的值和当前电脑中的日期相同 var date = Date() ...

  9. php-fpm定时器

    php-fpm有三种定时器 1)主进程接收到用户的信号,例如sigusr,主进程执行kill(子进程号,sigquit),的同时,设置定时器,在一个无限循环里如果当前时间 大于或等于 该定时器的过期时 ...

  10. centos7 防火墙与端口设置、linux端口范围

    防火墙 启动防火墙: systemctl start firewalld 查看防火墙状态: systemctl status firewalld 关闭防火墙: systemctl stop firew ...