玩转百度语音识别,就是这么简单

  明后两天就是公司一年一度的Fedex Day了。我的理解就是技术界的头脑风暴,idea喷如泉涌的盛大节日。

  对于这次活动每个人或者两三个人一组需要有个idea,针对当前的产品现状,提出自己的改进或者丰富产品的想法,我拿出自己的手机并登了经常去的网站,语音识别这个名词脱颖而出,击中我的脑海。相比较以前手指时代的手工输入,各种在中英文乃至数字之间进行切换,往往还会因为走神或者手抖导致输入出错,然后又是一通狂按删除键,一遍一遍的输入,面对偌大的屏幕,有种使不上劲的感觉。语音输入就可以告别这一烦恼,如今的语音识别准确率高,使用简单易操作,更是为解放双手铺平了道路。你可以对着siri说帮我查看最近的天气或者定个闹铃,你可以使用讯飞语音输入法,说到哪就输入到哪,你可以让各种品牌的手机自带的语音助手给你讲个笑话……

  今天闲来想先动动手,了解下这个语音识别技术,有什么好用的api可以调用。因为用的是度娘,所以映入眼帘的就是百度语音,"永久免费智能语音开放平台"的旗号还是深深的把我打动了。

  摸索下来,看了两种方式,一是基于REST API的方式完成语音识别,另一个是基于移动端Android平台的app语音识别。

一 、获得入场券

1.注册成为开发者

  点击进入http://yuyin.baidu.com/,用你的百度账号完成登录,如果在点击“应用管理”选项卡后发现如下图所示

  说明你需要完成注册验证,提交完毕后,你就是一名百度开发者用户了。

2.创建应用

  完成上面操作后,点击“应用管理”,如果页面中没有任何应用列表,说明你还需要添加一个应用,点击页面右上角“创建新应用”,填好应用类别并给他个名字,这样就完成了应用创建。创建成功后就会看到类似下面这样的效果。

  在“查看Key”中,我们可以看到后面我们需要用到的App ID, API Key和Secret Key

3.开通服务

  创建了应用后,我们需要开通语音识别的服务之后才能使用语音识别。点击应用卡片上的“开通服务”,选择语音识别即可。

  至此,您已经获得了入场券资格。

二、 基于REST API 的语音识别

  百度语音支持android、ios和REST API三种平台。这里先介绍REST API,相对来说不用搭建android或者ios开发环境。

  进入http://yuyin.baidu.com/asr/download下载REST API的示例和文档。

  示例分别有java、linux c和php版本,还附带了一个test.pcm的音频文件。

  选择java版本,导入eclipse中,代码很简单就一个测试类。

package com.baidu.speech.serviceapi;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.xml.bind.DatatypeConverter;

import org.json.JSONObject;

public class Sample {

    private static final String serverURL = "http://vop.baidu.com/server_api";
    private static String token = "";
    private static final String testFileName = "C:\Users\Administrator\workspace\speechrecognition\src\test.pcm";
    //put your own params here
    private static final String apiKey = "***";//这里的apiKey就是前面申请在应用卡片中的apiKey
    private static final String secretKey = "***";//这里的secretKey就是前面申请在应用卡片中的secretKey
    private static final String cuid = "***";//cuid是设备的唯一标示,因为我用的是PC,所以这里用的是网卡Mac地址

    public static void main(String[] args) throws Exception {
        getToken();
        method1();
        method2();
    }

    private static void getToken() throws Exception {
        String getTokenURL = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials" + 
            "&client_id=" + apiKey + "&client_secret=" + secretKey;
        HttpURLConnection conn = (HttpURLConnection) new URL(getTokenURL).openConnection();
        token = new JSONObject(printResponse(conn)).getString("access_token");
    }

    private static void method1() throws Exception {
        File pcmFile = new File(testFileName);
        HttpURLConnection conn = (HttpURLConnection) new URL(serverURL).openConnection();

        // construct params
        JSONObject params = new JSONObject();
        params.put("format", "pcm");
        params.put("rate", 8000);
        params.put("channel", "1");
        params.put("token", token);
        params.put("cuid", cuid);
        params.put("len", pcmFile.length());
        params.put("speech", DatatypeConverter.printBase64Binary(loadFile(pcmFile)));

        // add request header
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");

        conn.setDoInput(true);
        conn.setDoOutput(true);

        // send request
        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.writeBytes(params.toString());
        wr.flush();
        wr.close();

        printResponse(conn);
    }

