python 騰訊/百度/訊飛 ASR 語音轉(zhuǎn)文字

因為項目中有需要把微信里的語音轉(zhuǎn)成文本處理, 本次只說語音轉(zhuǎn)文本。
需要注意的是平臺對語音的格式有要求, 所以我們需要對語音進行轉(zhuǎn)換格式统锤。

語音轉(zhuǎn)換

使用的工具是ffmpeg, ffmpeg的安裝和配置請自行百度配猫。

import os
import tempfile
import subprocess
import base64
import logging
logger = logging.getLogger(__name__)
def mp3_2_wav(_path = None, _byte = None):
    ''' MP3轉(zhuǎn)WAV
    _path和_byte必須存在一個, 優(yōu)先級_path > _byte
    :param _path: 
    :param _byte:  
    :return: wav的字節(jié)流
    '''
    try:
        if _path is None and _byte is None: return
        temp = None
        if _path is None: # 字節(jié)流存入臨時文件
            temp = tempfile.NamedTemporaryFile(mode="w+b", delete=False)
            temp.write(_byte)
            temp.seek(0)
            _path = temp.name
        if _path is None: return
        # 根據(jù)要求進行格式轉(zhuǎn)換,-t 60 最大保存60秒, 采樣率 16K, 默認單聲道
        logger.info('mp3 ==> wav ========================')
        target_file = tempfile.NamedTemporaryFile(mode="w+b", delete=False, suffix='.wav')
        _perfix = r'ffmpeg'
        command = [_perfix, '-y', '-t', '60', '-i', _path, '-ar', '16K', target_file.name]
        return_code = subprocess.call(command)
        logger.info('mp3 ==> wav ==={}====================='.format(return_code))
        if return_code == 0:
            target_file.seek(0)
            _byte = target_file.read()
            target_file.close()
            os.remove(target_file.name)
            if temp is not None:
                temp.close()
                os.remove(temp.name)
            return _byte
    except Exception as e:
        logger.error('mp3_2_wav error [{}]'.format(e))

百度AI開放平臺 API

百度的比較方便幅恋,有百度封裝好的SDK使用和安裝都很方便, 上面API里有詳細介紹。

def BAIDU_ASR(_path):
    ''' 百度語音轉(zhuǎn)文字
    
    :param _path: 
    :return: 
    '''
    from aip import AipSpeech
    """ 你的 APPID AK SK """
    APP_ID = '你的 App ID'
    API_KEY = '你的 Api Key'
    SECRET_KEY = '你的 Secret Key'
    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    result = client.asr(mp3_2_wav(_path), 'pcm', 16000, {
        'dev_pid': '1537',
    })
    return result.get('result')[0]

訊飛開放平臺API

需要把請求的IP在訊飛控制臺加入白名單, 否則報錯:
{"code":"10105","data":"","desc":"illegal access|illegal client_ip: xxx.xxx.xxx.xxx","sid":"....."}
把報錯信息里的xxx.xxx.xxx.xxx加入白名單即可

import json
import time
import requests
def XUNFEI_ASR(_path):
    ''' 訊飛語音轉(zhuǎn)文字
    
    :param _path: 
    :return: 
    '''
    _byte = mp3_2_wav(_path)
    base64_audio = base64.b64encode(_byte)
    import urllib.parse
    body = urllib.parse.urlencode({'audio': base64_audio})
    url = 'http://api.xfyun.cn/v1/service/v1/iat'
    APP_ID = '你的 App ID'
    API_KEY = '你的 Api Key'
    param = {"engine_type": "sms16k", "aue": "raw"}
    import hashlib
    x_param = base64.b64encode(json.dumps(param).replace(' ', '').encode('utf-8'))
    x_time = int(int(round(time.time() * 1000)) / 1000)
    _str = API_KEY + str(x_time) + x_param.decode('utf-8')
    x_checksum = hashlib.md5(_str.encode('utf-8')).hexdigest()
    x_header = {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8',
                'X-Appid': APP_ID,
                'X-CurTime': str(x_time),
                'X-Param': x_param,
                'X-CheckSum': x_checksum}
    res = requests.post(url, body, headers = x_header)
    res = res.content.decode('utf-8')
    return res

騰訊AI開放平臺API

騰訊平臺主要是簽名算法需要注意

簽名算法

