移动端如何实现智能语音交互

智能语音交互(Intelligent Speech Interaction)是基于语音识别、语音合成、自然语言理解等技术,为企业在多种实际应用场景下,赋予产品"能听、会说、懂你"式的智能人机交互功能。适用于智能问答、智能质检、法庭庭审实时记录、实时演讲字幕、访谈录音转写等场景,在金融、司法、电商等多个领域均有应用。

一句话识别

对时长较短(一分钟以内)的语音进行识别,适用于较短的语音交互场景,如语音搜索、语音指令、语音短消息等,可集成在各类App、智能家电、智能助手等产品中。更多信息,请参见一句话识别接口说明

实时语音识别

对不限时长的音频流做实时识别,达到"边说边出文字"的效果,内置智能断句,可提供每句话开始结束时间。可用于视频实时直播字幕、实时会议记录、实时法庭庭审记录、智能语音助手等场景。更多信息,请参见实时语音识别接口说明

录音文件识别

对用户上传的录音文件进行识别,可用于呼叫中心语音质检、庭审数据库录入、会议记录总结、医院病历录入等场景。更多信息,请参见录音文件识别接口说明

说明

针对免费用户,系统可在24小时内完成识别并返回识别文本;针对付费客户,系统可在3小时之内完成识别并返回识别文本,一次性上传大规模数据(半小时内上传超过500小时时长的录音)的除外。有大规模数据转写需求的客户,可与售前专家另行沟通。

语音合成

通过先进的深度学习技术,将文本转换成自然流畅的语音。目前有多种音色可供选择,并提供调节语速、语调、音量等功能。适用于智能客服、语音交互、文学有声阅读和无障碍播报等场景。更多信息,请参见语音合成接口说明

语音合成CosyVoice大模型

语音合成CosyVoice大模型服务是依托大规模预训练语言模型,深度融合文本理解和语音生成的一项新型语音合成技术,能够精准解析并诠释各类文本内容,将其转化为宛如真人般的自然语音。

离线语音合成

在弱网或无网状态下,通过设备本地的语音合成模型,将文本转换成自然流畅的语音。

目前有多种音色可供选择,并提供调节语速、语调、音量等功能。适用于车载导航、智能硬件、文学有声阅读和无障碍播报等场景。以SDK的方式集成,支持多种不同硬件平台。按照设备激活数量收费,收费更加灵活可控。更多信息,请参见离线语音合成接口说明

语音合成声音定制(企业版)

为您提供深度定制的TTS(Text to Speech)声音功能:使用先进的深度学习技术,用更少的数据量,更快速高效地定制高表现力的TTS声音。将自然流畅的声音输出到服务或设备上。

如果您想体验定制的声音、了解定制流程,请查看语音合成声音定制(企业版)。如有任何需求和疑问,请联系:nls_support@service.aliyun.com

自学习平台

您可以使用自学习平台提升识别效果。它提供了训练热词自学习语言模型两种方式。语音识别服务中,通过添加热词和使用热词模型来改善识别结果。在司法、金融等领域,利用语言模型定制进行优化,提高该业务场景下的识别准确率。

学习路线

  • 快速入门:快速体验智能语音交互服务。

  • 产品定价:了解智能语音交互服务的计费情况。

  • 开发指南:掌握相关术语、获取Access Token等内容。

  • 管控台指南:详细了解管控台提供的各项功能。

  • 接口参考选择需要的服务:一句话识别、实时语音识别、录音文件识别、语音合成等。

  • 自学习平台:通过自学习平台的热词、语言模型定制提升识别效果。

  • 最佳实践:了解智能语音交互服务的最佳实现方式。

  • 常见问题:查询常见问题的解决方案。

为了避免在移动端App或者桌面端工具中保存固定AccessKey ID和AccessKey Secret可能引起的泄露风险,您可以通过在App服务端创建Token并下发到移动端使用,或使用STS临时访问凭证调用语音服务两种方式,更加安全地访问智能语音交互服务。

**方案一:**通过App服务端创建Token并下发到移动端使用

前提条件

已开通智能语音交互服务,并根据产品文档调试成功,具体操作,请参见开通服务

适用场景

如果您作为移动App开发者或者桌面端开发者,希望您的用户调用阿里云智能语音交互产品的语音合成、一句话识别、实时识别等服务时,为避免在移动端App或者桌面端工具中保存固定AccessKey ID和AccessKey Secret可能引起的泄露风险,您可以使用App服务端下发语音Token调用服务。

交互流程

  1. App端向用户应用服务器请求一个调用智能语音交互接口所依赖的语音Token,此处使用您自有的通信协议即可,比如用户登录时自动请求或服务端自动下发,或定时向应用服务器发起请求。

  2. 用户应用服务器向阿里云智能语音服务发起创建语音Token的真正请求,此处请您使用阿里云SDK或智能语音交互SDK来创建Token,创建Token所需的AccessKey ID和AccessKey Secret保存在您的应用服务器上。由于语音Token具有时效性,您可以在有效期范围内直接返回给App端,无需每次都向智能语音交互服务请求新的Token。

  3. 智能语音交互服务返回给应用服务器一个语音Token信息,包括Token字符串及有效期时间,在有效期内,您可以多次复用该Token而无需重新创建,Token的使用不受不同用户、不同设备的限制。

  4. 用户应用服务器将Token返回给App端,此时App端可以缓存并使用该Token,直到Token失效。当Token失效时,App端需要向应用服务器申请新的Token。假设Token凭证有效期为24小时,App端可以在Token过期前1到2小时主动向应用服务器请求更新Token。

  5. App端使用获取到的Token构建请求,向阿里云智能语音交互公共云发起调用,比如调用实时语音识别、一句话识别、语音合成等接口(不包括录音文件识别、录音文件识别闲时版等离线类接口),更多信息,请参见阿里云智能语音交互相关文档。

