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

相关推荐
我赵帅的飞起14 小时前
python国密SM4加解密
python·sm4加解密·国密sm4加解密
yaoh.wang14 小时前
力扣(LeetCode) 1: 两数之和 - 解法思路
python·程序人生·算法·leetcode·面试·跳槽·哈希算法
liwulin050615 小时前
【PYTHON-YOLOV8N】关于YOLO的推理训练图片的尺寸
开发语言·python·yolo
我送炭你添花15 小时前
Pelco KBD300A 模拟器:04+1.Python 打包详解:历史、发展与多种方式对比
python·测试工具·运维开发
yaoh.wang15 小时前
力扣(LeetCode) 27: 移除元素 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·双指针
幸存者letp15 小时前
Python 常用方法分类大全
linux·服务器·python
2401_8414956415 小时前
【自然语言处理】中文 n-gram 词模型
人工智能·python·算法·自然语言处理·n-gram·中文文本生成模型·kneser-ney平滑
嘻哈baby15 小时前
为什么越来越多的人放弃Flask转向FastAPI?
python
ss27316 小时前
Java并发编程:DelayQueue延迟订单系统
java·python·算法
JHC00000016 小时前
118. 杨辉三角
python·算法·面试