def get_sign_code(params, app_key):
    ''' 生成簽名CODE
    
    1. 計算步驟
    用于計算簽名的參數(shù)在不同接口之間會有差異泵肄,但算法過程固定如下4個步驟佳遣。
    將<key, value>請求參數(shù)對按key進行字典升序排序,得到有序的參數(shù)對列表N
    將列表N中的參數(shù)對按URL鍵值對的格式拼接成字符串凡伊,得到字符串T(如:key1=value1&key2=value2),URL鍵值拼接過程value部分需要URL編碼窒舟,URL編碼算法用大寫字母系忙,例如%E8,而不是小寫%e8
    將應用密鑰以app_key為鍵名惠豺,組成URL鍵值拼接到字符串T末尾银还,得到字符串S(如:key1=value1&key2=value2&app_key=密鑰)
    對字符串S進行MD5運算风宁,將得到的MD5值所有字符轉(zhuǎn)換成大寫,得到接口請求簽名
    2. 注意事項
    不同接口要求的參數(shù)對不一樣蛹疯,計算簽名使用的參數(shù)對也不一樣
    參數(shù)名區(qū)分大小寫戒财,參數(shù)值為空不參與簽名
    URL鍵值拼接過程value部分需要URL編碼
    簽名有效期5分鐘,需要請求接口時刻實時計算簽名信息
    :param params: 參數(shù)字典
    :param app_key: 
    :return: 
    '''
    if params is None or type(params) != dict or len(params) == 0: return
    try:
        params = sorted(params.items(), key=lambda x:x[0])
        _str = ''
        for item in params:
            key = item[0]
            value = item[1]
            if value == '': continue
            _str += urllib.parse.urlencode({key: value}) + '&'
        _str += 'app_key=' + app_key
        _str = hashlib.md5(_str.encode('utf-8')).hexdigest()
        return _str.upper()
    except Exception as e:
        logger.error('tencen get_sign_code error [{}]'.format(e))

ASR

def TencenASR(_path):
    ''' 騰訊語音轉(zhuǎn)文字
    
    :param _path: 
    :return: 
    '''
    APP_ID = '你的 App ID'
    API_KEY = '你的 Api Key'
    _byte = mp3_2_wav(_path)
    base64_audio = base64.b64encode(_byte)
    url = 'https://api.ai.qq.com/fcgi-bin/aai/aai_asr'
    params = {'app_id': APP_ID, 'time_stamp':int(time.time()), 'nonce_str': 'fa577ce340859f9fe', 'format': 2, 'speech': base64_audio, 'rate': 16000}
    sign = get_sign_code(params, API_KEY)
    params['sign'] = sign
    rt = requests.post(url, data=params)
    jsonData = json.loads(rt.text)
    if jsonData.get('ret') == 0:
        rt = jsonData.get('data').get('text')
        logger.info('Tencen ==> wav ===> {}'.format(rt))
        return rt

至此關鍵代碼開發(fā)完成捺弦。 比較效果使用饮寞。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市列吼,隨后出現(xiàn)的幾起案子幽崩,更是在濱河造成了極大的恐慌,老刑警劉巖寞钥,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慌申,死亡現(xiàn)場離奇詭異,居然都是意外死亡理郑,警方通過查閱死者的電腦和手機蹄溉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來您炉,“玉大人柒爵,你說我怎么就攤上這事×诳裕” “怎么了餐弱?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長囱晴。 經(jīng)常有香客問我膏蚓,道長,這世上最難降的妖魔是什么畸写? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任驮瞧,我火速辦了婚禮,結(jié)果婚禮上枯芬,老公的妹妹穿的比我還像新娘论笔。我一直安慰自己,他們只是感情好千所,可當我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布狂魔。 她就那樣靜靜地躺著,像睡著了一般淫痰。 火紅的嫁衣襯著肌膚如雪最楷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音籽孙,去河邊找鬼烈评。 笑死,一個胖子當著我的面吹牛犯建,可吹牛的內(nèi)容都是我干的讲冠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼适瓦,長吁一口氣:“原來是場噩夢啊……” “哼竿开!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起犹菇,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤德迹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后揭芍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胳搞,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年称杨,在試婚紗的時候發(fā)現(xiàn)自己被綠了肌毅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡姑原,死狀恐怖悬而,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情锭汛,我是刑警寧澤笨奠,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站唤殴,受9級特大地震影響般婆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜朵逝,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一蔚袍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧配名,春花似錦啤咽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至芋膘,卻和暖如春没陡,著一層夾襖步出監(jiān)牢的瞬間涩哟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工盼玄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人潜腻。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓埃儿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親融涣。 傳聞我的和親對象是個殘疾皇子童番,可洞房花燭夜當晚...
    茶點故事閱讀 43,490評論 2 348