【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的使用流程,包括如何生成签名、上传音频、查询结果并解析返回数据。希望这篇文章对你有所帮助!如果对你有帮助,帮忙给个一键三连,求求了,各位吴彦祖,刘亦菲们

相关推荐
小碗细面16 小时前
告别手动喂饭!Skill-Seekers 快速构建你的 AI 专属知识库
aigc·ai编程
AI探索者16 小时前
LangGraph StateGraph 实战:状态机聊天机器人构建指南
python
AI探索者16 小时前
LangGraph 入门:构建带记忆功能的天气查询 Agent
python
iOS日常16 小时前
iOS设备崩溃日志获取与查看
ios·xcode
王小酱16 小时前
AI 编程实战指南:核心概念梳理与 Claude Code 高效技巧
aigc·openai·ai编程
FishCoderh17 小时前
Python自动化办公实战:批量重命名文件,告别手动操作
python
躺平大鹅17 小时前
Python函数入门详解(定义+调用+参数)
python
曲幽18 小时前
我用FastAPI接ollama大模型,差点被asyncio整崩溃(附对话窗口实战)
python·fastapi·web·async·httpx·asyncio·ollama
是一碗螺丝粉1 天前
LangChain 核心组件深度解析:模型与提示词模板
前端·langchain·aigc
两万五千个小时1 天前
落地实现 Anthropic Multi-Agent Research System
人工智能·python·架构