版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
最近业务需求要调用腾讯的语音识别接口来识别音频全部转为文字。比较熟悉Python。所以用Python来做。
中间有些坑:
- HMAC-SHA1 算法 在python中定义的函数顺序跟其他语言不太一样,容易在加密时,出错
- 生成的签名只有在get请求放在url中时,才需要urlencoding。post放在heards中不需要编码。
- 时间戳要取整
- 请求的服务已经开通了。
- 会debug比啥都强
源代码我放在了github地址:https://github.com/1414044032/TengXun-jianquan
CSDN地址:https://download.csdn.net/download/wangliuqi123/10450756
回调方法地址:https://blog.csdn.net/wangliuqi123/article/details/80537635
腾讯的接口API 还是比较好用的,写的详细,跟着文档写基本没啥毛病,就是比较复杂(不复杂怎么保证安全)
离线语音识别也是基于Restful的。腾讯提供了两套方法:
这里,第二种基于第一种。我只写一下第一种:
第一种基本上就是 接口鉴权+request请求:
写的时候时间也基本花在鉴权上:
首先需要获取到你帐号的详细信息:
app_id,Secretid,SecretKey。:在路径 控制台==》访问管理==》云API密钥中查看。
获取项目id:
项目ID,我这里实用的默认项目也就是0.
接下来就是敲代码了。
鉴权的思路就是本地根据规则生成的签名
在你访问资源时,要传送生成的签名,服务器会进行比对校验。相同则通过。
用到的方法:
主要用三个:一个生成随机整数串,一个对dict进行字典顺序排序,还有就是加密算法。
# 生成随机整数串
def getrandom(length):
nonce=''
for i in range(length):
number = random.randint(1,9)
nonce = nonce+str(number)
return int(nonce)
# 字典排序算法
def sordict(dict):
after=sorted(zip(dict.keys(),dict.values()))
return after
# 算法参考地址
# http://outofmemory.cn/code-snippet/33173/python-hmac-sha1
def encrypt(signature1, secretkey):
signature = bytes(signature1,encoding='utf-8')
secretkey = bytes(secretkey,encoding='utf-8')
# 这里python跟其他语言的写法不太一样。密钥在第一位,第二位才是要加密的。而且是bytes类型加密
my_sign = hmac.new(secretkey,signature, hashlib.sha1).digest()
my_sign = base64.b64encode(my_sign)
return my_sign
之后生成签名:
# 官方文档地址:
# https://cloud.tencent.com/document/product/441/17366
# https://cloud.tencent.com/document/product/441/6201
def keygen(app_id, secretid, secretkey, projectid =0, engine_model_type="16k_0",
callback_url="接受结果的回调url", res_text_format=0, source_type=1 ):
"""
:param app_id: 在控制台“云API密钥”获得
:param secretid: 在控制台“云API密钥”获得
:param secretkey: 在控制台“云API密钥”获得
:param projectid: 项目id, 默认0为默认项目
:param engine_model_type: 采样率
:param callback_url: 回调url
:param res_text_format:
:param source_type:
:return: 加密后的签名,appid
"""
timestamp = int(time.time()) # 当前时间的时间戳
expired= timestamp +10000 # 签名有效期
nonce = getrandom(6) # 随机正整数。用户需自行生成,最长 10 位
app_id= app_id# 1256603936
projectid =0
secretkey = secretkey
secretid = secretid
keydict ={
"projectid": projectid,
"sub_service_type": 0,
"engine_model_type": engine_model_type,
# 语音 URL,公网可下载。当 source_type 值为 0 时须填写该字段,为 1 时不填;URL 的长度大于 0,小于 2048
# "url": "http://test.qq.com/rec_callback",
"res_text_format": 0,
"res_type": 1,
"callback_url": "http://qa6iyt.natappfree.cc/test",
"source_type": source_type,
"secretid": secretid,
"timestamp": timestamp,
"expired": expired,
"nonce": nonce,
}
# 字典排序后的字典
sortkeydict = sordict(keydict)
# 签名字符串拼接
afterstr=''
for i in sortkeydict:
afterstr=afterstr+str(i[0])+'='+str(i[1])+'&'
keystr = 'POSTaai.qcloud.com/asr/v1/'+str(app_id)+'?'
signature1=(keystr+afterstr[:-1])
print('拼接后的字符串', signature1)
# 加密处理后,得到签名字符串
# 签名字符可以保存,下次直接使用。
signature_str = encrypt(signature1, secretkey)
# 返回签名
return str(signature_str),app_id,
签名生成后,直接访问语音识别的接口:
def request2getjob_id(signature_str, app_id, filepath, sortkeydict):
"""
:param signature_str: j加密后的签名
:param app_id: appid ,在控制台“云API密钥”获得
:param filepath: 本地音频文件路径
:param sortkeydict: 访问语音API需要的参数列表,已经过字典排序
:return: job_id 任务id,用于获取语音结果。
"""
print('签名字符',urllib.parse.quote(signature_str))
body = ''
with open(filepath, 'rb') as f:
body = f.read()
header={
"Host": "aai.qcloud.com",
"Content-Type": "application/octet-stream",
"Authorization": signature_str,
"Content-Length": str(len(body)),
}
url="http://aai.qcloud.com/asr/v1/"+str(app_id)+'?'+ urllib.parse.urlencode(sortkeydict)
print(url)
response=requests.post(url, data=body, headers=header)
if response.status_code == 200 :
print("上传识别音频文件成功")
result=eval(str(response.content))
# 任务ID
job_id=result.get("requestid")
return job_id
else:
print("失败")
# 根据返回的code去腾讯的文档中心来查看是哪一步出错了
# https://cloud.tencent.com/document/product/441/6201
print(response.content)
return 0
return 0
最后访问结果如图:SUCCESS