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

相关推荐
mahuifa9 分钟前
Qt图表绘制(QtCharts)- 性能优化(13)
python·qt·pyside6·开发经验·qtchart
Bugabooo32 分钟前
python打卡DAY22
开发语言·python
低维歌者1 小时前
python训练营day27
java·开发语言·python
微刻时光1 小时前
影刀处理 Excel:智能工具带来的高效变革
人工智能·python·低代码·自动化·excel·rpa·影刀rpa
大帅不是我1 小时前
Python多进程编程执行任务
java·前端·python
Fu_lucas1 小时前
Python Logging 模块完全指南
开发语言·python
Eiceblue1 小时前
Python 在Excel单元格中应用多种字体样式
开发语言·vscode·python·pycharm·excel
Superstarimage3 小时前
使用conda创建python虚拟环境,并自定义路径
windows·python·conda
菜鸡码农,喵。3 小时前
已经装了pygame但pycharm显示没有该模块/软件包无法加载出来下载pygame
python·pycharm·pygame
小羊Linux客栈3 小时前
自动化:批量文件重命名
运维·人工智能·python·自动化·游戏程序