此方案无需过多额外设置或开发,将AccessKey ID和AccessKey Secret保存到移动端改为保存到用户自己的服务端,并通过服务端创建语音Token再下发给移动端使用,兼容了使用安全性及开发便捷性。

**方案二:**使用STS临时访问凭证调用语音服务

阿里云STS(Security Token Service)是阿里云提供的一种临时访问权限管理服务。您可以通过STS服务给其他用户颁发临时访问凭证,该用户可使用临时访问凭证,在规定时间内调用智能语音交互的录音文件识别服务(含闲时版)。临时访问凭证无需透露您的长期密钥,保障您的账户更加安全。

前提条件

已确保当前账号为阿里云账号或者被授予AliyunRAMFullAccess 权限的RAM用户。关于为RAM用户授权的具体步骤,请参见为RAM用户授权

适用场景

如果您作为移动App开发者或者桌面端开发者,希望您的用户调用阿里云智能语音交互产品的录音文件识别等服务时,避免在移动端App或者桌面端工具中保存固定AccessKey ID和AccessKey Secret可能引起的泄露风险,您可以使用STS授权用户调用服务。

交互流程

  1. App端向用户应用服务器请求STS临时访问凭证,此处使用用户自有的通信协议即可,比如用户登录时自动请求或服务端自动下发,或定时向应用服务器发起请求。

  2. 用户应用服务器向阿里云STS服务发起STS请求,此处请使用阿里云SDK,根据应用服务器自身保存的固定AK向STS请求生成一个临时凭证。

  3. STS返回给应用服务器一个临时访问凭证,包括临时访问密钥(AccessKey ID和AccessKey Secret)、安全令牌(SecurityToken)、该凭证的过期时间等信息。

  4. 用户应用服务器将临时凭证返回给App端,此时App端可以缓存并使用该凭证,直到凭证失效。当凭证失效时,App端需要向应用服务器申请新的临时访问凭证。假设临时访问凭证有效期为1小时,App端可以每30分钟或者每50分钟的频率向应用服务器请求更新临时访问凭证。

  5. App端使用获取到的临时凭证构建请求,向阿里云智能语音交互公共云发起调用,更多信息,请参见阿里云智能语音交互相关开发文档。

    本文以录音文件识别为例,为您介绍相关示例代码。

操作步骤

步骤一:创建RAM用户
  1. 登录RAM控制台

  2. 在左侧导航栏,选择身份管理 > 用户

  3. 单击创建用户

  4. 输入登录名称显示名称

  5. 访问方式 区域下,选择Open API 调用访问 ,然后单击确定

  6. 单击复制,保存访问密钥(AccessKey ID 和 AccessKey Secret)。

**步骤二:**为RAM用户授予请求AssumeRole的权限
  1. 在已创建的RAM用户右侧,单击对应的添加权限

  2. 在添加权限页面,选择AliyunSTSAssumeRoleAccess系统策略。

  3. 单击确定

**步骤三:**创建用于获取临时访问凭证的角色
  1. 在左侧导航栏,选择身份管理 > 角色

  2. 单击创建角色 ,可信实体类型选择阿里云账号 ,单击下一步

  3. 填写角色名称 (此处以stsrole为例),选择当前云账号

  4. 单击完成 。完成角色创建后,单击关闭

  5. 在RAM角色管理页面,搜索框输入角色名称stsrole。

  6. 单击复制,保存角色的ARN。