    private static void method2() throws Exception {
        File pcmFile = new File(testFileName);
        HttpURLConnection conn = (HttpURLConnection) new URL(serverURL
                + "?cuid=" + cuid + "&token=" + token).openConnection();

        // add request header
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "audio/pcm; rate=8000");

        conn.setDoInput(true);
        conn.setDoOutput(true);

        // send request
        DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
        wr.write(loadFile(pcmFile));
        wr.flush();
        wr.close();

        printResponse(conn);
    }

    private static String printResponse(HttpURLConnection conn) throws Exception {
        if (conn.getResponseCode() != 200) {
            // request error
            return "";
        }
        InputStream is = conn.getInputStream();
        BufferedReader rd = new BufferedReader(new InputStreamReader(is));
        String line;
        StringBuffer response = new StringBuffer();
        while ((line = rd.readLine()) != null) {
            response.append(line);
            response.append('
');
        }
        rd.close();
        System.out.println(new JSONObject(response.toString()).toString(4));
        return response.toString();
    }

    private static byte[] loadFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);

        long length = file.length();
        byte[] bytes = new byte[(int) length];

        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
                && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }

        if (offset < bytes.length) {
            is.close();
            throw new IOException("Could not completely read file " + file.getName());
        }

        is.close();
        return bytes;
    }
}

  

  整个类运行和普通的类运行完全没两样,得到的控制台的信息如下:

{
    "access_token": "***66a6adc3bb14***99.2592000.1462845194.282335-7***",
    "refresh_token": "25.344b6***6a9748d8b25a***360000.1775613194.282335-7***",
    "scope": "public audio_voice_assistant_get wise_adapt lebo_resource_base lightservice_public hetu_basic lightcms_map_poi kaidian_kaidian",
    "session_key": "9mzdC***7BvKTa4HuiEVYXrXOUPY***RSS8h4936rRxxd***V4PMq1Y+6OVKac+18rRxRtsT",
    "session_secret": "*352***e9a7a664ef***775e",
    "expires_in": 2592000
}
{
    "result": ["百度语音提供技术支持,"],
    "err_msg": "success.",
    "sn": "160625465371460253194",
    "corpus_no": "6271739712934435529",
    "err_no": 0
}
{
    "result": ["百度语音提供技术支持,"],
    "err_msg": "success.",
    "sn": "613862746801460253195",
    "corpus_no": "6271739717258680030",
    "err_no": 0
}

  从结果看出,装在test.pcm的那段语音内容就是“百度语音提供技术支持”。于是,我也利用windows自带的录音机功能,录制了一段wav格式的语音,一开始报错3301,查看文档说是识别错误,打开音频文件,发现没有录入任何东西,于是重新录入进行识别,虽然没有报错,但是识别的并非语音内容,估计是噪音太大。

三、基于Android平台的语音识别

  显然,光是REST API模式还是玩的不过瘾,想着在来试试移动端的效果如何,移动平台有android和ios,考虑到自己本子的情况,还是选择了android,当然,这两者都不熟悉。

  网上找了一个可以直接使用的android环境http://blog.sina.com.cn/s/blog_6de000c20101rpva.html#cmt_2623882,下载了一通eclipse、sdk和adt等等,凭着之前搭建过一次android平台的记忆,勉强把环境弄好了。

  于是还是如REST API中一样需要下载android的sdk和文档。SDK目录包含以下内容:

  各个模块的功能如下:


  导入demo项目到eclipse中,配置好virtual device,就可以启动虚拟机(我在实际操作过程中,发现将libbdEASRAndroid.so和libBDVoiceRecognitionClient_MFE_V1.so导入classpath时会报错,于是我删除了这两个包),运行起来的效果如下:

  点击下面工具栏的中间按钮,进入全部应用,可以找到应用“Speech Recorder”:

  点击进入应用:

目前在点击“Record”,应用会闪退,还没摸清是什么原因,后面在研究下(有遇到过的欢迎留言指教)~~~

总得来说,百度语音还是蛮好上手的,文档也比较详细,但是就个人录制的音频识别来说,效果还有待提高(可能是音频文件噪音过大)。

先混个脸熟,了解下支持的平台,api的调用方式,后面两天趁Fedex Day好好看看这块。

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

  

 

原文地址:https://www.cnblogs.com/bigdataZJ/p/SpeechRecognition.html