玩轉百度語音識別,就是這么簡單


  明后兩天就是公司一年一度的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('\r');
        }
        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的微信公眾號,我會將我的文章推送給您,並和您一起分享我日常閱讀過的優質文章。

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM