【AIGC】使用Python实现科大讯飞语音服务ASR转录功能:完整指南

文章目录

  • 讯飞ASR转写API完整指南
    • [1. 引言](#1. 引言)
    • [2. 讯飞ASR API介绍](#2. 讯飞ASR API介绍)
    • [3. API参数说明](#3. API参数说明)
      • [3.1 认证参数](#3.1 认证参数)
      • [3.2 上传参数](#3.2 上传参数)
      • [3.3 查询结果参数](#3.3 查询结果参数)
      • [3.4 orderResult 字段](#3.4 orderResult 字段)
      • [3.5 Lattice 字段](#3.5 Lattice 字段)
      • [3.6 json_1best 字段](#3.6 json_1best 字段)
      • [3.7 st 字段](#3.7 st 字段)
    • [4. Python代码实现](#4. Python代码实现)
      • [4.1 生成签名](#4.1 生成签名)
      • [4.2 上传音频文件](#4.2 上传音频文件)
      • [4.3 获取转写结果](#4.3 获取转写结果)
      • [4.4 解析转写结果](#4.4 解析转写结果)
    • [5. 请求与返回示例](#5. 请求与返回示例)
      • [5.1 成功返回示例](#5.1 成功返回示例)
      • [5.4 异步回调](#5.4 异步回调)
        • [1. 转写结束异步回调状态](#1. 转写结束异步回调状态)
    • [6. 文档地址](#6. 文档地址)
    • [7. 结论](#7. 结论)

讯飞ASR转写API完整指南

1. 引言

在这篇博客中,我们将详细解析如何使用讯飞ASR(自动语音识别)API进行音频转写,包括上传音频、查询转写结果及解析返回数据。本文将涵盖API的参数说明,并提供完整的Python代码,确保代码能够顺利执行。

2. 讯飞ASR API介绍

讯飞ASR API提供了一整套音频转写的解决方案,主要流程如下:

  1. 生成签名 - 认证请求的合法性。
  2. 上传音频 - 通过URL方式或本地文件上传音频。
  3. 查询结果 - 轮询转写结果,等待识别完成。
  4. 解析结果 - 处理返回的JSON数据,提取文本和说话人信息。

3. API参数说明

3.1 认证参数

参数名 说明
appId 讯飞开发者平台分配的应用ID
secret_key 用于生成签名的密钥
ts 时间戳,单位为秒
signa 认证签名,由appId、ts和secret_key计算得出

3.2 上传参数

参数名 说明
fileName 音频文件名称
fileSize 文件大小(若使用URL方式可随意填写)
duration 音频时长(单位秒,可随机填写)
language 语言(cn代表中文)
audioMode 上传模式(urlLink 代表通过URL上传)
audioUrl 音频文件的URL(需要URL编码)


3.3 查询结果参数

参数名 说明
orderId 订单ID,用于查询转写结果
resultType 返回结果类型(transfer 表示最终转写文本)

成功

bash 复制代码
{
 "code": "000000",
 "descInfo": "success",
 "content": {
  "orderId": "DKHJQ202209021522090215490FAAE7DD0008C",
  "taskEstimateTime": 28000
 }
}

失败

bash 复制代码
{
 "code": "26600",
 "descInfo": "转写业务通用错误"
}

3.4 orderResult 字段

参数名 类型 说明
lattice List 做顺滑功能的识别结果
lattice2 List 未做顺滑功能的识别结果,当开启顺滑和后语规整后 orderResult 才返回 lattice2 字段(需要开通权限)
label Object 转写结果标签信息,用于补充转写结果相关信息,标记转写结果角色和声道的对应关系

3.5 Lattice 字段

参数名 类型 说明
json_1best String 单个 VAD 的结果的 JSON 内容

3.6 json_1best 字段

参数名 类型 说明
st Object 单个句子的结果对象

3.7 st 字段

参数名 类型 说明
bg String 单个句子的开始时间,单位毫秒
ed String 单个句子的结束时间,单位毫秒
rl String 分离的角色编号,取值正整数,需开启角色分离的功能才返回对应的分离角色编号
rt List 输出词语识别结果集合

4. Python代码实现

4.1 生成签名

bash 复制代码
def generate_signa(self):
    """
    生成签名
    :return: 签名字符串
    """
    appid = self.appid
    ts = self.ts
    base_string = appid + ts
    
    md5 = hashlib.md5()
    md5.update(base_string.encode('utf-8'))
    base_string_md5 = md5.hexdigest()
    
    key = self.secret_key.encode('utf-8')
    message = base_string_md5.encode('utf-8')
    hmac_obj = hmac.new(key, message, hashlib.sha1)
    signa = base64.b64encode(hmac_obj.digest()).decode('utf-8')
    
    return signa

4.2 上传音频文件

1、文件上传

#概述

首先调用文件上传接口,上传待转写音频文件的基本信息(文件名、大小等)和相关的可配置参数。

调用成功,返回订单ID(orderId,用于查询结果或者联调排查问题时使用),是后续接口的必传参数。

#请求示例

bash 复制代码
https://raasr.xfyun.cn/v2/api/upload?duration=200&signa=Je5YsBvPcsbB4qy8Qvzd367fiv0%3D&fileName=%E9%98%B3%E5%85%89%E6%80%BB%E5%9C%A8%E9%A3%8E%E9%9B%A8%E5%90%8E.speex-wb&fileSize=11895&sysDicts=uncivilizedLanguage&appId=3e79d91c&ts=1662101767

#URL

bash 复制代码
 POST https: //raasr.xfyun.cn/v2/api/upload

#请求头

复制代码
Content-Type: application/json; charset=UTF-8,Chunked: false

#signa生成

bash 复制代码
def upload(self):
    """
    上传音频文件
    :return: 上传响应结果
    """
    try:
        file_name = os.path.basename(urllib.parse.unquote(self.audio_url))
        param_dict = {
            "appId": self.appid,
            "signa": self.signa,
            "ts": self.ts,
            "fileName": file_name,
            "fileSize": "10000",
            "duration": "200",
            "language": "cn",
            "audioMode": "urlLink",
            "audioUrl": urllib.parse.quote(self.audio_url, safe='')
        }
        url = lfasr_host + api_upload + "?" + urllib.parse.urlencode(param_dict)
        response = requests.post(url, headers={"Content-Type": "application/json; charset=UTF-8"})
        result = json.loads(response.text)
        
        if str(result.get('code', '')) != '000000':
            return None
        
        return result
    except Exception as e:
        return None

4.3 获取转写结果

status == 4

bash 复制代码
def get_result(self):
    """
    获取转写结果
    :return: 转写结果
    """
    uploadresp = self.upload()
    if not uploadresp:
        return None
    
    try:
        orderId = uploadresp['content']['orderId']
        param_dict = {
            "appId": self.appid,
            "signa": self.signa,
            "ts": self.ts,
            "orderId": orderId,
            'roleType':1,
            'roleNum':2,
            "resultType": "transfer"
        }
        
        url = lfasr_host + api_get_result + "?" + urllib.parse.urlencode(param_dict)
        status = 3
        while status == 3:
            response = requests.post(url, headers={"Content-Type": "application/json; charset=UTF-8"})
            result = json.loads(response.text)
            
            if str(result.get('code', '')) != '000000':
                continue
                
            status = result['content']['orderInfo']['status']
            if status == 4:
                return result
            time.sleep(5)
        
        return None
    except Exception as e:
        return None

查询结构返回数据

bash 复制代码
{
 "code": "000000",
 "descInfo": "success",
 "content": {
  "orderInfo": {
   "orderId": "DKHJQ2022090510220905100562536FEF00062",
   "failType": 0,
   "status": 4,
   "originalDuration": 200,
   "realDuration": 1878
  },
  "orderResult": "{\"lattice\":[{\"json_1best\":\"{\\\"st\\\":{\\\"sc\\\":\\\"0.86\\\",\\\"pa\\\":\\\"0\\\",\\\"rt\\\":[{\\\"ws\\\":[{\\\"cw\\\":[{\\\"w\\\":\\\"这\\\",\\\"wp\\\":\\\"n\\\",\\\"wc\\\":\\\"1.0000\\\"}],\\\"wb\\\":1,\\\"we\\\":16},{\\\"cw\\\":[{\\\"w\\\":\\\"是\\\",\\\"wp\\\":\\\"n\\\",\\\"wc\\\":\\\"1.0000\\\"}],\\\"wb\\\":17,\\\"we\\\":36},{\\\"cw\\\":[{\\\"w\\\":\\\"一\\\",\\\"wp\\\":\\\"n\\\",\\\"wc\\\":\\\"1.0000\\\"}],\\\"wb\\\":37,\\\"we\\\":52},{\\\"cw\\\":[{\\\"w\\\":\\\"条\\\",\\\"wp\\\":\\\"n\\\",\\\"wc\\\":\\\"1.0000\\\"}],\\\"wb\\\":53,\\\"we\\\":80},{\\\"cw\\\":[{\\\"w\\\":\\\"测试\\\",\\\"wp\\\":\\\"n\\\",\\\"wc\\\":\\\"1.0000\\\"}],\\\"wb\\\":81,\\\"we\\\":116},{\\\"cw\\\":[{\\\"w\\\":\\\"音频\\\",\\\"wp\\\":\\\"n\\\",\\\"wc\\\":\\\"1.0000\\\"}],\\\"wb\\\":117,\\\"we\\\":172},{\\\"cw\\\":[{\\\"w\\\":\\\"。\\\",\\\"wp\\\":\\\"p\\\",\\\"wc\\\":\\\"0.0000\\\"}],\\\"wb\\\":172,\\\"we\\\":172},{\\\"cw\\\":[{\\\"w\\\":\\\"\\\",\\\"wp\\\":\\\"g\\\",\\\"wc\\\":\\\"0.0000\\\"}],\\\"wb\\\":172,\\\"we\\\":172}]}],\\\"bg\\\":\\\"50\\\",\\\"rl\\\":\\\"0\\\",\\\"ed\\\":\\\"1840\\\"}}\"}],\"lattice2\":[{\"lid\":\"0\",\"end\":\"1840\",\"begin\":\"50\",\"json_1best\":{\"st\":{\"sc\":\"0.86\",\"pa\":\"0\",\"rt\":[{\"nb\":\"1\",\"nc\":\"1.0\",\"ws\":[{\"cw\":[{\"w\":\"这\",\"wp\":\"n\",\"wc\":\"1.0000\"}],\"wb\":1,\"we\":16},{\"cw\":[{\"w\":\"是\",\"wp\":\"n\",\"wc\":\"1.0000\"}],\"wb\":17,\"we\":36},{\"cw\":[{\"w\":\"一\",\"wp\":\"n\",\"wc\":\"1.0000\"}],\"wb\":37,\"we\":52},{\"cw\":[{\"w\":\"条\",\"wp\":\"n\",\"wc\":\"1.0000\"}],\"wb\":53,\"we\":80},{\"cw\":[{\"w\":\"测试\",\"wp\":\"n\",\"wc\":\"1.0000\"}],\"wb\":81,\"we\":116},{\"cw\":[{\"w\":\"音频\",\"wp\":\"n\",\"wc\":\"1.0000\"}],\"wb\":117,\"we\":172},{\"cw\":[{\"w\":\"。\",\"wp\":\"p\",\"wc\":\"0.0000\"}],\"wb\":172,\"we\":172},{\"cw\":[{\"w\":\"\",\"wp\":\"g\",\"wc\":\"0.0000\"}],\"wb\":172,\"we\":172}]}],\"pt\":\"reserved\",\"bg\":\"50\",\"si\":\"0\",\"rl\":\"0\",\"ed\":\"1840\"}},\"spk\":\"段落-0\"}]}",
  "taskEstimateTime": 0
 }

4.4 解析转写结果

bash 复制代码
def parse_result(self, result_json):
    """
    解析转写结果,按说话人分组
    """
    try:
        result = json.loads(result_json)
        speakers = {}
        if 'lattice2' in result:
            for item in result['lattice2']:
                speaker = item.get('spk', '未知')
                json_1best = json.loads(item['json_1best'])
                text = "".join(cw['w'] for rt in json_1best.get('st', {}).get('rt', []) for ws in rt.get('ws', []) for cw in ws.get('cw', []) if 'w' in cw)
                speakers.setdefault(speaker, []).append(text)
        return speakers
    except Exception as e:
        return None
        

5. 请求与返回示例

5.1 成功返回示例

json 复制代码
{
 "code": "000000",
 "descInfo": "success",
 "content": {
  "orderId": "DKHJQ202209021522090215490FAAE7DD0008C",
  "taskEstimateTime": 28000
 }
}

5.4 异步回调

1. 转写结束异步回调状态

当订单转写流程结束时会回调用户(如果录音文件转写接口 upload 传了callbackUrl),会把订单号和订单状态返回,具体的格式和参数说明如下: 回调地址示例:

bash 复制代码
GET http://ip:prot/server/xxx?orderId=DKHJQ202004291620042916580FBC96690001F&status=1

6. 文档地址

讯飞ASR文档

7. 结论

本文详细讲解了讯飞ASR API的使用流程,包括如何生成签名、上传音频、查询结果并解析返回数据。希望这篇文章对你有所帮助!如果对你有帮助,帮忙给个一键三连,求求了,各位吴彦祖,刘亦菲们

相关推荐
Tobiichiorigami.44 分钟前
Python训练Day30
python
墨风如雪1 小时前
小米亮剑:快20倍的「顺风耳」,让人车家听懂全世界
aigc
Dxy12393102161 小时前
python创建一个excel文件
开发语言·python·excel
涡能增压发动积4 小时前
Browser-Use Agent使用初体验
人工智能·后端·python
JustNow_Man5 小时前
【LLM】 BaseModel的作用
数据库·人工智能·python·uv
hans汉斯5 小时前
【建模与仿真】二阶邻居节点信息驱动的节点重要性排序算法
人工智能·python·算法·分类·数据挖掘·排序算法·xca
青衫客366 小时前
Python中的sys.path与PYTHONPATH全解析:模块导入路径的底层机制与最佳实践
python
御水流红叶6 小时前
安卓加固脱壳
android·开发语言·python
AI Echoes6 小时前
ChatGPT、Playground手动模拟Agent摘要缓冲混合记忆功能
人工智能·python·langchain
PetterHillWater6 小时前
CodeGeeX体验GLM4.5模型与实践
aigc