Java demo

更新时间:
复制 MD 格式

This topic describes how to use the Java software development kit (SDK) for Alibaba Cloud Intelligent Speech Interaction. It includes installation instructions and code examples.

Prerequisites

  • Before you use the SDK, review the API reference. For more information, see API reference.

  • You have activated Intelligent Speech Interaction and obtained an AccessKey ID and AccessKey secret. For more information, see Get started.

SDK description

The Java demo for audio file transcription uses the CommonRequest of Alibaba Cloud SDK for Java to submit transcription requests and query for results. It uses remote procedure call (RPC) POP API calls. For more information about how to use CommonRequest of Alibaba Cloud SDK for Java, see Generalized calls.

Important

Alibaba Cloud SDK for Java does not support Android development.

Java dependencies

You only need to add dependencies for the core library of Alibaba Cloud SDK for Java and the Alibaba open source library fastjson. The core library of Alibaba Cloud SDK for Java must be version 3.5.0 or later. If you use version 4.0.0 or later, you must add the required third-party dependencies as prompted.

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

Examples

Note

Download nls-sample-16k.wav. The WAV audio file used in the example is PCM-encoded, has a sample rate of 16 kHz, and uses the general-purpose model.

Authentication

Create a client by passing the AccessKey ID and AccessKey secret of your Alibaba Cloud account to the Alibaba Cloud SDK for Java. For more information about how to obtain an AccessKey, see Activate the service. The following code provides an example:

final String accessKeyId = System.getenv().get("ALIYUN_AK_ID");
final String accessKeySecret = System.getenv().get("ALIYUN_AK_SECRET");
/**
 * The region ID.
 */
final String regionId = "cn-shanghai";
final String endpointName = "cn-shanghai";
final String product = "nls-filetrans";
final String domain = "filetrans.cn-shanghai.aliyuncs.com";

IAcsClient client;
// Set the endpoint.
DefaultProfile.addEndpoint(endpointName, regionId, product, domain);
// Create and initialize a DefaultAcsClient instance.
DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);
client = new DefaultAcsClient(profile);

Call the API for audio file transcription requests

The Java example uses polling. It submits an audio file transcription request to obtain a task ID, which is then used for polling.

Note

For more information about parameter settings, see API reference. Set only the required parameters in the JSON string and leave the other parameters at their default values.

/**
 * Create a CommonRequest and set the request parameters.
 */
CommonRequest postRequest = new CommonRequest();
postRequest.setDomain("filetrans.cn-shanghai.aliyuncs.com"); // Set the domain name. This is a static field.
postRequest.setVersion("2018-08-17");         // Set the version number for the Alibaba Cloud China Website.
// postRequest.setVersion("2019-08-23");         // Set the version number for the Alibaba Cloud International Website. Users of the international website must set this parameter.
postRequest.setAction("SubmitTask");          // Set the action. This is a static field.
postRequest.setProduct("nls-filetrans");      // Set the product name. This is a static field.
// Set the request parameters for audio file transcription. Add the parameters to the request body in a JSON string.
JSONObject taskObject = new JSONObject();
taskObject.put("appkey", "Your appkey");    // The Appkey of your project. To obtain an Appkey, go to the console: https://nls-portal.console.aliyun.com/applist
taskObject.put("file_link", "The URL of your audio file");  // Set the link to the audio file.
taskObject.put(KEY_VERSION, "4.0");  // If you are a new user, use version 4.0. If you are an existing user of version 2.0 and want to continue using it, comment out this parameter.
String task = taskObject.toJSONString();
postRequest.putBodyParameter("Task", task);  // Set the preceding JSON string as the Body parameter.
postRequest.setMethod(MethodType.POST);      // Set the request method to POST.
// postRequest.setHttpContentType(FormatType.JSON);    // If the version of aliyun-java-sdk-core is 4.6.0 or later, uncomment this line.
/**
 * Submit the audio file transcription request.
 */
String taskId = "";   // Obtain the ID of the audio file transcription task. The ID is used to query the transcription result.
CommonResponse postResponse = client.getCommonResponse(postRequest);
if (postResponse.getHttpStatus() == 200) {
    JSONObject result = JSONObject.parseObject(postResponse.getData());
    String statusText = result.getString("StatusText");
    if ("SUCCESS".equals(statusText)) {
        System.out.println("The audio file transcription request was successful. Response: " + result.toJSONString());
        taskId = result.getString("TaskId");
    }
    else {
        System.out.println("The audio file transcription request failed. Response: " + result.toJSONString());
        return;
    }
}
else {
    System.err.println("The audio file transcription request failed. HTTP error code: " + postResponse.getHttpStatus());
    System.err.println("The audio file transcription request failed. Response: " + JSONObject.toJSONString(postResponse));
    return;
}

Query the audio file transcription result

Use the obtained task ID to query for the audio file transcription result.

/**
 * Create a CommonRequest and set the task ID.
 */
CommonRequest getRequest = new CommonRequest();
getRequest.setDomain("filetrans.cn-shanghai.aliyuncs.com");   // Set the domain name. This is a static field.
getRequest.setVersion("2018-08-17");         // Set the version number for the Alibaba Cloud China Website.
// getRequest.setVersion("2019-08-23");         // Set the version number for the Alibaba Cloud International Website. Users of the international website must set this parameter.
getRequest.setAction("GetTaskResult");           // Set the action. This is a static field.
getRequest.setProduct("nls-filetrans");          // Set the product name. This is a static field.
getRequest.putQueryParameter("TaskId", taskId);  // Set the task ID as a query parameter.
getRequest.setMethod(MethodType.GET);            // Set the request method to GET.
/**
 * Submit the request to query the audio file transcription result.
 * Poll for the result until the server returns SUCCESS, SUCCESS_WITH_NO_VALID_FRAGMENT, or an error.
 */
String statusText = "";
while (true) {
    CommonResponse getResponse = client.getCommonResponse(getRequest);
    if (getResponse.getHttpStatus() != 200) {
        System.err.println("The request to query the transcription result failed. HTTP error code: " + getResponse.getHttpStatus());
        System.err.println("The request to query the transcription result failed. Response: " + getResponse.getData());
        break;
    }
    JSONObject result = JSONObject.parseObject(getResponse.getData());
    System.out.println("Query result: " + result.toJSONString());
    statusText = result.getString("StatusText");
    if ("RUNNING".equals(statusText) || "QUEUEING".equals(statusText)) {
        // Continue polling.
        Thread.sleep(3000);
    }
    else {
        break;
    }
}
if ("SUCCESS".equals(statusText) || "SUCCESS_WITH_NO_VALID_FRAGMENT".equals(statusText)) {
    System.out.println("The audio file was transcribed successfully.");
}
else {
    System.err.println("The audio file transcription failed.");
}

Sample code

