科大讯飞语音转文本(极速转换和普通转换两种)

有两种语音转换模式
参考

极速语音转换

和普通语音转换不一样
下载官方的demo以后,
上传m4a不行,用格式转换的软件转换为wav,可以上传,
然后有报错,

“message”:“HMAC signature cannot be verified, a valid date or x-date header is required for HMAC Authentication”}’

在这里插入图片描述
然后debug过程中上传异常了应该是被封禁了。
第二天换成了官方demo复制过来,
返回结果如下

{ “code”: 0, “data”: {“force_refresh”: “0”, “result”:
{“file_length”: 160044, “lattice”: [{“begin”: “0”, “end”: “4770”,
“json_1best”: {“st”: {“bg”: “0”, “ed”: “4770”, “pa”: “45464”, “pt”:
“reserved”, “rl”: “0”, “rt”: [{“nb”: “1”, “nc”: “1.0”, “ws”:
[{“cw”: [{“w”: “科大讯飞”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 5, “we”: 108},
{“cw”: [{“w”: “是”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 109, “we”: 144},
{“cw”: [{“w”: “中国”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 145, “we”: 184},
{“cw”: [{“w”: “最”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 185, “we”: 212},
{“cw”: [{“w”: “大”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 213, “we”: 228},
{“cw”: [{“w”: “的”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 229, “we”: 260},
{“cw”: [{“w”: “智能”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 261, “we”: 304},
{“cw”: [{“w”: “语音”, “wc”: “0.5105”, “wp”: “n”}], “wb”: 305, “we”: 352},
{“cw”: [{“w”: “技术”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 353, “we”: 392},
{“cw”: [{“w”: “提供商”, “wc”: “0.7552”, “wp”: “n”}], “wb”: 393, “we”: 472},
{“cw”: [{“w”: “。”, “wc”: “0.0000”, “wp”: “p”}], “wb”: 472, “we”: 472},
{“cw”: [{“w”: “”, “wc”: “0.0000”, “wp”: “g”}], “wb”: 472, “we”: 472}]}], “sc”: “0.93”, “si”: “92408”}}, “lid”: “45464”,
“spk”: “段落-0”}], “lattice2”: [{“begin”: “0”, “end”: “4770”,
“json_1best”: {“st”: {“bg”: “0”, “ed”: “4770”, “pa”: “45464”, “pt”:
“reserved”, “rl”: “0”, “rt”: [{“nb”: “1”, “nc”: “1.0”, “ws”: [{“cw”:
[{“w”: “科大讯飞”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 5, “we”: 108},
{“cw”: [{“w”: “是”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 109, “we”: 144},
{“cw”: [{“w”: “中国”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 145, “we”:
184}, {“cw”: [{“w”: “最”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 185, “we”:
212}, {“cw”: [{“w”: “大”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 213, “we”:
228}, {“cw”: [{“w”: “的”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 229, “we”:
260}, {“cw”: [{“w”: “智能”, “wc”: “1.0000”, “wp”: “n”}], “wb”: 261,
“we”: 304}, {“cw”: [{“w”: “语音”, “wc”: “0.5105”, “wp”: “n”}], “wb”:
305, “we”: 352}, {“cw”: [{“w”: “技术”, “wc”: “1.0000”, “wp”: “n”}],
“wb”: 353, “we”: 392}, {“cw”: [{“w”: “提供商”, “wc”: “0.7552”, “wp”:
“n”}], “wb”: 393, “we”: 472}, {“cw”: [{“w”: “。”, “wc”: “0.0000”, “wp”:
“p”}], “wb”: 472, “we”: 472}, {“cw”: [{“w”: “”, “wc”: “0.0000”, “wp”:
“g”}], “wb”: 472, “we”: 472}]}], “sc”: “0.93”, “si”: “92408”}}, “lid”:
“45464”, “spk”: “段落-0”}]}, “task_id”: “220715120925528844879582”,
“task_status”: “4”, “task_type”: “distribute_task”}, “message”:
“success”, “sid”: “ost000fd117@dx182000c0c187c0e902”}

返回的是 字典格式 想办法 从字典中提取需要的文本,然后保存。

普通语音转换

m4a格式可以其他没试过
下面代码可以运行

参考
这个bug

报错,(盲猜可能是文件没有 用 / ,因为直接复制路径 的话是 \的)

/prepare error:{‘ok’: -1, ‘err_no’: 26601, ‘failed’: ‘非法应用信息|signa verify fail’, ‘data’: None}

所以新参考了一个
能完美识别,代码如下

# -*- coding: utf-8 -*-
# 非实时转写调用demo
# 语音转写
import base64
import hashlib
import hmac
import json
import os
import time

import requests

lfasr_host = 'http://raasr.xfyun.cn/api'

# 请求的接口名
api_prepare = '/prepare'
api_upload = '/upload'
api_merge = '/merge'
api_get_progress = '/getProgress'
api_get_result = '/getResult'
# 文件分片大小10M
file_piece_sice = 10485760

# ——————————————————转写可配置参数————————————————
# 参数可在官网界面(https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html)查看,根据需求可自行在gene_params方法里添加修改
# 转写类型
lfasr_type = 0
# 是否开启分词
has_participle = 'false'
has_seperate = 'true'
# 多候选词个数
max_alternatives = 0
# 子用户标识
suid = ''


class SliceIdGenerator:
    """slice id生成器"""

    def __init__(self):
        self.__ch = 'aaaaaaaaa`'

    def getNextSliceId(self):
        ch = self.__ch
        j = len(ch) - 1
        while j >= 0:
            cj = ch[j]
            if cj != 'z':
                ch = ch[:j] + chr(ord(cj) + 1) + ch[j + 1:]
                break
            else:
                ch = ch[:j] + 'a' + ch[j + 1:]
                j = j - 1
        self.__ch = ch
        return self.__ch


class RequestApi(object):
    def __init__(self, appid, secret_key, upload_file_path):
        self.appid = appid
        self.secret_key = secret_key
        self.upload_file_path = upload_file_path

    # 根据不同的apiname生成不同的参数,本示例中未使用全部参数您可在官网(https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html)查看后选择适合业务场景的进行更换
    def gene_params(self, apiname, taskid=None, slice_id=None):
        appid = self.appid
        secret_key = self.secret_key
        upload_file_path = self.upload_file_path
        ts = str(int(time.time()))
        m2 = hashlib.md5()
        m2.update((appid + ts).encode('utf-8'))
        md5 = m2.hexdigest()
        md5 = bytes(md5, encoding='utf-8')
        # 以secret_key为key, 上面的md5为msg, 使用hashlib.sha1加密结果为signa
        signa = hmac.new(secret_key.encode('utf-8'), md5, hashlib.sha1).digest()
        signa = base64.b64encode(signa)
        signa = str(signa, 'utf-8')
        file_len = os.path.getsize(upload_file_path)
        file_name = os.path.basename(upload_file_path)
        param_dict = {}

        if apiname == api_prepare:
            # slice_num是指分片数量,如果您使用的音频都是较短音频也可以不分片,直接将slice_num指定为1即可
            slice_num = int(file_len / file_piece_sice) + (0 if (file_len % file_piece_sice == 0) else 1)
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['file_len'] = str(file_len)
            param_dict['file_name'] = file_name
            param_dict['slice_num'] = str(slice_num)
        elif apiname == api_upload:
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['task_id'] = taskid
            param_dict['slice_id'] = slice_id
        elif apiname == api_merge:
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['task_id'] = taskid
            param_dict['file_name'] = file_name
        elif apiname == api_get_progress or apiname == api_get_result:
            param_dict['app_id'] = appid
            param_dict['signa'] = signa
            param_dict['ts'] = ts
            param_dict['task_id'] = taskid
        return param_dict

    # 请求和结果解析,结果中各个字段的含义可参考:https://doc.xfyun.cn/rest_api/%E8%AF%AD%E9%9F%B3%E8%BD%AC%E5%86%99.html
    def gene_request(self, apiname, data, files=None, headers=None):
        response = requests.post(lfasr_host + apiname, data=data, files=files, headers=headers)
        result = json.loads(response.text)
        if result["ok"] == 0:
            print("{} success:".format(apiname) + str(result))
            return result
        else:
            print("{} error:".format(apiname) + str(result))
            exit(0)
            return result

    # 预处理
    def prepare_request(self):
        return self.gene_request(apiname=api_prepare,
                                 data=self.gene_params(api_prepare))

    # 上传
    def upload_request(self, taskid, upload_file_path):
        file_object = open(upload_file_path, 'rb')
        try:
            index = 1
            sig = SliceIdGenerator()
            while True:
                content = file_object.read(file_piece_sice)
                if not content or len(content) == 0:
                    break
                files = {
                    "filename": self.gene_params(api_upload).get("slice_id"),
                    "content": content
                }
                response = self.gene_request(api_upload,
                                             data=self.gene_params(api_upload, taskid=taskid,
                                                                   slice_id=sig.getNextSliceId()),
                                             files=files)
                if response.get('ok') != 0:
                    # 上传分片失败
                    print('upload slice fail, response: ' + str(response))
                    return False
                print('upload slice ' + str(index) + ' success')
                index += 1
        finally:
            'file index:' + str(file_object.tell())
            file_object.close()
        return True

    # 合并
    def merge_request(self, taskid):
        return self.gene_request(api_merge, data=self.gene_params(api_merge, taskid=taskid))

    # 获取进度
    def get_progress_request(self, taskid):
        return self.gene_request(api_get_progress, data=self.gene_params(api_get_progress, taskid=taskid))

    # 获取结果
    def get_result_request(self, taskid):
        return self.gene_request(api_get_result, data=self.gene_params(api_get_result, taskid=taskid))

    def all_api_request(self):
        # 1. 预处理
        pre_result = self.prepare_request()
        taskid = pre_result["data"]
        # 2 . 分片上传
        self.upload_request(taskid=taskid, upload_file_path=self.upload_file_path)
        # 3 . 文件合并
        self.merge_request(taskid=taskid)
        # 4 . 获取任务进度
        while True:
            # 每隔20秒获取一次任务进度
            progress = self.get_progress_request(taskid)
            progress_dic = progress
            if progress_dic['err_no'] != 0 and progress_dic['err_no'] != 26605:
                print('task error: ' + progress_dic['failed'])
                return
            else:
                data = progress_dic['data']
                task_status = json.loads(data)
                if task_status['status'] == 9:
                    print('task ' + taskid + ' finished')
                    break
                print('The task ' + taskid + ' is in processing, task status: ' + str(data))

            # 每次获取进度间隔20S
            time.sleep(20)
        # 5 . 获取结果
        res = self.get_result_request(taskid=taskid)
        # 保存到txt
        data = res['data'].strip('[').strip(']')
        for d in eval(data):
            a = d['onebest']
            fw.write(a + '\n') # 逐行保存


# 注意:如果出现requests模块报错:"NoneType" object has no attribute 'read', 请尝试将requests模块更新到2.20.0或以上版本(本demo测试版本为2.20.0)
# 输入讯飞开放平台的appid,secret_key和待转写的文件路径
if __name__ == '__main__':
    # 单个语音文件解析并保存
    root = "E:/data/"
    filename = "1" # mp3文件名,需修改
    speechpath = root +filename
    save_path = speechpath + '.txt' # txt与mp3同名,并保存在同一路径下
    fw = open(save_path, 'w')

    # 解析语音并保存到txt
    api = RequestApi(appid="9dae85ee", secret_key="34326182bc5d949ab5dc68b54f4da5a9", upload_file_path=speechpath+".m4a")
    api.all_api_request()
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方-教育技术博主

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值