因為項目中有需要把微信里的語音轉(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ā)完成捺弦。 比較效果使用饮寞。