This topic describes how to use the SDK to implement the audio recognition flow for real-time recording scenarios.
Interaction flow

Prerequisites
Sample code
package com.alibaba.tingwu.client.demo.realtimemeeting;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.nls.client.protocol.NlsClient;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriber;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberListener;
import com.alibaba.nls.client.protocol.asr.SpeechTranscriberResponse;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.FileInputStream;
import java.util.Arrays;
/**
* @author tingwu2023
* @desc This demo shows how to call the real-time speech recognition service using the MeetingJoinUrl returned after creating a meeting in a real-time meeting scenario.
*/
public class RealtimeTransTest {
private static NlsClient NLS_CLIENT;
/**
* Initialize the speech recognition SDK. The SDK can be reused and used globally.
*/
@BeforeClass
public static void before() {
NLS_CLIENT = new NlsClient("default");
}
/**
* Single-channel real-time transcription. In most cases, you can refer to this implementation.
*/
@Test
public void testRealtimeTrans() throws Exception {
// The URL is the ingest URL returned when you create a meeting using OpenAPI. The URL is typically in the format: "wss://tingwu-realtime-cn-beijing.aliyuncs.com/api/ws/v1?mc={xxxxxxzzzzyyy}"
String meetingJoinUrl = "Enter the MeetingJoinUrl returned when you created the real-time meeting";
SpeechTranscriber speechTranscriber = new SpeechTranscriber(NLS_CLIENT, "default" ,createListener(), meetingJoinUrl);
speechTranscriber.start();
// Use a local file to simulate real-time audio stream collection in a real-world scenario.
String localAudioFile = "nls-sample-16k.wav";
byte[] buffer = new byte[3200];
FileInputStream fis = new FileInputStream(localAudioFile);
int len;
while ((len = fis.read(buffer)) > 0) {
// TODO: Simulate sending real-time audio data frames.
speechTranscriber.send(Arrays.copyOf(buffer, len));
// TODO: Simulate the audio collection interval.
Thread.sleep(100L);
}
// After the audio stream ends, send a stop signal to end the real-time transcription process.
// TODO: Note that the meeting has not ended. To end the meeting, see the StopRealtimeMeetingTaskTest process.
speechTranscriber.stop();
speechTranscriber.close();
}
public SpeechTranscriberListener createListener() {
return new SpeechTranscriberListener() {
@Override
public void onMessage(String message) {
System.out.println("onMessage " + message);
if (message == null || message.trim().length() == 0) {
return;
}
SpeechTranscriberResponse response = JSON.parseObject(message, SpeechTranscriberResponse.class);
if("ResultTranslated".equals(response.getName())) {
// Translation event output. You can handle the event here.
System.out.println("--- ResultTranslated ---" + JSON.toJSONString(response, SerializerFeature.PrettyFormat));
} else {
// Original speech recognition event output. The parent class handles the callback.
super.onMessage(message);
}
}
@Override
public void onTranscriberStart(SpeechTranscriberResponse response) {
// The task_id is very important. Note that this task_id identifies the real-time audio stream ingest and recognition process, not the meeting-level TaskId.
System.out.println("task_id: " + response.getTaskId() + ", name: " + response.getName() + ", status: " + response.getStatus());
}
@Override
public void onSentenceBegin(SpeechTranscriberResponse response) {
System.out.println("received onSentenceBegin: " + JSON.toJSONString(response));
}
@Override
public void onSentenceEnd(SpeechTranscriberResponse response) {
// A sentence is recognized. The server intelligently segments sentences and returns this message when the end of a sentence is detected.
System.out.println("received onSentenceEnd: " + JSON.toJSONString(response));
System.out.println("task_id: " + response.getTaskId() +
", name: " + response.getName() +
// A status code of "20000000" indicates that the recognition is successful.
", status: " + response.getStatus() +
// The sentence number, which increments from 1.
", index: " + response.getTransSentenceIndex() +
// The current recognition result.
", result: " + response.getTransSentenceText() +
// The current word-level recognition result.
", words: " + response.getWords() +
// The start time.
", begin_time: " + response.getSentenceBeginTime() +
// The duration of the processed audio in milliseconds.
", time: " + response.getTransSentenceTime());
// The current recognition result (a fixed result that will not change).
String text = response.getTransSentenceText();
// The current recognition result (unlike response.getTransSentenceText(), this result may change).
SpeechTranscriberResponse.StashResult stashResult = response.getStashResult();
// Concatenate the two recognition results above.
String stashText = stashResult == null ? "" : stashResult.getText();
System.out.println("[onSentenceEnd] text = " + text + " | stashText = " + stashText);
}
@Override
public void onTranscriptionResultChange(SpeechTranscriberResponse response) {
// An intermediate recognition result is generated. This message is returned only when OutputLevel is set to 2.
System.out.println("received onTranscriptionResultChange: " + JSON.toJSONString(response));
System.out.println("task_id: " + response.getTaskId() +
", name: " + response.getName() +
// A status code of "20000000" indicates that the recognition is successful.
", status: " + response.getStatus() +
// The sentence number, which increments from 1.
", index: " + response.getTransSentenceIndex() +
// The current recognition result.
", result: " + response.getTransSentenceText() +
// The current word-level recognition result.
", words: " + response.getWords() +
// The duration of the processed audio in milliseconds.
", time: " + response.getTransSentenceTime());
}
@Override
public void onTranscriptionComplete(SpeechTranscriberResponse response) {
// The recognition ends. This event is received after you call speechTranscriber.stop().
System.out.println("received onTranscriptionComplete: " + JSON.toJSONString(response));
}
@Override
public void onFail(SpeechTranscriberResponse response) {
// A real-time recognition error occurred. Check the error code and record this task_id for troubleshooting.
System.out.println("received onFail: " + JSON.toJSONString(response));
}
};
}
}
package main
import (
"errors"
"log"
"os"
"time"
nls "github.com/aliyun/alibabacloud-nls-go-sdk"
)
const (
TOKEN = "default"
APPKEY = "default"
)
func onTaskFailed(text string, param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("TaskFailed:", text)
}
func onStarted(text string, param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("onStarted:", text)
}
func onSentenceBegin(text string, param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("onSentenceBegin:", text)
}
func onSentenceEnd(text string, param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("onSentenceEnd:", text)
}
func onResultChanged(text string, param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("onResultChanged:", text)
}
func onCompleted(text string, param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("onCompleted:", text)
}
func onClose(param interface{}) {
logger, ok := param.(*nls.NlsLogger)
if !ok {
return
}
logger.Println("onClosed:")
}
func waitReady(ch chan bool, logger *nls.NlsLogger) error {
select {
case done := <-ch:
{
if !done {
logger.Println("Wait failed")
return errors.New("wait failed")
}
logger.Println("Wait done")
}
case <-time.After(20 * time.Second):
{
logger.Println("Wait timeout")
return errors.New("wait timeout")
}
}
return nil
}
func run_push_audio_stream(url string) {
// Use a local file in PCM or Opus format to simulate real-time audio stream collection in a real-world scenario.
pcm, err := os.Open("tingwu-sample-16k.pcm")
if err != nil {
log.Default().Fatalln(err)
}
buffers := nls.LoadPcmInChunk(pcm, 320)
param := nls.DefaultSpeechTranscriptionParam()
config := nls.NewConnectionConfigWithToken(url, APPKEY, TOKEN)
logger := nls.NewNlsLogger(os.Stderr, "1", log.LstdFlags|log.Lmicroseconds)
logger.SetLogSil(false)
logger.SetDebug(true)
st, err := nls.NewSpeechTranscription(config, logger,
onTaskFailed, onStarted,
onSentenceBegin, onSentenceEnd, onResultChanged,
onCompleted, onClose, logger)
if err != nil {
logger.Fatalln(err)
return
}
logger.Println("Start pushing audio stream")
ready, err := st.Start(param, nil)
if err != nil {
logger.Fatalln(err)
return
}
err = waitReady(ready, logger)
if err != nil {
logger.Fatalln(err)
return
}
for _, data := range buffers.Data {
if data != nil {
st.SendAudioData(data.Data)
time.Sleep(10 * time.Millisecond)
}
}
ready, err = st.Stop()
if err != nil {
logger.Fatalln(err)
return
}
err = waitReady(ready, logger)
if err != nil {
logger.Fatalln(err)
return
}
st.Shutdown()
logger.Println("Push audio stream done")
}
func main() {
// The URL is the ingest URL returned when you create a recording using OpenAPI.
run_push_audio_stream("wss://tingwu-realtime-cn-hangzhou-pre.aliyuncs.com/api/ws/v1?mc=*********h-moSNWGZO5mq-uZzu1EQbVBABVn9y8VGzWmVcAEiLNE1idoml7JU_wr17G4dDdxwQ6jiMg8OCQCrptlCnSk4hJ9K_fVfP8ngWaYk2If*********")
}
#include <fstream>
#include <string>
#include <mutex>
#include <condition_variable>
#include <thread>
#include <chrono>
#include "nlsClient.h"
#include "nlsEvent.h"
#include "speechTranscriberRequest.h"
// Implement a simple semaphore for event synchronization. In your actual project, you can replace this with your project's semaphore implementation.
class Semaphore {
public:
Semaphore(int count = 0) : count_(count) {
}
void notify() {
std::unique_lock<std::mutex> lock(mtx_);
++count_;
cv_.notify_one();
}
void wait() {
std::unique_lock<std::mutex> lock(mtx_);
cv_.wait(lock, [this](){ return count_ > 0; });
--count_;
}
// Wait with timeout
bool wait_for(const std::chrono::milliseconds& timeout) {
std::unique_lock<std::mutex> lock(mtx_);
if (!cv_.wait_for(lock, timeout, [this](){ return count_ > 0; })) {
return false; // Timeout occurred
}
--count_;
return true;
}
private:
std::mutex mtx_;
std::condition_variable cv_;
int count_;
};
Semaphore kSemaphore(0);
// All information returned by the server is sent through this callback.
// cbEvent: The callback event structure. For more information, see nlsEvent.h.
// cbParam: A custom callback parameter. The default value is NULL. You can customize this parameter as needed.
void onMessage(AlibabaNls::NlsEvent *cbEvent, void *cbParam) {
printf("onMessage: [%s]\n", cbEvent->getAllResponse());
int result = cbEvent->parseJsonMsg(true);
if (result) {
printf("onMessage: parseJsonMsg failed: [%d]", result);
return;
}
switch (cbEvent->getMsgType()) {
case AlibabaNls::NlsEvent::TaskFailed:
// If an exception occurs during the recognition process (including start(), sendAudio(), and stop()), the SDK's internal thread reports a TaskFailed event.
// After a TaskFailed event is reported, the SDK closes the recognition connection channel. Calling sendAudio will then return a negative value. Stop sending audio.
printf("onTaskFailed: status code=%d, task id=%s, error message=%s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId(),
cbEvent->getErrorMessage());
break;
case AlibabaNls::NlsEvent::TranscriptionStarted:
// After you call start(), a connection is successfully established with the cloud, and the SDK's internal thread reports a started event.
// Notify the sending thread that start() was successful and that data can be sent.
kSemaphore.notify();
break;
case AlibabaNls::NlsEvent::SentenceBegin:
printf("##### %d, %d\n", cbEvent->getMsgType(), AlibabaNls::NlsEvent::SentenceBegin),
// The server detects the beginning of a sentence, and the SDK's internal thread reports a SentenceBegin event.
printf("onSentenceBegin: status code=%d, task id=%s, index=%d, time=%d\n",
cbEvent->getStatusCode(), cbEvent->getTaskId(),
cbEvent->getSentenceIndex(), // The sentence number, which increments from 1.
cbEvent->getSentenceTime()); // The duration of the processed audio in milliseconds.
break;
case AlibabaNls::NlsEvent::TranscriptionResultChanged:
// The recognition result has changed. When the SDK receives the latest result from the cloud,
printf("onTranscriptionResultChanged: status code=%d, task id=%s, index=%d, time=%d, result=%s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId(),
cbEvent->getSentenceIndex(), // The sentence number, which increments from 1.
cbEvent->getSentenceTime(), // The duration of the processed audio in milliseconds.
cbEvent->getResult()); // The complete recognition result for the current sentence.
break;
case AlibabaNls::NlsEvent::SentenceEnd:
// The server detects the end of a sentence, and the SDK's internal thread reports a SentenceEnd event.
printf("onSentenceEnd: status code=%d, task id=%s, index=%d, time=%d, begin_time=%d, result=%s | %s\n",
cbEvent->getStatusCode(),
cbEvent->getTaskId(),
cbEvent->getSentenceIndex(), // The sentence number, which increments from 1.
cbEvent->getSentenceTime(), // The duration of the processed audio in milliseconds.
cbEvent->getSentenceBeginTime(), // The time of the corresponding SentenceBegin event.
cbEvent->getResult(), cbEvent->getStashResultText()); // The complete recognition result for the current sentence. Note that you also need to concatenate the stashResultText.
break;
case AlibabaNls::NlsEvent::TranscriptionCompleted:
// When the server stops real-time audio stream recognition, the SDK's internal thread reports a Completed event.
kSemaphore.notify();
break;
case AlibabaNls::NlsEvent::Close:
// When recognition ends or an exception occurs, the connection channel is closed, and the SDK's internal thread reports a ChannelClosed event.
// Notify the sending thread that the final recognition result has been returned and that stop() can be called.
break;
default:
// Other possible events. For example, if you enable the translation feature, the translation result message is returned here for you to handle.
printf("---otherEvent---\n");
break;
}
}
int main( int argc, char** argv ) {
// The URL is the ingest URL returned when you create a meeting using OpenAPI. The URL is typically in the format: "wss://tingwu-realtime-cn-beijing.aliyuncs.com/api/ws/v1?mc={xxxxxxzzzzyyy}"
const char* websocketUrl = "Enter the MeetingJoinUrl returned when you created the real-time meeting";
const char* localAudioPath = "nls-sample-16k.wav"; // The path to the local audio file for testing. This audio is short, so you may not be able to test the related summary results.
// Set the SDK output log as needed. This is optional.
AlibabaNls::NlsClient::getInstance()->setLogConfig("log-transcriber", AlibabaNls::LogDebug, 400, 50);
// Start the worker threads. You must call this function before creating and starting a request. This can be considered the initialization of NlsClient. If the input parameter is negative, the number of available cores in the current system is used.
AlibabaNls::NlsClient::getInstance()->startWorkThread(1);
// Create a SpeechTranscriberRequest object for real-time audio stream recognition.
AlibabaNls::SpeechTranscriberRequest* request = AlibabaNls::NlsClient::getInstance()->createTranscriberRequest();
request->setUrl(websocketUrl);
// Set the callback function for all information returned by the server.
request->setOnMessage(onMessage, NULL);
request->setEnableOnMessage(true);
int ret = request->start();
if(ret < 0) {
printf("start fail, error: [%d]", ret);
AlibabaNls::NlsClient::getInstance()->releaseTranscriberRequest(request);
return 0;
} else {
// Wait for start() to return synchronously before sending more audio data.
if (kSemaphore.wait_for(std::chrono::milliseconds(10000))) {
printf("start success\n");
} else {
printf("start timeout\n");
return -1;
}
}
std::ifstream fs;
fs.open(localAudioPath, std::ios::binary | std::ios::in);
while (!fs.eof()) {
const int FRAME_SIZE = 3200;
uint8_t data[FRAME_SIZE] = {0};
fs.read((char *) data, sizeof(uint8_t) * FRAME_SIZE);
size_t nlen = fs.gcount();
// Send audio data: sendAudio is an asynchronous operation. A negative return value indicates a failure, and you must stop sending. A value greater than 0 indicates success.
ret = request->sendAudio(data, nlen);
if (ret < 0) {
// Send failed. Exit the data sending loop.
printf("send data fail, ret: %d.\n", ret);
break;
}
// For audio with a 16 kHz sample rate, 3200 bytes is about 100 ms of data. For 8 kHz audio, 1600 bytes is about 100 ms of data.
// In actual use, audio data is real-time. You do not need to use sleep to control the rate. You can send it directly. Here, we use audio data from a file for simulation, so we need to control the rate to simulate a real recording scenario.
std::this_thread::sleep_for(std::chrono::milliseconds(200));
} // while
fs.close();
request->stop();
// Wait for the server to return the final data and end the recognition.
kSemaphore.wait_for(std::chrono::milliseconds(10000));
AlibabaNls::NlsClient::getInstance()->releaseTranscriberRequest(request);
// After all tasks are complete, release nlsClient before the process exits.
AlibabaNls::NlsClient::releaseInstance();
}import time
import threading
import sys
import nls
class TestRealtimeMeeting:
def __init__(self, tid, test_file, url):
self.__th = threading.Thread(target=self.__test_run)
self.__id = tid
self.__test_file = test_file
self.__url = url
def loadfile(self, filename):
with open(filename, "rb") as f:
self.__data = f.read()
def start(self):
self.loadfile(self.__test_file)
self.__th.start()
def test_on_sentence_begin(self, message, *args):
print("test_on_sentence_begin:{}".format(message))
def test_on_sentence_end(self, message, *args):
print("test_on_sentence_end:{}".format(message))
def test_on_start(self, message, *args):
print("test_on_start:{}".format(message))
def test_on_error(self, message, *args):
print("on_error message=>{} args=>{}".format(message, args))
def test_on_close(self, *args):
print("on_close: args=>{}".format(args))
def test_on_result_chg(self, message, *args):
print("test_on_chg:{}".format(message))
def test_on_result_translated(self, message, *args):
print("test_on_translated:{}".format(message))
def test_on_completed(self, message, *args):
print("on_completed:args=>{} message=>{}".format(args, message))
def __test_run(self):
print("thread:{} start..".format(self.__id))
rm = nls.NlsRealtimeMeeting(
url=self.__url,
on_sentence_begin=self.test_on_sentence_begin,
on_sentence_end=self.test_on_sentence_end,
on_start=self.test_on_start,
on_result_changed=self.test_on_result_chg,
on_result_translated=self.test_on_result_translated,
on_completed=self.test_on_completed,
on_error=self.test_on_error,
on_close=self.test_on_close,
callback_args=[self.__id]
)
print("{}: session start".format(self.__id))
r = rm.start()
self.__slices = zip(*(iter(self.__data),) * 640)
for i in self.__slices:
rm.send_audio(bytes(i))
time.sleep(0.01)
time.sleep(1)
r = rm.stop()
print("{}: rm stopped:{}".format(self.__id, r))
time.sleep(5)
def multiruntest(num=1):
for i in range(0, num):
name = "thread" + str(i)
t = TestRealtimeMeeting(name, "nls-sample-16k.wav",
"Enter the MeetingJoinUrl returned when you created the real-time meeting")
t.start()
nls.enableTrace(False)
multiruntest(1)
Real-time audio stream ingest for recordings
Stream ingest procedure
1. Establish an ingest channel. This corresponds to step 1 in the interaction flow.
2. Push audio for recognition. This corresponds to pushing the audio stream in step 2 of the interaction flow.
3. Receive recognition results. This corresponds to obtaining the returned event results in step 2 of the interaction flow. The client sends audio data in a loop and continuously receives recognition results:
Sentence begin event (SentenceBegin)
A sentence begin event indicates that the server has detected the beginning of a sentence. The intelligent sentence segmentation feature of the Tingwu service determines the beginning and end of a sentence. The following is an example.
{
"header":{
"namespace":"SpeechTranscriber",
"name":"SentenceBegin",
"status":20000000,
"message_id":"a426f3d4618447519c9d85d1a0d1****",
"task_id":"5ec521b5aa104e3abccf3d361822****",
"status_text":"Gateway:SUCCESS:Success."
},
"payload":{
"index":0,
"time":0
}
}Parameter description:
Parameter | Type | Description |
header | object | The header information of the returned result. |
namespace | string | The namespace to which the message belongs. The value is fixed to SpeechTranscriber. |
name | string | The name of the message. SentenceBegin indicates the beginning of a sentence. |
task_id | string | The globally unique ID (GUID) of the stream ingest task. Record this value for troubleshooting. |
message_id | string | The ID of this message. |
status | int | The status code. It indicates whether the request was successful. For more information, see Common error codes. |
status_text | string | The status message. |
payload | object | The returned result. |
index | int | The sentence number, which increments from 0. |
time | int | The duration of the processed audio in milliseconds. |
speaker_id | string | The speaker corresponding to the recognition result. This is not returned for single-channel or mixed-stream recognition. |
In-sentence recognition result changed event (TranscriptionResultChanged)
An in-sentence recognition result changed event indicates that the recognition result has changed. The following is an example.
{
"header":{
"namespace":"SpeechTranscriber",
"name":"TranscriptionResultChanged",
"status":20000000,
"message_id":"dc21193fada84380a3b6137875ab****",
"task_id":"5ec521b5aa104e3abccf3d361822****",
"status_text":"Gateway:SUCCESS:Success."
},
"payload":{
"index":0,
"time":1835,
"result":"Beijing's sky",
"words":[
{
"text":"Beijing",
"startTime":630,
"endTime":930
},
{
"text":"'s",
"startTime":930,
"endTime":1110
},
{
"text":"sky",
"startTime":1110,
"endTime":1140
}
]
}
}Parameter description:
Parameter | Type | Description |
header | object | The header information of the returned result. |
namespace | string | The namespace to which the message belongs. The value is fixed to SpeechTranscriber. |
name | string | The name of the message. TranscriptionResultChanged indicates a change in the in-sentence recognition result. |
task_id | string | The GUID of the stream ingest task. Record this value for troubleshooting. |
message_id | string | The ID of this message. |
status | int | The status code. It indicates whether the request was successful. For more information, see Common error codes. |
status_text | string | The status message. |
payload | object | The returned result. |
index | int | The sentence number, which increments from 0. |
time | int | The duration of the processed audio in milliseconds. |
result | string | The recognition result for the current sentence. |
words | list[] | The word information for the current sentence. |
text | string | The text. |
startTime | int | The start time of the word in milliseconds. |
endTime | int | The end time of the word in milliseconds. |
speaker_id | string | The speaker corresponding to the recognition result. This is not returned for single-channel or mixed-stream recognition. |
Sentence end event (SentenceEnd)
A sentence end event indicates that the server has detected the end of a sentence, and returns the recognition result for that sentence. The following is an example.
{
"header":{
"namespace":"SpeechTranscriber",
"name":"SentenceEnd",
"status":20000000,
"message_id":"c3a9ae4b231649d5ae05d4af36fd****",
"task_id":"5ec521b5aa104e3abccf3d361822****",
"status_text":"Gateway:SUCCESS:Success."
},
"payload":{
"index":0,
"time":1835,
"result":"The weather in Beijing",
"words":[
{
"text":"The weather",
"startTime":630,
"endTime":930
},
{
"text":"in",
"startTime":930,
"endTime":1110
},
{
"text":"Beijing",
"startTime":1110,
"endTime":1140
}
],
"stash_result": {
"index": 1,
"currentTime": 1140,
"words": [
{
"startTime": 1150,
"text": "will",
"endTime": 1190
},
{
"startTime": 1190,
"text": "rain",
"endTime": 1320
}
],
"beginTime": 1140,
"text": "will rain"
}
}
}Parameter descriptions:
Parameter | Type | Description |
header | object | The header information of the returned result. |
namespace | string | The namespace to which the message belongs. The value is fixed to SpeechTranscriber. |
name | string | The name of the message. SentenceEnd indicates the end of a sentence. |
task_id | string | The GUID of the stream ingest task. Record this value for troubleshooting. |
message_id | string | The ID of this message. |
status | int | The status code. It indicates whether the request was successful. For more information, see Common error codes. |
status_text | string | The status message. |
payload | object | The returned result. |
index | int | The sentence number, which increments from 0. |
time | int | The duration of the processed audio in milliseconds. |
result | string | The recognition result for the current sentence. |
words | list[] | The word information for the current sentence. |
text | string | The text. |
startTime | int | The start time of the word in milliseconds. |
endTime | int | The end time of the word in milliseconds. |
speaker_id | string | The speaker corresponding to the recognition result. This is not returned for single-channel or mixed-stream recognition. |
stash_result | object | The staging result of speech recognition. This is the information for the next sentence that has not yet been segmented. You need to concatenate the stash_result with the text result above for subsequent processing. |
stash_result.index | int | The sentence number of the stash result. |
stash_result.text | string | The Automatic Speech Recognition (ASR) text of the stash result. |
stash_result.words | list[] | The word information of the stash result. |
Translated recognition result event (ResultTranslated)
When translation is enabled, a recognition result translation event indicates that the server has detected a recognition result and translated it into the target language. The following is an example.
{
"header":{
"namespace":"SpeechTranscriber",
"name":"ResultTranslated",
"status":20000000,
"message_id":"c3a9ae4b231649d5ae05d4af36fd****",
"task_id":"5ec521b5aa104e3abccf3d361822****",
"status_text":"Gateway:SUCCESS:Success.",
"source_message_id":"d4a9ae4b231649d5ae05d4af36fd****"
},
"payload":{
"speaker_id":"xxx",
"source_lang":"cn",
"target_lang":"en",
"translate_result":[
{
"text":"At that time.",
"index":110,
"beginTime":123000,
"endTime":125000
},
{
"text":"xxx",
"index":111,
"partial":true
}
]
}
}Parameter descriptions:
Parameter | Type | Description |
header | object | The header information of the returned result. |
namespace | string | The namespace to which the message belongs. The value is fixed to SpeechTranscriber. |
name | string | The name of the message. ResultTranslated indicates a recognition result translation. |
task_id | string | The GUID of the stream ingest task. Record this value for troubleshooting. |
message_id | string | The ID of this message. |
source_message_id | string | The message ID of the source recognition result for this translation. |
status | int | The status code. It indicates whether the request was successful. For more information, see Common error codes. |
status_text | string | The status message. |
payload | object | The returned result. |
speaker_id | string | The speaker ID corresponding to the recognition result, which is the same as the one passed in the stream ingest protobuf. If this field is not present, it indicates a translation for single-channel or mixed-stream recognition. |
source_lang | string | The source language for the translation. |
target_lang | string | The target language for the translation. |
translate_result | list[] | The translation information for the recognition result. |
text | string | The translated text. |
index | int | The translated sentence number, which increments from 0. |
partial | boolean | If true, this corresponds to the translation result for recognition content that is not from a SentenceEnd event. |
beginTime | int | The start time of the translated sentence in milliseconds. This is returned when translating a SentenceEnd recognition result. |
endTime | int | The end time of the translated sentence in milliseconds. This is returned when translating a SentenceEnd recognition result. |
4. Pause stream ingest and recognition, which corresponds to step 3 in the interaction flow.
Recognition completed event
Parameter | Type | Description |
header | object | The header information of the returned result. |
namespace | string | The namespace to which the message belongs. The value is fixed to SpeechTranscriber. |
name | string | The name of the message. TranscriptionCompleted indicates that the current stream ingest and recognition task is complete. TaskFailed indicates that the task was interrupted by an exception. |
task_id | string | The GUID of the stream ingest task. Record this value for troubleshooting. |
message_id | string | The ID of this message. |
status | int | The status code. It indicates whether the request was successful. For more information, see Common error codes. |
status_text | string | The status message. |
payload | object | The returned result. |
5. (Optional) To resume stream ingest and recognition, repeat the interaction flow described in this topic.