Before you call the API, configure environment variables for your access credentials. The environment variable names for the AccessKey ID, AccessKey secret, and AppKey of Intelligent Speech Interaction are ALIYUN_AK_ID, ALIYUN_AK_SECRET, and NLS_APP_KEY respectively.

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 FileTransJavaDemo {
    // The region ID. This is a constant and a static field.
    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";  // Version for the Alibaba Cloud China Website.
    // public static final String API_VERSION = "2019-08-23";  // Version for the Alibaba Cloud International Website.
    public static final String POST_REQUEST_ACTION = "SubmitTask";
    public static final String GET_REQUEST_ACTION = "GetTaskResult";
    // Request parameters.
    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";
    // Response parameters.
    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";
    // Status values.
    public static final String STATUS_SUCCESS = "SUCCESS";
    private static final String STATUS_RUNNING = "RUNNING";
    private static final String STATUS_QUEUEING = "QUEUEING";
    // The client for Alibaba Cloud authentication.
    IAcsClient client;
    public FileTransJavaDemo(String accessKeyId, String accessKeySecret) {
        // Set the endpoint.
        try {
            DefaultProfile.addEndpoint(ENDPOINTNAME, REGIONID, PRODUCT, DOMAIN);
        } catch (ClientException e) {
            e.printStackTrace();
        }
        // Create and initialize a DefaultAcsClient instance.
        DefaultProfile profile = DefaultProfile.getProfile(REGIONID, accessKeyId, accessKeySecret);
        this.client = new DefaultAcsClient(profile);
    }
    public String submitFileTransRequest(String appKey, String fileLink) {
        /**
         * 1. Create a CommonRequest and set the request parameters.
         */
        CommonRequest postRequest = new CommonRequest();
        // Set the domain name.
        postRequest.setDomain(DOMAIN);
        // Set the API version number in the YYYY-MM-DD format.
        postRequest.setVersion(API_VERSION);
        // Set the action.
        postRequest.setAction(POST_REQUEST_ACTION);
        // Set the product name.
        postRequest.setProduct(PRODUCT);
        /**
         * 2. Set the request parameters for audio file transcription. Add the parameters to the request body in a JSON string.
         */
        JSONObject taskObject = new JSONObject();
        // Set the appkey.
        taskObject.put(KEY_APP_KEY, appKey);
        // Set the URL of the audio file.
        taskObject.put(KEY_FILE_LINK, fileLink);
        // If you are a new user, use version 4.0. If you are an existing user of version 2.0 and want to continue using it, comment out this parameter.
        taskObject.put(KEY_VERSION, "4.0");
        // Specify whether to output word-level information. Default value: false. To enable this feature, you must set the version to 4.0 or later.
        taskObject.put(KEY_ENABLE_WORDS, true);
        String task = taskObject.toJSONString();
        System.out.println(task);
        // Set the preceding JSON string as the Body parameter.
        postRequest.putBodyParameter(KEY_TASK, task);
        // Set the request method to POST.
        postRequest.setMethod(MethodType.POST);
        // postRequest.setHttpContentType(FormatType.JSON);    // If the version of aliyun-java-sdk-core is 4.6.0 or later, uncomment this line.
        /**
         * 3. Submit the audio file transcription request and obtain the task ID. The ID is used to query the transcription result.
         */
        String taskId = null;
        try {
            CommonResponse postResponse = client.getCommonResponse(postRequest);
            System.err.println("Response to the audio file transcription request: " + 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. Create a CommonRequest and set the task ID.
         */
        CommonRequest getRequest = new CommonRequest();
        // Set the domain name.
        getRequest.setDomain(DOMAIN);
        // Set the API version.
        getRequest.setVersion(API_VERSION);
        // Set the action.
        getRequest.setAction(GET_REQUEST_ACTION);
        // Set the product name.
        getRequest.setProduct(PRODUCT);
        // Set the task ID as a query parameter.
        getRequest.putQueryParameter(KEY_TASK_ID, taskId);
        // Set the request method to GET.
        getRequest.setMethod(MethodType.GET);
        /**
         * 2. Submit the request to query the audio file transcription result.
         * Poll for the result until the server returns SUCCESS or an error.
         */
        String result = null;
        while (true) {
            try {
                CommonResponse getResponse = client.getCommonResponse(getRequest);
                System.err.println("Query result: " + 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)) {
                    // Continue polling. Set a proper polling interval.
                    Thread.sleep(10000);
                }
                else {
                    // If the status is SUCCESS, the transcription result is returned. If an error occurs, null is returned.
                    if (STATUS_SUCCESS.equals(statusText)) {
                        result = rootObj.getString(KEY_RESULT);
                       // If the status is SUCCESS but no transcription result is returned, the file may contain only silence or noise.
                        if(result == null) {
                            result = "";
                        }
                    }
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return result;
    }
    public static void main(String args[]) throws Exception {
        final String accessKeyId = System.getenv().get("ALIYUN_AK_ID");
        final String accessKeySecret = System.getenv().get("ALIYUN_AK_SECRET");
        final String appKey = System.getenv().get("NLS_APP_KEY");
        String fileLink = "https://gw.alipayobjects.com/os/bmw-prod/0574ee2e-f494-45a5-820f-63aee583045a.wav";
        FileTransJavaDemo demo = new FileTransJavaDemo(accessKeyId, accessKeySecret);
        // Step 1: Submit the audio file transcription request and obtain the task ID for polling the transcription result.
        String taskId = demo.submitFileTransRequest(appKey, fileLink);
        if (taskId != null) {
            System.out.println("The audio file transcription request is successful. task_id: " + taskId);
        }
        else {
            System.out.println("The audio file transcription request failed.");
            return;
        }
        // Step 2: Poll for the transcription result based on the task ID.
        String result = demo.getFileTransResult(taskId);
        if (result != null) {
            System.out.println("The transcription result was queried successfully: " + result);
        }
        else {
            System.out.println("Failed to query the transcription result.");
        }
    }
}

Note

If you use the callback method, set the enable_callback and callback_url parameters:

taskObject.put("enable_callback", true);
taskObject.put("callback_url", "Your webhook address");

Callback service example: This service is used to obtain the transcription result through a callback. Assume that the webhook address is set to http://ip:port/filetrans/callback/result.

package com.example.filetrans;

import com.alibaba.fastjson.JSONObject;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
@RequestMapping("/filetrans/callback")
@RestController
public class FiletransCallBack {
    // A status code that starts with 4 indicates a client error.
    private static final Pattern PATTERN_CLIENT_ERR = Pattern.compile("4105[0-9]*");
    // A status code that starts with 5 indicates a server-side error.
    private static final Pattern PATTERN_SERVER_ERR = Pattern.compile("5105[0-9]*");
    // The request must be a POST request.
    @RequestMapping(value = "result", method = RequestMethod.POST)
    public void GetResult(@RequestBody String body) {
        System.out.println("body: " + body);
        try {
            // Obtain the file transcription result in JSON format.
            String result = body;
            JSONObject jsonResult = JSONObject.parseObject(result);
            // Parse and print the result.
            System.out.println("Callback result of file transcription:" + result);
            System.out.println("TaskId: " + jsonResult.getString("TaskId"));
            System.out.println("StatusCode: " + jsonResult.getString("StatusCode"));
            System.out.println("StatusText: " + jsonResult.getString("StatusText"));
            Matcher matcherClient = PATTERN_CLIENT_ERR.matcher(jsonResult.getString("StatusCode"));
            Matcher matcherServer = PATTERN_SERVER_ERR.matcher(jsonResult.getString("StatusCode"));
            // A status code that starts with 2 indicates success. For callbacks, the only success code is 21050000.
            if("21050000".equals(jsonResult.getString("StatusCode"))) {
                System.out.println("RequestTime: " + jsonResult.getString("RequestTime"));
                System.out.println("SolveTime: " + jsonResult.getString("SolveTime"));
                System.out.println("BizDuration: " + jsonResult.getString("BizDuration"));
                System.out.println("Result.Sentences.size: " +
                    jsonResult.getJSONObject("Result").getJSONArray("Sentences").size());
                for (int i = 0; i < jsonResult.getJSONObject("Result").getJSONArray("Sentences").size(); i++) {
                    System.out.println("Result.Sentences[" + i + "].BeginTime: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("BeginTime"));
                    System.out.println("Result.Sentences[" + i + "].EndTime: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("EndTime"));
                    System.out.println("Result.Sentences[" + i + "].SilenceDuration: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("SilenceDuration"));
                    System.out.println("Result.Sentences[" + i + "].Text: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("Text"));
                    System.out.println("Result.Sentences[" + i + "].ChannelId: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("ChannelId"));
                    System.out.println("Result.Sentences[" + i + "].SpeechRate: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("SpeechRate"));
                    System.out.println("Result.Sentences[" + i + "].EmotionValue: " +
                        jsonResult.getJSONObject("Result").getJSONArray("Sentences").getJSONObject(i).getString("EmotionValue"));
                }
            }
            else if(matcherClient.matches()) {
                System.out.println("A status code starting with 4 indicates a client error...");
            }
            else if(matcherServer.matches()) {
                System.out.println("A status code starting with 5 indicates a server-side error...");
            }
            else {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

FAQ

How do I troubleshoot errors when I run the Java SDK demo for the audio file transcription API?

  1. Verify that the region where you activated Intelligent Speech Interaction is the same as the region specified in your code.

    Log on to the Intelligent Speech Interaction console and verify that the region selected in the top navigation bar is China (Hangzhou).

    In the sample code of the file transcription Java SDK, set the values of REGIONID and ENDPOINTNAME to cn-hangzhou, and set the value of DOMAIN to filetrans.cn-hangzhou.aliyuncs.com.

    import com.aliyuncs.IAcsClient;
    import com.aliyuncs.exceptions.ClientException;
    import com.aliyuncs.http.MethodType;
    import com.aliyuncs.profile.DefaultProfile;
    public class HelloApplicationTests {
        // Region ID, constant, fixed value. Endpoint
        public static final String REGIONID = "cn-hangzhou";
        public static final String ENDPOINTNAME = "cn-hangzhou";
        public static final String PRODUCT = "nls-filetrans";
        public static final String DOMAIN = "filetrans.cn-hangzhou.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";
        // Request parameters
        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";
        // Response parameters
        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";
        // Status values
        public static final String STATUS_SUCCESS = "SUCCESS";
        private static final String STATUS_RUNNING = "RUNNING";
  2. Verify the dependency versions of the fastjson and aliyun-java-sdk-core libraries. The core library of Alibaba Cloud SDK for Java must be version 3.5.0 or later. If you use version 4.0.0 or later, you must add the required third-party dependencies as prompted. For more information, see Java SDK for audio file transcription.

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

How do I use SDK logs to analyze latency issues?

The following examples use Java SDK logs.

  • The latency of short sentence recognition is the duration from when a sentence is spoken to when the final recognition result is received.

    Search for the keywords StopRecognition and RecognitionCompleted in the logs to find the log entries for when the audio is sent and when the recognition is complete. The time difference between these entries is the latency recorded by the SDK. In the following logs, the latency is 984 - 844 = 140 ms.

    14:24:44.844 DEBUG [           main] [c.a.n.c.transport.netty4.NettyConnection] thread:1,send:{"header":{"namespace":"SpeechRecognizer","name":"StopRecognition","message_id":"bccac69b505f4e2897d12940e5b38953","appkey":"FWpPCaVYDRp6J1rO","task_id":"8c5c28d9a40c4a229a5345c09bc9c968"}}
    14:24:44.984 DEBUG [ntLoopGroup-2-1] [  c.a.n.c.p.asr.SpeechRecognizerListener] on message:{"header":{"namespace":"SpeechRecognizer","name":"RecognitionCompleted","status":20000000,"message_id":"2869e93427b9429190206123b7a3d397","task_id":"8c5c28d9a40c4a229a5345c09bc9c968","status_text":"Gateway:SUCCESS:Success."},"payload":{"result":"The weather in Beijing.","duration":2959}}
  • For speech synthesis, focus on the time to first byte (TTFB). This is the duration from when the synthesis request is sent to when the first audio packet is received.

    Search for the keyword send in the logs to find the log entry for the request and the subsequent log entry for the received audio packet. The time difference between these entries is the TTFB recorded by the SDK. In the following logs, the latency is 1035 - 813 = 222 ms.

    14:32:13.813 DEBUG [           main] [c.a.n.c.transport.netty4.NettyConnection] thread:1,send:{"payload":{"volume":50,"voice":"Ruoxi","sample_rate":8000,"format":"wav","text":"A country is composed of four elements: territory, people, culture, and government. Country is also a term in political geography. In a broad sense, a country refers to a social group that has a common language, culture, ancestry, territory, government, or history. In a narrow sense, a country is a community formed by a group of people within a certain range."},"context":{"sdk":{"name":"nls-sdk-java","version":"2.1.0"},"network":{"upgrade_cost":160,"connect_cost":212}},"header":{"namespace":"SpeechSynthesizer","name":"StartSynthesis","message_id":"6bf2a84444434c0299974d8242380d6c","appkey":"FWpPCaVYDRp6J1rO","task_id":"affa5c90986e4378907fbf49eddd283a"}}
    14:32:14.035  INFO [ntLoopGroup-2-1] [  c.a.n.c.protocol.tts.SpeechSynthesizer] write array:6896
  • The logs for real-time speech recognition are similar to those for short sentence recognition. You can calculate the end-of-speech latency from the logs. The keywords are StopTranscription and TranscriptionCompleted.

  • For RESTful API calls, client-side logs do not record latency. You must write your own code to measure latency or check the server-side logs.