Java demo

更新时间:
复制 MD 格式

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

Prerequisites

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

  • Activate Intelligent Speech Interaction and obtain an AccessKey ID and an AccessKey secret. For more information, see Get started.

SDK description

The Java example for audio file transcription uses the CommonRequest class of the Alibaba Cloud SDK for Java to submit transcription requests and query results. This process uses RPC-style POP API calls. For more information about how to use the CommonRequest class of the Alibaba Cloud SDK for Java, see Use CommonRequest to make an API call.

Important

The Alibaba Cloud SDK for Java does not support Android development.

Java dependencies

This example depends on the core library of the Alibaba Cloud SDK for Java and the open source library fastjson. The core library 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 based on the error messages.

<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>

Example description

  • Download nls-sample-16k.wav. The WAV audio file used in this example has a PCM encoding format, a 16000 Hz sample rate, and uses the general-purpose model.

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

Authentication

Pass the AccessKey ID and AccessKey secret of your Alibaba Cloud account to the Alibaba Cloud SDK for Java to create a client. For more information about how to obtain an AccessKey pair, 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");
/**
 * Region ID
 */
final String regionId = "cn-shanghai";
final String endpointName = "cn-shanghai";
final String product = "SpeechFileTranscriberLite";
final String domain = "speechfiletranscriberlite.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 an audio file transcription request

The Java example uses polling. It submits an audio file transcription request and obtains a task ID for subsequent polling.

Note

For more information about parameter settings, see API reference. Set only the parameters in the JSON string and keep the parameter values of other methods unchanged.

/**
 * Create a CommonRequest and set request parameters.
 */
CommonRequest postRequest = new CommonRequest();
postRequest.setDomain("speechfiletranscriberlite.cn-shanghai.aliyuncs.com"); // Set the domain name. This is a static field.
postRequest.setVersion("2021-12-21");         // Set the API version number. This is a static field.
postRequest.setAction("SubmitTask");          // Set the action. This is a static field.
postRequest.setProduct("SpeechFileTranscriberLite");      // Set the product name. This is a static field.
// Set the audio file transcription request parameters in the request body in JSON string format.
JSONObject taskObject = new JSONObject();
taskObject.put("appkey", "Your AppKey");    // The AppKey of your project. To get an AppKey, go to the console: https://nls-portal.console.aliyun.com/applist
taskObject.put("file_link", "The access URL of your audio file");  // Set the link to the audio file.
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 aliyun-java-sdk-core version is 4.6.0 or later, uncomment this line.
/**
 * Submit the audio file transcription request.
 */
String taskId = "";   // Get the task ID of the audio file transcription request for querying the 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("Audio file transcription request successful. Response: " + result.toJSONString());
        taskId = result.getString("TaskId");
    }
    else {
        System.out.println("Audio file transcription request failed: " + result.toJSONString());
        return;
    }
}
else {
    System.err.println("Audio file transcription request failed. HTTP error code: " + postResponse.getHttpStatus());
    System.err.println("Audio file transcription request failed. Response: " + JSONObject.toJSONString(postResponse));
    return;
}

Query the audio file transcription result

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

/**
 * Create a CommonRequest and set the task ID.
 */
CommonRequest getRequest = new CommonRequest();
getRequest.setDomain("speechfiletranscriberlite.cn-shanghai.aliyuncs.com");   // Set the domain name. This is a static field.
getRequest.setVersion("2021-12-21");             // Set the API version. This is a static field.
getRequest.setAction("GetTaskResult");           // Set the action. This is a static field.
getRequest.setProduct("SpeechFileTranscriberLite");          // 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 transcription result.
 * Query the transcription result by polling until the server returns a status of "SUCCESS", "SUCCESS_WITH_NO_VALID_FRAGMENT", or an error. Then, stop polling.
 */