**步骤四:**为角色授予调用录音文件识别接口的权限
  1. 创建上传文件的自定义权限策略。

    1. 在左侧导航栏,选择权限管理 > 权限策略

    2. 单击创建权限策略

    3. 创建权限策略 页面,单击脚本编辑

      如果您需要角色具备调用录音文件识别、录音文件识别闲时版服务,请参考以下配置示例。

      重要

      以下示例仅供参考。您需要根据实际需求配置更细粒度的授权策略,防止出现权限过大的风险。关于更细粒度的授权策略配置详情,请参见通过RAM或STS服务向其他用户授权

      {
          "Version": "1",
          "Statement": [
              {
                  "Action": "nls:SubmitTask",
                  "Resource": "*",
                  "Effect": "Allow"
              },
              {
                  "Action": "nls:GetTaskResult",
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
      
    4. 策略配置完成后,单击继续编辑基本信息

    5. 基本信息 区域,填写策略名称(此处以nls-stsuser-policy为例),然后单击确定

  2. 为上面创建的RAM角色stsrole授予自定义权限策略。

    1. 在左侧导航栏,选择身份管理 > 角色

    2. 角色页面,找到目标RAM角色stsrole。

    3. 单击RAM角色stsrole右侧的添加权限

    4. 添加权限 页面下的自定义策略页签,选择已创建的自定义权限策略nls-stsuser-policy。

    5. 单击确定

**步骤五:**服务端获取STS临时访问凭证

需要注意,此步骤并不是在客户端侧(移动端App或桌面端)调用的,您可以在自己的应用服务器侧,通过您持有的固定AccessKey ID和AccessKey Secret(即步骤一创建RAM用户时保存的账户信息)创建STS临时访问凭证,然后将该凭证通过您已有的交互链路返回给客户端侧。客户端侧获取到临时访问凭证后,再调用步骤六中的录音文件识别服务。

  • 方式一:使用阿里云SDK(推荐)

    您可以使用多语言STS SDK获取临时访问凭证。

    以下Java代码用于获取临时访问凭证。

    引入POM依赖:

       <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
                <version>4.5.6</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-sts</artifactId>
                <version>3.0.0</version>
            </dependency>
    

    完整示例代码如下:

    import com.aliyuncs.CommonRequest;
    import com.aliyuncs.CommonResponse;
    import com.aliyuncs.DefaultAcsClient;
    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.auth.sts.AssumeRoleRequest;
    import com.aliyuncs.auth.sts.AssumeRoleResponse;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.http.MethodType;
    import com.aliyuncs.http.ProtocolType;
    import com.aliyuncs.profile.DefaultProfile;
    import com.aliyuncs.profile.IClientProfile;
    
    public class CreateStsCredentialsDemo {
    
        public static void main(String args[]) throws ClientException {
            //同region STS的OpenAPI地址
            String endpoint = "sts.aliyuncs.com";
    
            // 填写步骤一生成的访问密钥AccessKey ID和AccessKey Secret。
            String accessKeyId = "******";
            String accessKeySecret = "******";
    
            // 填写步骤三获取的角色ARN, 一般是: acs:ram::********:role/***
            String roleArn = "******";
    
            // 自定义角色会话名称,用来区分不同的令牌,例如可填写为nls-role-session-99。
            String roleSession = "nls-role-session-99";
    
            // 添加endpoint(直接使用STS endpoint,前两个参数留空,无需添加region ID)
            DefaultProfile.addEndpoint("", "Sts", endpoint);
            // 构造default profile(参数留空,无需添加region ID)
            IClientProfile profile = DefaultProfile.getProfile("", accessKeyId, accessKeySecret);
            // 用profile构造client
            DefaultAcsClient client = new DefaultAcsClient(profile);
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSession);
            final AssumeRoleResponse response = client.getAcsResponse(request);
    
            String stsAccessKeyId = response.getCredentials().getAccessKeyId();
            String stsAccessKeySecret = response.getCredentials().getAccessKeySecret();
            String stsToken = response.getCredentials().getSecurityToken();
    
            System.out.println("Expiration: " + response.getCredentials().getExpiration());
            System.out.println("Access Key Id: " + stsAccessKeyId);
            System.out.println("Access Key Secret: " + stsAccessKeySecret);
            System.out.println("Security Token: " + stsToken);
            System.out.println("RequestId: " + response.getRequestId());
        }
    }
    
  • 方式二:使用REST API

    您可以通过调用STS服务接口AssumeRole获取临时访问凭证。

**步骤六:**客户端使用临时访问凭证调用录音文件识别服务(或录音文件识别闲时版)

如果您使用的是录音文件识别闲时版服务,本文流程及以下示例代码都可复用。

为了调用录音文件识别闲时版服务,下方的示例代码的产品信息需要从:

PRODUCT = "nls-filetrans"
DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
API_VERSION = "2018-08-17"

改为:

PRODUCT = "SpeechFileTranscriberLite"
DOMAIN = "speechfiletranscriberlite.cn-shanghai.aliyuncs.com"
API_VERSION = "2021-12-21"

Java代码演示通过STS临时访问凭证调用录音文件识别服务

引入POM依赖:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.5.6</version>
        </dependency>

以下是Java代码演示通过STS临时访问凭证调用录音文件转写服务的完整示例:

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;

public class FileTransByStsJavaDemo {
    // 地域ID,常量,固定值。
    public static final String REGIONID = "cn-shanghai";
    public static final String ENDPOINTNAME = "cn-shanghai";
    public static final String PRODUCT = "nls-filetrans";
    public static final String DOMAIN = "filetrans.cn-shanghai.aliyuncs.com";
    public static final String API_VERSION = "2018-08-17";
    public static final String POST_REQUEST_ACTION = "SubmitTask";
    public static final String GET_REQUEST_ACTION = "GetTaskResult";
    // 请求参数
    public static final String KEY_APP_KEY = "appkey";
    public static final String KEY_FILE_LINK = "file_link";
    public static final String KEY_VERSION = "version";
    public static final String KEY_ENABLE_WORDS = "enable_words";
    // 响应参数
    public static final String KEY_TASK = "Task";
    public static final String KEY_TASK_ID = "TaskId";
    public static final String KEY_STATUS_TEXT = "StatusText";
    public static final String KEY_RESULT = "Result";
    // 状态值
    public static final String STATUS_SUCCESS = "SUCCESS";
    private static final String STATUS_RUNNING = "RUNNING";
    private static final String STATUS_QUEUEING = "QUEUEING";
    // 阿里云鉴权client
    IAcsClient client;
    public FileTransByStsJavaDemo(String stsAccessKeyId, String stsAccessKeySecret, String stsToken) {
        // 设置endpoint
        try {
            DefaultProfile.addEndpoint(ENDPOINTNAME, REGIONID, PRODUCT, DOMAIN);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        // 创建DefaultAcsClient实例并初始化
        DefaultProfile profile = DefaultProfile.getProfile(REGIONID, stsAccessKeyId, stsAccessKeySecret, stsToken);
        this.client = new DefaultAcsClient(profile);
    }
    public String submitFileTransRequest(String appKey, String fileLink) {
        /**
         * 1. 创建CommonRequest,设置请求参数。
         */
        CommonRequest postRequest = new CommonRequest();
        // 设置域名
        postRequest.setDomain(DOMAIN);
        // 设置API的版本号,格式为YYYY-MM-DD。
        postRequest.setVersion(API_VERSION);
        // 设置action
        postRequest.setAction(POST_REQUEST_ACTION);
        // 设置产品名称
        postRequest.setProduct(PRODUCT);
        /**
         * 2. 设置录音文件识别请求参数,以JSON字符串的格式设置到请求Body中。
         */
        JSONObject taskObject = new JSONObject();
        // 设置appkey
        taskObject.put(KEY_APP_KEY, appKey);
        // 设置音频文件访问链接
        taskObject.put(KEY_FILE_LINK, fileLink);
        // 新接入请使用4.0版本,已接入(默认2.0)如需维持现状,请注释掉该参数设置。
        taskObject.put(KEY_VERSION, "4.0");
        // 设置是否输出词信息,默认为false,开启时需要设置version为4.0及以上。
        taskObject.put(KEY_ENABLE_WORDS, true);
        String task = taskObject.toJSONString();
        System.out.println(task);
        // 设置以上JSON字符串为Body参数。
        postRequest.putBodyParameter(KEY_TASK, task);
        // 设置为POST方式的请求。
        postRequest.setMethod(MethodType.POST);
        /**
         * 3. 提交录音文件识别请求,获取录音文件识别请求任务的ID,以供识别结果查询使用。
         */
        String taskId = null;
        try {
            CommonResponse postResponse = client.getCommonResponse(postRequest);
            System.err.println("提交录音文件识别请求的响应:" + postResponse.getData());
            if (postResponse.getHttpStatus() == 200) {
                JSONObject result = JSONObject.parseObject(postResponse.getData());
                String statusText = result.getString(KEY_STATUS_TEXT);
                if (STATUS_SUCCESS.equals(statusText)) {
                    taskId = result.getString(KEY_TASK_ID);
                }
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return taskId;
    }
    public String getFileTransResult(String taskId) {
        /**
         * 1. 创建CommonRequest,设置任务ID。
         */
        CommonRequest getRequest = new CommonRequest();
        // 设置域名
        getRequest.setDomain(DOMAIN);
        // 设置API版本
        getRequest.setVersion(API_VERSION);
        // 设置action
        getRequest.setAction(GET_REQUEST_ACTION);
        // 设置产品名称
        getRequest.setProduct(PRODUCT);
        // 设置任务ID为查询参数
        getRequest.putQueryParameter(KEY_TASK_ID, taskId);
        // 设置为GET方式的请求
        getRequest.setMethod(MethodType.GET);
        /**
         * 2. 提交录音文件识别结果查询请求
         * 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述为"SUCCESS"或错误描述,则结束轮询。
         */
        String result = null;
        while (true) {
            try {
                CommonResponse getResponse = client.getCommonResponse(getRequest);
                System.err.println("识别查询结果:" + getResponse.getData());
                if (getResponse.getHttpStatus() != 200) {
                    break;
                }
                JSONObject rootObj = JSONObject.parseObject(getResponse.getData());
                String statusText = rootObj.getString(KEY_STATUS_TEXT);
                if (STATUS_RUNNING.equals(statusText) || STATUS_QUEUEING.equals(statusText)) {
                    // 继续轮询,注意设置轮询时间间隔。
                    Thread.sleep(10000);
                }
                else {
                    // 状态信息为成功,返回识别结果;状态信息为异常,返回空。
                    if (STATUS_SUCCESS.equals(statusText)) {
                        result = rootObj.getString(KEY_RESULT);
                        // 状态信息为成功,但没有识别结果,则可能是由于文件里全是静音、噪音等导致识别为空。
                        if(result == null) {
                            result = "";
                        }
                    }
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    public static void main(String args[]) throws Exception {
        // 相比非STS模式,此时此处填写之前生成的STS临时访问凭证。
        // 特别需要注意的是:临时访问凭证存在有效期,在有效期内您可以一直使用,但是请在过期前及时再次获取
        final String stsAccessKeyId = "STS.******";
        final String stsAccessKeySecret = "******";
        final String stsToken = "******";
        final String appKey = "******";
        
        String fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav";
        FileTransByStsJavaDemo demo = new FileTransByStsJavaDemo(stsAccessKeyId, stsAccessKeySecret, stsToken);
        // 第一步:提交录音文件识别请求,获取任务ID用于后续的识别结果轮询。
        String taskId = demo.submitFileTransRequest(appKey, fileLink);
        if (taskId != null) {
            System.out.println("录音文件识别请求成功,task_id: " + taskId);
        }
        else {
            System.out.println("录音文件识别请求失败!");
            return;
        }
        // 第二步:根据任务ID轮询识别结果。
        String result = demo.getFileTransResult(taskId);
        if (result != null) {
            System.out.println("录音文件识别结果查询成功:" + result);
        }
        else {
            System.out.println("录音文件识别结果查询失败!");
        }
    }
}

Python代码演示通过STS临时访问凭证调用录音文件识别服务

# -*- coding: utf-8 -*-
import json
import time
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.auth.credentials import StsTokenCredential
from aliyunsdkcore.request import CommonRequest

REGION_ID = "cn-shanghai"
DOMAIN = "filetrans.cn-shanghai.aliyuncs.com"
PRODUCT = "nls-filetrans"
API_VERSION = "2018-08-17"
POST_REQUEST_ACTION = "SubmitTask"
GET_REQUEST_ACTION = "GetTaskResult"
KEY_APP_KEY = "appkey"
KEY_FILE_LINK = "file_link"
KEY_VERSION = "version"
KEY_TASK = "Task"
KEY_TASK_ID = "TaskId"
KEY_STATUS_TEXT = "StatusText"

def submitTask(stsAkId, stsAkSecret, stsToken, appKey, fileLink):
    # 创建AcsClient实例
    stsTokenCredential = StsTokenCredential(stsAkId, stsAkSecret, stsToken)
    client = AcsClient(region_id=REGION_ID, credential=stsTokenCredential)
    # 创建提交录音文件识别请求,并设置请求参数。
    postRequest = CommonRequest()
    postRequest.set_domain(DOMAIN)
    postRequest.set_version(API_VERSION)
    postRequest.set_product(PRODUCT)
    postRequest.set_action_name(POST_REQUEST_ACTION)
    postRequest.set_method('POST')

    task = {KEY_APP_KEY : appKey, KEY_FILE_LINK : fileLink, KEY_VERSION : "4.0", "enable_words" : False}
    task = json.dumps(task)
    print(task)
    postRequest.add_body_params(KEY_TASK, task)
    taskId = ""
    try :
        # 提交录音文件识别请求,处理服务端返回的响应。
        postResponse = client.do_action_with_exception(postRequest)
        postResponse = json.loads(postResponse)
        print(postResponse)
        # 获取录音文件识别请求任务的ID,以供识别结果查询使用。
        statusText = postResponse[KEY_STATUS_TEXT]
        if statusText == "SUCCESS" :
            print("录音文件识别请求成功响应!")
            taskId = postResponse[KEY_TASK_ID]
            print("taskId = " + taskId)
        else :
            print("录音文件识别请求失败!")
    except ServerException as e:
        print(e)
    except ClientException as e:
        print(e)

    print(taskId)
    return taskId

def queryResult(stsAkId, stsAkSecret, stsToken, taskId):
    # 创建CommonRequest,设置任务ID。
    stsTokenCredential = StsTokenCredential(stsAkId, stsAkSecret, stsToken)
    client = AcsClient(region_id=REGION_ID, credential=stsTokenCredential)

    getRequest = CommonRequest()
    getRequest.set_domain(DOMAIN)
    getRequest.set_version(API_VERSION)
    getRequest.set_product(PRODUCT)
    getRequest.set_action_name(GET_REQUEST_ACTION)
    getRequest.set_method('GET')
    getRequest.add_query_param(KEY_TASK_ID, taskId)

    # 提交录音文件识别结果查询请求
    # 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述符为"SUCCESS"、"SUCCESS_WITH_NO_VALID_FRAGMENT",或者为错误描述,则结束轮询。
    statusText = ""
    while True :
        try :
            getResponse = client.do_action_with_exception(getRequest)
            getResponse = json.loads(getResponse)
            print (json.dumps(getResponse).decode('unicode-escape'))
            statusText = getResponse[KEY_STATUS_TEXT]
            if statusText == "RUNNING" or statusText == "QUEUEING" :
                # 继续轮询
                time.sleep(5)
            else :
                # 退出轮询
                break
        except ServerException as e:
            print (e)
        except ClientException as e:
            print (e)
    if statusText == "SUCCESS" :
        print ("录音文件识别成功!")
    else :
        print ("录音文件识别失败!")

# 智能语音交互Appkey,获取Appkey请前往控制台:https://nls-portal.console.aliyun.com/applist
appKey = '******'
# 测试录音的url
fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav"

# 相比非STS模式,此时此处填写之前生成的STS临时访问凭证(含STS账号信息及SecurityToken)
# 特别需要注意的是:临时访问凭证存在有效期,在有效期内您可以一直使用,但是请在过期前及时再次获取
stsAkId = 'STS.******'
stsAkSecret = '******'
stsToken = '************'
print("--- submit one file ---")
taskId = submitTask(stsAkId, stsAkSecret, stsToken, appKey, fileLink)

print("--- query result ---")
queryResult(stsAkId, stsAkSecret, stsToken, taskId)

Go代码演示通过STS临时访问凭证调用录音文件转写服务

关于阿里云SDK Go语言版本的安装操作,请参见Go SDK 依赖STS SDK

以下是Go代码演示通过STS临时访问凭证调用录音文件转写服务的完整示例:

package main

import (
	"encoding/json"
	"fmt"
	"time"

	"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests"
)

func main() {
	// 地域ID,固定值。
	const REGION_ID string = "cn-shanghai"
	const ENDPOINT_NAME string = "cn-shanghai"
	const PRODUCT string = "nls-filetrans"
	const DOMAIN string = "filetrans.cn-shanghai.aliyuncs.com"
	const API_VERSION string = "2018-08-17"
	const POST_REQUEST_ACTION string = "SubmitTask"
	const GET_REQUEST_ACTION string = "GetTaskResult"
	// 请求参数
	const KEY_APP_KEY string = "appkey"
	const KEY_FILE_LINK string = "file_link"
	const KEY_VERSION string = "version"
	const KEY_ENABLE_WORDS string = "enable_words"
	// 响应参数
	const KEY_TASK string = "Task"
	const KEY_TASK_ID string = "TaskId"
	const KEY_STATUS_TEXT string = "StatusText"
	const KEY_RESULT string = "Result"
	// 状态值
	const STATUS_SUCCESS string = "SUCCESS"
	const STATUS_RUNNING string = "RUNNING"
	const STATUS_QUEUEING string = "QUEUEING"

	// 相比非STS模式,此时此处填写之前生成的STS临时访问凭证(含STS账号信息及SecurityToken)
	// 特别需要注意的是:临时访问凭证存在有效期,在有效期内您可以一直使用,但是请在过期前及时再次获取
	var accessKeyId string = "STS.******"
	var accessKeySecret string = "******"
	var stsToken string = ""******""
  var appKey string = "请填写您的appkey"

	var fileLink string = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav"
	client, err := sdk.NewClientWithStsToken(REGION_ID, accessKeyId, accessKeySecret, stsToken)
	if err != nil {
		panic(err)
	}
	postRequest := requests.NewCommonRequest()
	postRequest.Domain = DOMAIN
	postRequest.Version = API_VERSION
	postRequest.Product = PRODUCT
	postRequest.ApiName = POST_REQUEST_ACTION
	postRequest.Method = "POST"
	mapTask := make(map[string]string)
	mapTask[KEY_APP_KEY] = appKey
	mapTask[KEY_FILE_LINK] = fileLink
	// 新接入请使用4.0版本,已接入(默认2.0)如需维持现状,请注释掉该参数设置。
	mapTask[KEY_VERSION] = "4.0"
	// 设置是否输出词信息,默认为false。开启时需要设置version为4.0。
	mapTask[KEY_ENABLE_WORDS] = "false"
	task, err := json.Marshal(mapTask)
	if err != nil {
		panic(err)
	}
	postRequest.FormParams[KEY_TASK] = string(task)
	postResponse, err := client.ProcessCommonRequest(postRequest)
	if err != nil {
		panic(err)
	}
	postResponseContent := postResponse.GetHttpContentString()
	fmt.Println(postResponseContent)
	if postResponse.GetHttpStatus() != 200 {
		fmt.Println("录音文件识别请求失败,Http错误码: ", postResponse.GetHttpStatus())
		return
	}
	var postMapResult map[string]interface{}
	err = json.Unmarshal([]byte(postResponseContent), &postMapResult)
	if err != nil {
		panic(err)
	}
	var taskId string = ""
	var statusText string = ""
	statusText = postMapResult[KEY_STATUS_TEXT].(string)
	if statusText == STATUS_SUCCESS {
		fmt.Println("录音文件识别请求成功响应!")
		taskId = postMapResult[KEY_TASK_ID].(string)
	} else {
		fmt.Println("录音文件识别请求失败!")
		return
	}
	getRequest := requests.NewCommonRequest()
	getRequest.Domain = DOMAIN
	getRequest.Version = API_VERSION
	getRequest.Product = PRODUCT
	getRequest.ApiName = GET_REQUEST_ACTION
	getRequest.Method = "GET"
	getRequest.QueryParams[KEY_TASK_ID] = taskId
	statusText = ""
	for true {
		getResponse, err := client.ProcessCommonRequest(getRequest)
		if err != nil {
			panic(err)
		}
		getResponseContent := getResponse.GetHttpContentString()
		fmt.Println("识别查询结果:", getResponseContent)
		if getResponse.GetHttpStatus() != 200 {
			fmt.Println("识别结果查询请求失败,Http错误码:", getResponse.GetHttpStatus())
			break
		}
		var getMapResult map[string]interface{}
		err = json.Unmarshal([]byte(getResponseContent), &getMapResult)
		if err != nil {
			panic(err)
		}
		statusText = getMapResult[KEY_STATUS_TEXT].(string)
		if statusText == STATUS_RUNNING || statusText == STATUS_QUEUEING {
			time.Sleep(10 * time.Second)
		} else {
			break
		}
	}
	if statusText == STATUS_SUCCESS {
		fmt.Println("录音文件识别成功!")
	} else {
		fmt.Println("录音文件识别失败!")
	}
}

Node.js代码演示通过STS临时访问凭证调用录音文件识别服务

请您提前安装阿里云Core SDK、STS SDK及录音文件转写识别SDK,前两个SDK的安装,请参见Node.js SDK安装及示例。简单步骤如下:

npm install @alicloud/pop-core --save  
npm install @alicloud/sts-sdk --save   
npm install @alicloud/nls-filetrans-2018-08-17 --save

以下是Node.js代码演示通过STS临时访问凭证调用录音文件转写服务的完整示例:

'use strict';
const Client = require('@alicloud/nls-filetrans-2018-08-17');
function fileTrans(akID, akSecret, stsToken, appKey, fileLink) {
    //地域ID,固定值。
    var ENDPOINT = 'http://filetrans.cn-hangzhou.aliyuncs.com';
    var API_VERSION = '2018-08-17';
    /**
     * 创建阿里云鉴权client
     */
    var client = new Client({
        accessKeyId: akID, 
        secretAccessKey: akSecret,
        securityToken: stsToken,
        endpoint: ENDPOINT,
        apiVersion: API_VERSION
    });
    /**
     * 提交录音文件识别请求,请求参数组合成JSON格式的字符串作为task的值。
     * 请求参数appkey:项目appkey,获取Appkey请前往控制台:https://nls-portal.console.aliyun.com/applist
     * 请求参数file_link:需要识别的录音文件。
     */
    var task = {
        appkey : appKey,
        file_link : fileLink,
        version : "4.0",        // 新接入请使用4.0版本,已接入(默认2.0)如需维持现状,请注释掉该参数设置。
        enable_words : false     // 设置是否输出词信息,默认值为false,开启时需要设置version为4.0。
    };
    task = JSON.stringify(task);
    var taskParams = {
        Task : task
    };
    var options = {
            method: 'POST'
        };
    // 提交录音文件识别请求,处理服务端返回的响应。
    client.submitTask(taskParams, options).then((response) => {
        console.log(response);
        // 服务端响应信息的状态描述StatusText。
        var statusText = response.StatusText;
        if (statusText != 'SUCCESS') {
            console.log('录音文件识别请求响应失败!')
            return;
        }
        console.log('录音文件识别请求响应成功!');
        // 获取录音文件识别请求任务的TaskId,以供识别结果查询使用。
        var taskId = response.TaskId;
        /**
         * 以TaskId为查询参数,提交识别结果查询请求。
         * 以轮询的方式进行识别结果的查询,直到服务端返回的状态描述为"SUCCESS"、SUCCESS_WITH_NO_VALID_FRAGMENT,
         * 或者为错误描述,则结束轮询。
        */
        var taskIdParams = {
            TaskId : taskId
        };
        var timer = setInterval(() => {
            client.getTaskResult(taskIdParams).then((response) => {
                console.log('识别结果查询响应:');
                console.log(response);
                var statusText = response.StatusText;
                if (statusText == 'RUNNING' || statusText == 'QUEUEING') {
                    // 继续轮询,注意间隔周期。
                }
                else {
                    if (statusText == 'SUCCESS' || statusText == 'SUCCESS_WITH_NO_VALID_FRAGMENT') {
                        console.log('录音文件识别成功:');
                        var sentences = response.Result;
                        console.log(sentences);
                    }
                    else {
                        console.log('录音文件识别失败!');
                    }
                    // 退出轮询
                    clearInterval(timer);
                }
            }).catch((error) => {
                console.error(error);
                // 异常情况,退出轮询。
                clearInterval(timer);
            });
        }, 10000);
    }).catch((error) => {
        console.error(error);
    });
}

// 相比非STS模式,此时此处填写之前生成的STS临时访问凭证(含STS账号信息及SecurityToken)
// 特别需要注意的是:临时访问凭证存在有效期,在有效期内您可以一直使用,但是请在过期前及时再次获取
var akId = 'STS.******';
var akSecret = '******';
var stsToken = '******';
var appKey = '请填写您的appkey';
var fileLink = 'https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav';

fileTrans(akId, akSecret, stsToken, appKey, fileLink);

PHP代码演示通过STS临时访问凭证调用录音文件识别服务

请您提前安装阿里云Core SDK、STS SDK的PHP语言版本,详细安装请参见Node.js SDK安装及示例。简单步骤如下:

composer require alibabacloud/sdk
composer require alibabacloud/sts

以下是PHP代码演示通过STS临时访问凭证调用录音文件识别服务的完整示例:

<?php
require __DIR__ . '/vendor/autoload.php';
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;

class NLSFileTrans {
    // 请求参数
    private const KEY_APP_KEY = "appkey";
    private const KEY_FILE_LINK = "file_link";
    private const KEY_VERSION = "version";
    private const KEY_ENABLE_WORDS = "enable_words";
    // 响应参数
    private const KEY_TASK_ID = "TaskId";
    private const KEY_STATUS_TEXT = "StatusText";
    private const KEY_RESULT = "Result";
    // 状态值
    private const STATUS_SUCCESS = "SUCCESS";
    private const STATUS_RUNNING = "RUNNING";
    private const STATUS_QUEUEING = "QUEUEING";

    function submitFileTransRequest($appKey, $fileLink) {
        // 获取task JSON字符串,包含appkey和file_link参数等。
        $taskArr = array(self::KEY_APP_KEY => $appKey, self::KEY_FILE_LINK => $fileLink, self::KEY_VERSION => "4.0", self::KEY_ENABLE_WORDS => FALSE);
        $task = json_encode($taskArr);
        print $task . "\n";
        try {
            // 提交请求,返回服务端的响应。
            $submitTaskResponse = AlibabaCloud::nlsFiletrans()
                                              ->v20180817()
                                              ->submitTask()
                                              ->host("filetrans.cn-shanghai.aliyuncs.com")
                                              ->withTask($task)
                                              ->request();

            print $submitTaskResponse . "\n";
            // 获取录音文件识别请求任务的ID,以供识别结果查询使用。
            $taskId = NULL;
            $statusText = $submitTaskResponse[self::KEY_STATUS_TEXT];
            if (strcmp(self::STATUS_SUCCESS, $statusText) == 0) {
                $taskId = $submitTaskResponse[self::KEY_TASK_ID];
            }
            return $taskId;
        } catch (ClientException $exception) {
            // 获取错误消息
            print_r($exception->getErrorMessage());
        } catch (ServerException $exception) {
            // 获取错误消息
            print_r($exception->getErrorMessage());
        }
    }
    function getFileTransResult($taskId) {
        $result = NULL;
        while (TRUE) {
            try {
                $getResultResponse = AlibabaCloud::nlsFiletrans()
                                                 ->v20180817()
                                                 ->getTaskResult()
                                                 ->host("filetrans.cn-shanghai.aliyuncs.com")
                                                 ->withTaskId($taskId)
                                                 ->request();
                print "识别查询结果: " . $getResultResponse . "\n";
                $statusText = $getResultResponse[self::KEY_STATUS_TEXT];
                if (strcmp(self::STATUS_RUNNING, $statusText) == 0 || strcmp(self::STATUS_QUEUEING, $statusText) == 0) {
                    // 继续轮询
                    sleep(10);
                }
                else {
                    if (strcmp(self::STATUS_SUCCESS, $statusText) == 0) {
                        $result = $getResultResponse;
                    }
                    // 退出轮询
                    break;
                }
            } catch (ClientException $exception) {
                // 获取错误消息
                print_r($exception->getErrorMessage());
            } catch (ServerException $exception) {
                // 获取错误消息
                print_r($exception->getErrorMessage());
            }
        }
        return $result;
    }
}
$accessKeyId = "STS.******";
$accessKeySecret = "******";
$stsToken = "******";
$appKey = "请填写您的appkey";
$fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav";
/**
  * 第一步:设置一个全局客户端。
  * 使用阿里云RAM账号的AccessKey ID和AccessKey Secret进行鉴权。
 */
Alibabacloud::stsClient($accessKeyId, $accessKeySecret, $stsToken)
                ->regionId("cn-shanghai")
                ->asGlobalClient();

$fileTrans = new NLSFileTrans();
/**
  *  第二步:提交录音文件识别请求,获取任务ID,用于后续的识别结果轮询。
 */
$taskId = $fileTrans->submitFileTransRequest($appKey, $fileLink);
if ($taskId != NULL) {
    print "录音文件识别请求成功,task_id: " . $taskId . "\n";
}
else {
    print "录音文件识别请求失败!";
    return ;
}
/**
  * 第三步:根据任务ID轮询识别结果。
 */
$result = $fileTrans->getFileTransResult($taskId);
if ($result != NULL) {
    print "录音文件识别结果查询成功: " . $result . "\n";
}
else {
    print "录音文件识别结果查询失败!";
}
相关推荐
乐闻x2 天前
VSCode 插件开发实战(二):自定义插件与编辑器交互技巧
vscode·编辑器·交互
万物得其道者成4 天前
构建健壮的 Axios 请求管理器:提升 React 应用的 API 交互体验
前端·react.js·交互
小小怪下士yeah5 天前
探秘 JSON:数据交互的轻盈使者
okhttp·json·交互
兆。6 天前
JS进阶-面向对象-搭建网站-HTML与JS交互
javascript·爬虫·python·html·交互
叫我菜菜就好6 天前
【Flutter_Web】Flutter编译Web第二篇(webview篇):flutter_inappwebview如何改造方法,变成web之后数据如何交互
前端·flutter·交互·inappwebview
GISer_Jing6 天前
前端切换端口,系统前后端交互就报401错误(未授权)的常见原因
前端·java-ee·交互
Forworder6 天前
MVC前后端交互案例--留言板
java·开发语言·java-ee·mvc·intellij-idea·交互·postman
飞露7 天前
Uniapp跟原生android插件交互发信息(二)
android·uni-app·交互
梓贤Vigo10 天前
【Axure教程】动态统计字数
交互·产品经理·axure·原型
聆思科技AI芯片10 天前
实操给触摸一体机接入大模型语音交互
交互