实时实时语音识别(websocket)接入-腾讯云

文章详细介绍了如何使用腾讯云的实时语音识别服务,包括客户端如何持续上传音频流数据,接口的URL构造,参数签名生成过程,以及WebSocket调用的代码示例。签名生成涉及HmacSha1加密和Base64编码。整个过程强调了实时率和数据包间隔的要求,以及结束识别的信号发送。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

预期结果:实时语音文字识别

三方功能支持:腾讯云语音识别

对接要求:在识别过程中,客户端持续上传 binary message 到后台,内容为音频流二进制数据。建议每40ms 发送40ms 时长(即1:1实时率)的数据包,对应 pcm 大小为:8k 采样率640字节,16k 采样率1280字节。音频发送速率过快超过1:1实时率或者音频数据包之间发送间隔超过6秒,可能导致引擎出错,后台将返回错误并主动断开连接。

音频流上传完成之后,客户端需发送以下内容的 text message,通知后台结束识别。

拼装请求url:

传入参数:engine_model_type【引擎模型类型】16k_zh_dialect:多方言,

expired【签名的有效期截止时间,UNIX 时间戳,单位为秒】System.currentTimeMillis() / 1000L + 86400L,

needvad【语音分片长】1:开启 

nonce【随机正整数】RandomUtil.randomInt(1000, 99999);

timestamp【当前 UNIX 时间戳,单位为秒】,

secretid【密钥 】

voice_format【语音编码方式】1:pcm

voice_id【音频流识别全局唯一标识】AsrUtils.getVoiceId(asrConfig.getAppId())

signature【接口签名参数】

举例:wss://asr.cloud.tencent.com/asr/v2/1256841545?engine_model_type=16k_zh_dialect&expired=1685527216&needvad=1&nonce=37769&secretid=AKIDkHZbOtm7qKYu1ktrY0D9k6E6hfPdFIkx&timestamp=1685440816&voice_format=8&voice_id=1256841545_1685440816950_byc53&signature=Qv1YDDYCP7skMsASStxFuAVMa0w=

签名生成:

1、对除 signature 之外的所有参数按字典序进行排序,拼接请求 URL 作为签名原文,这里以 Appid=125922***SecretId=*****Qq1zhZMN8dv0****** 为例拼接签名原文,则拼接的签名原文为:

asr.cloud.tencent.com/asr/v2/125922***?engine_model_type=16k_zh&expired=1673494772&needvad=1&nonce=1673408372&secretid=*****Qq1zhZMN8dv0******&timestamp=1673408372&voice_format=1&voice_id=c64385ee-3e5c-4fc5-bbfd-7c71addb35b0

实现方法:

    private TreeMap<String, Object> getRequestParamMap(AsrConfig asrConfig, AsrRequest request, AsrRequestContent content) {
        TreeMap<String, Object> treeMap = new TreeMap();
        treeMap.put(TencentContents.SECRET_ID, asrConfig.getSecretId());
        treeMap.put(TencentContents.ENGINE_MODEL_TYPE, request.getEngineModelType());
        treeMap.put(TencentContents.VOICE_ID, content.getVoiceId());
        treeMap.put(TencentContents.VOICE_FORMAT, request.getVoiceFormat());
        treeMap.put(TencentContents.TIMESTAMP, request.getTimestamp());
        treeMap.put(TencentContents.EXPIRED, request.getExpired());
        treeMap.put(TencentContents.NONCE, request.getNonce());
        treeMap.put(TencentContents.NEED_VAD, request.getNeedVad());
        return treeMap;
    }

    private TreeMap<String, Object> getWsParams(AsrConfig asrConfig, AsrRequest request, AsrRequestContent content) {
        TreeMap<String, Object> treeMap = this.getRequestParamMap(asrConfig, request, content);
        if (request.getExtendsParam() != null) {
            Iterator var5 = request.getExtendsParam().entrySet().iterator();
            while (var5.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry) var5.next();
                treeMap.put(entry.getKey(), entry.getValue());
            }
        }
        return treeMap;
    }

    public static String createUrl(Map<String, Object> paramMap) {
        StringBuilder sb = new StringBuilder();
        sb.append("?");
        Iterator var2 = paramMap.entrySet().iterator();

        while(var2.hasNext()) {
            Map.Entry<String, Object> entry = (Map.Entry)var2.next();
            if (entry.getValue() != null && entry.getValue() != "") {
                sb.append((String)entry.getKey());
                sb.append('=');
                sb.append(entry.getValue());
                sb.append('&');
            }
        }

        if (paramMap.size() > 0) {
            sb.setLength(sb.length() - 1);
        }

        return sb.toString();
    }

String signUrl = new StringBuilder().append(asrConfig.getWsSignUrl()).append(asrConfig.getAppId()).append(paramUrl).toString();

   public AsrConfig(String appId, String secretKey, String secretId, Long waitTime, String realAsrUrl, String signUrl, String logUrl, String wsUrl, String token) {
        super(secretId, secretKey, Long.valueOf(appId), token);
        this.realAsrUrl = (String)Optional.ofNullable(realAsrUrl).orElse("https://asr.cloud.tencent.com/asr/v1/");
        this.signUrl = (String)Optional.ofNullable(signUrl).orElse("asr.cloud.tencent.com/asr/v1/");
        this.logUrl = (String)Optional.ofNullable(logUrl).orElse("https://asr.tencentcloudapi.com/");
        this.wsUrl = (String)Optional.ofNullable(wsUrl).orElse("wss://asr.cloud.tencent.com/asr/v2/");
        this.wsSignUrl = "asr.cloud.tencent.com/asr/v2/";
        this.flashUrl =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值