String statusText = "";
while (true) {
    CommonResponse getResponse = client.getCommonResponse(getRequest);
    if (getResponse.getHttpStatus() != 200) {
        System.err.println("Failed to query the transcription result. HTTP error code: " + getResponse.getHttpStatus());
        System.err.println("Failed to query the transcription result: " + getResponse.getData());
        break;
    }
    JSONObject result = JSONObject.parseObject(getResponse.getData());
    System.out.println("Transcription 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("Audio file transcription successful!");
}
else {
    System.err.println("Audio file transcription failed!");
}

Sample code

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

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 {
    // 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 = "SpeechFileTranscriberLite";
    public static final String DOMAIN = "speechfiletranscriberlite.cn-shanghai.aliyuncs.com";
    public static final String API_VERSION = "2021-12-21";
    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";
    // Alibaba Cloud authentication client
    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 audio file transcription request parameters in the request body in JSON string format.
         */
        JSONObject taskObject = new JSONObject();
        // Set the appkey.
        taskObject.put(KEY_APP_KEY, appKey);
        // Set the audio file access link.
        taskObject.put(KEY_FILE_LINK, fileLink);
        // Specify whether to output word-level information. Default value: false.
        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 aliyun-java-sdk-core version is 4.6.0 or later, uncomment this line.  
        /**
         * 3. Submit the audio file transcription request to get the task ID. You can use the task ID 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 transcription result.
         * Query the transcription result by polling until the server returns a status of "SUCCESS" or an error. Then, stop polling.
         */
        String result = null;
        while (true) {
            try {
                CommonResponse getResponse = client.getCommonResponse(getRequest);
                System.err.println("Transcription 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. Note the polling interval.
                    Thread.sleep(10000);
                }
                else {
                    // If the status is success, the transcription result is returned. If the status is abnormal, empty is returned.
                    if (STATUS_SUCCESS.equals(statusText)) {
                        result = rootObj.getString(KEY_RESULT);
                       // If the status is success but no transcription result is returned, the audio 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 an audio file transcription request to get a task ID for polling the transcription result.
        String taskId = demo.submitFileTransRequest(appKey, fileLink);
        if (taskId != null) {
            System.out.println("Audio file transcription request successful, task_id: " + taskId);
        }
        else {
            System.out.println("Audio file transcription request failed!");
            return;
        }
        // Step 2: Poll the transcription result based on the task ID.
        String result = demo.getFileTransResult(taskId);
        if (result != null) {
            System.out.println("Successfully queried the audio file transcription result: " + result);
        }
        else {
            System.out.println("Failed to query the audio file transcription result!");
        }
    }
}

Note

If you use the callback method, set the following 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 retrieve 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]*");
    // Must be a POST request.
    @RequestMapping(value = "result", method = RequestMethod.POST)
    public void GetResult(@RequestBody String body) {
        System.out.println("body: " + body);
        try {
            // Get the file transcription result in JSON format.
            String result = body;
            JSONObject jsonResult = JSONObject.parseObject(result);
            // Parse and output the result content.
            System.out.println("Get the transcription callback result from the file:" + 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 is a normal status code. For the callback method, the normal status 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 that starts with 4 indicates a client error...");
            }
            else if(matcherServer.matches()) {
                System.out.println("A status code that starts with 5 indicates a server-side error...");
            }
            else {
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

FAQ

How to analyze latency issues using SDK logs?

The following examples use Java SDK logs.

  • The latency of one-sentence recognition is the time from when a sentence is spoken to when the final recognition result is received.

    In the logs, search for the keywords StopRecognition and RecognitionCompleted to find the log entries for when the audio is sent and when the one-sentence recognition is complete. The time difference is the latency that is 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":"Weather in Beijing.","duration":2959}}
  • For speech synthesis, focus on the first-packet latency. This is the time from when the synthesis request is sent to when the first audio packet is received.

    In the logs, search for the keyword send to find the log entry and the subsequent log entry for receiving the audio packet. The time difference is the first-packet latency that is 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. The term 'country' is also a term in political geography. In a broad sense, a country refers to a social group that shares 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 real-time speech recognition SDK logs are similar to those for one-sentence recognition. You can calculate the end-of-speech latency from the logs. The keywords are StopTranscription and TranscriptionCompleted.

  • For RESTful API access, the latency is not shown in the client-side logs. You must write your own code or view the server-side logs.

The Java SDK cannot find the com.alibaba JAR package. How do I install Alibaba Cloud SDK for Java?

For more information about how to install the Alibaba Cloud SDK for Java, see V1.0 Java SDK.

When I use the Java SDK to create a client by passing the AccessKey ID and AccessKey secret, the error `org.json.JSONArray.iterator()Ljava/util/Iterator` is reported. How do I fix it?

Ensure that all dependency packages are included. Find and add the following two dependency JAR packages.

<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20170516</version>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>