文档

接口与实现

更新时间:
一键部署

本文主要介绍实时记录接入流程。

说明

如果您需要咨询更多产品技术问题,欢迎搜索钉钉群号44604776,加入通义听悟咨询群联系我们。

使用须知

  • 支持的输入格式:PCM(无压缩的PCM或WAV文件)、OPUS、SPEEX、MP3、AAC格式,16 bit采样位数、单声道(mono)。

  • 支持的音频采样率:16000 Hz、8000Hz。

  • 支持的单次记录时长:24小时。

  • 支持设置返回结果:是否返回中间识别结果。

  • 支持设置多语言识别:中文、英文、粤语、日语、中英自由说(长段中英混)。

  • 支持设置开启翻译:翻译目标语言为中文、英文、中文&英文,支持会中开启或关闭。

  • 支持设置同步音频转码:转码为比特率128kb/s的mp3格式音频,准实时写入的指定OSS。

  • 支持设置会后纪要智能提取:智能提取关键词、关键句、小议题、待办事项。

交互流程

image.png

接入步骤

步骤1:调用CreateTask接口创建实时记录,对应交互流程1-2。

说明

转写的管理粒度为记录,在完成记录创建后便可基于该记录体验会中实时记录语音推流转写。

步骤2:实时记录语音推流,在完成记录创建后,便可通过听悟提供的实时推流进行会中实时语音推流并接收识别结果,对应交互流程3-17。

步骤3:调用GetTaskInfo接口查询实时记录状态,对应交互流程18-19。

步骤4:调用CreateTask接口结束实时记录,对应交互流程20-22。

说明

结束记录后会进行智能纪要提取,并在完成时进行结果通知

前提条件

AccessKey环境变量设置

需要使用您的AccessKey的Id和secret替换如下命令中的YOUR_ACCESS_KEY_ID和YOUR_ACCESS_KEY_SECRET。

export ALIBABA_CLOUD_ACCESS_KEY_ID=YOUR_ACCESS_KEY_ID &&
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=YOUR_ACCESS_KEY_SECRET

创建实时记录

参考如下内容创建一个实时记录任务,之后根据获取到的记录推流url,建立websocket链接,实时推流并进行识别。

请求参数

功能名称

参数

类型

默认值

说明

AppKey

AppKey

string

-

必选,请设置为您在管控台上创建的appkey。

基本请求信息

(Input)

Input.Format

string

-

必选,实时推送二进制音频流时对应的音频格式,支持pcm、opus、aac、speex、mp3。

Input.SampleRate

int

-

必选,实时推送二进制音频流时对应的采样率,支持16000和8000;一般来说大部分记录场景都是16000。

Input.SourceLanguage

string

-

必选,音视频文件对应的语言种类;支持cn(中文)、en(英文)、粤语(yue)、fspk(中英文)、日语(ja)、韩语(ko)。

Input.TaskKey

string

null

用户自行设置的自定义标识。

转码

(Transcoding)

Transcoding.TargetAudioFormat

string

null

当前只支持设置mp3转换,默认不开启。

语音识别

(Transcription)

Transcription.OutputLevel

int

1

设置语音识别结果返回等级。

  • 1:识别出完整句子时返回识别结果

  • 2:识别出中间结果及完整句子时返回识别结果

仅在实时记录场景下按需设置,离线转写场景无须设置。

Transcription.DiarizationEnabled

boolean

false

是否在语音识别过程中开启说话人分离功能。

Transcription.Diarization.SpeakerCount

int

-

开启说话人分离功能时,设置的说话人数。

  • 不设置:不使用说话人角色区分

  • 0:说话人角色区分结果为不定人数

  • 2:说话人角色区分结果为2人

当有此参数时,使用此参数辅助指定的人数。最终分轨人数以真实分类人数为准。

Transcription.PhraseId

String

-

热词词表ID。

翻译

(Translation)

TranslationEnabled

boolean

false

是否开启翻译功能。

Translation.OutputLevel

int

1

设置实时语言翻译识别结果返回等级。

  • 1:识别出完整句子时返回识别结果;

  • 2:识别出中间结果及完整句子时返回识别结果

仅在实时记录场景下按需设置,离线转写场景无须设置。

Translation.TargetLanguages

list[string]

-

如果开启翻译,需要设置目标翻译语言。支持设置中(cn)英(en)、中(cn)日(ja)、中(cn)韩(ko)的双向互译。

章节速览

AutoChaptersEnabled

boolean

false

章节速览功能,包括:议程标题和议程摘要

智能纪要

MeetingAssistanceEnabled

boolean

false

关键词、行动项、待办、场景识别

摘要

SummarizationEnabled

boolean

false

是否开启摘要功能。

Summarization.Types

list[string]

-

如果开启摘要功能,需要设置摘要类型。支持设置1个或多个。

  • Paragraph(全文摘要)

  • Conversational(发言总结)

  • QuestionsAnswering(问答回顾、要点回顾)

口语书面化

TextPolishEnabled

boolean

false

是否开启口语书面化功能。

代码示例

package com.alibaba.tingwu.client.demo.realtimemeeting;

import com.alibaba.fastjson.JSONArray;
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.FormatType;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import org.junit.Test;

/**
 * @author tingwu2023
 * @desc 演示了通过OpenAPI 创建实时记录的调用方式。
 */
public class SubmitRealtimeMeetingTaskTest {

    @Test
    public void testSummitRealtimeMeetingTask() throws ClientException {
        CommonRequest request = createCommonRequest("tingwu.cn-beijing.aliyuncs.com", "2023-09-30", ProtocolType.HTTPS, MethodType.PUT, "/openapi/tingwu/v2/tasks");
        request.putQueryParameter("type", "realtime");

        JSONObject root = new JSONObject();
        root.put("AppKey", "输入您在听悟管控台创建的Appkey");

        JSONObject input = new JSONObject();
        input.fluentPut("SourceLanguage", "cn").fluentPut("Format", "pcm").fluentPut("SampleRate", 16000).fluentPut("TaskKey", "task" + System.currentTimeMillis());
        root.put("Input", input);

        JSONObject parameters = initRequestParameters();
        root.put("Parameters", parameters);

        System.out.println(root.toJSONString());
        request.setHttpContent(root.toJSONString().getBytes(), "utf-8", FormatType.JSON);

        // TODO 请通过环境变量设置您的AccessKeyId、AccessKeySecret
        DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        IAcsClient client = new DefaultAcsClient(profile);
        CommonResponse response = client.getCommonResponse(request);
        System.out.println(response.getData());
        JSONObject body = JSONObject.parseObject(response.getData());
        JSONObject data = (JSONObject) body.get("Data");
        System.out.println("TaskId = " + data.getString("TaskId"));
        System.out.println("MeetingJoinUrl = " + data.getString("MeetingJoinUrl"));
    }

    private static JSONObject initRequestParameters() {
        JSONObject parameters = new JSONObject();

        // 音视频转换: 可选
        JSONObject transcoding = new JSONObject();
        //transcoding.put("TargetAudioFormat", "mp3");
        //transcoding.put("SpectrumEnabled", false);
        parameters.put("Transcoding", transcoding);

        // 语音识别
        JSONObject transcription = new JSONObject();
        transcription.put("DiarizationEnabled", true);
        JSONObject speakerCount = new JSONObject();
        speakerCount.put("SpeakerCount", 2);
        transcription.put("Diarization", speakerCount);
        parameters.put("Transcription", transcription);

        // 翻译: 可选
        JSONObject translation = new JSONObject();
        JSONArray langArry = new JSONArray();
        langArry.add("en");
        translation.put("TargetLanguages", langArry);
        parameters.put("Translation", translation);
        parameters.put("TranslationEnabled", true);

        // 章节速览: 可选
        parameters.put("AutoChaptersEnabled", false);

        // 智能纪要: 可选
        parameters.put("MeetingAssistanceEnabled", false);

        // 摘要相关: 可选
        parameters.put("SummarizationEnabled", true);
        JSONObject summarization = new JSONObject();
        JSONArray types = new JSONArray().fluentAdd("Paragraph").fluentAdd("Conversational").fluentAdd("QuestionsAnswering");
        summarization.put("Types", types);
        parameters.put("Summarization", summarization);

        // PPT抽取: 不可选,实时记录没有视频信息,无法进行ppt功能
        // parameters.put("PptExtractionEnabled", false);
      	
	      // 口语书面化:可选
        parameters.put("TextPolishEnabled", false);

        return parameters;
    }
    public static CommonRequest createCommonRequest(String domain, String version, ProtocolType protocolType, MethodType method, String uri) {
        CommonRequest request = new CommonRequest();
        request.setSysDomain(domain);
        request.setSysVersion(version);
        request.setSysProtocol(protocolType);
        request.setSysMethod(method);
        request.setSysUriPattern(uri);
        request.setHttpContentType(FormatType.JSON);
        return request;
    }
}
package main

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

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

type TranscodeingParam struct {
	TargetAudioFormat     string `json:"TargetAudioFormat,omitempty"`
	TargetVideoFormat     string `json:"TargetVideoFormat,omitempty"`
	VideoThumbnailEnabled bool   `json:"VideoThumbnailEnabled,omitempty"`
	SpectrumEnabled       bool   `json:"SpectrumEnabled,omitempty"`
}

type DiarizationParam struct {
	SpeakerCount int `json:"SpeakerCount,omitempty"`
}

type TranscriptionParam struct {
	AudioEventDetectionEnabled bool              `json:"AudioEventDetectionEnabled,omitempty"`
	DiarizationEnabled         bool              `json:"DiarizationEnabled,omitempty"`
	Diarization                *DiarizationParam `json:"Diarization,omitempty"`
}

type TranslationParam struct {
	TargetLanguages []string `json:"TargetLanguages,omitempty"`
}

type SummarizationParam struct {
	Types []string `json:"Types,omitempty"`
}

type ExtraParamerters struct {
	Transcoding              *TranscodeingParam  `json:"Transcoding,omitempty"`
	Transcription            *TranscriptionParam `json:"Transcription,omitempty"`
	TranslationEnabled       bool                `json:"TranslationEnabled,omitempty"`
	Translation              *TranslationParam   `json:"Translation,omitempty"`
	AutoChaptersEnabled      bool                `json:"AutoChaptersEnabled,omitempty"`
	MeetingAssistanceEnabled bool                `json:"MeetingAssistanceEnabled,omitempty"`
	SummarizationEnabled     bool                `json:"SummarizationEnabled,omitempty"`
	Summarization            *SummarizationParam `json:"Summarization,omitempty"`
  TextPolishEnabled        bool                `json:"TextPolishEnabled,omitempty"`
}

type InputParam struct {
	SourceLanguage string `json:"SourceLanguage"`
	FileUrl        string `json:"FileUrl,omitempty"`
	TaskKey        string `json:"TaskKey,omitempty"`
	Format         string `json:"Format,omitempty"`
	SampleRate     int    `json:"SampleRate,omitempty"`
}

type TaskBodyParam struct {
	Appkey      string            `json:"AppKey"`
	Input       InputParam        `json:"Input"`
	Paramerters *ExtraParamerters `json:"Parameters,omitempty"`
}

type CreateTaskResponse struct {
	RequestId string `json:"RequestId"`
	Code      string `json:"Code"`
	Message   string `json:"Message"`
	Data      struct {
		TaskId         string `json:"TaskId"`
		TaskKey        string `json:"TaskKey"`
		MeetingJoinUrl string `json:"MeetingJoinUrl,omitempty"`
	} `json:"Data"`
}

func init_request_param() *ExtraParamerters {
	param := new(ExtraParamerters)
	param.Transcoding = new(TranscodeingParam)

	transcription := new(TranscriptionParam)
	transcription.Diarization = new(DiarizationParam)
	transcription.Diarization.SpeakerCount = 2
	transcription.DiarizationEnabled = true
	param.Transcription = transcription

	translation := new(TranslationParam)
	translation.TargetLanguages = []string{"en"}
	param.Translation = translation
	param.TranslationEnabled = true
	param.AutoChaptersEnabled = false
	param.MeetingAssistanceEnabled = false
	param.SummarizationEnabled = true

	summarization := new(SummarizationParam)
	summarization.Types = []string{"Paragraph", "Conversational", "QuestionsAnswering"}
	param.Summarization = summarization
  param.TextPolishEnabled = false

	return param
}

func test_submit_realtime_meeting_task() string {
	akkey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
	aksecret := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
	client, err := sdk.NewClientWithAccessKey("cn-beijing", akkey, aksecret)
	if err != nil {
		log.Default().Fatalln(err)
		return ""
	}

	request := requests.NewCommonRequest()
	request.Method = "PUT"
	request.Domain = "tingwu.cn-beijing.aliyuncs.com"
	request.Version = "2023-09-30"
	request.SetContentType("application/json")
	request.PathPattern = "/openapi/tingwu/v2/tasks"
	request.QueryParams["type"] = "realtime"

	param := new(TaskBodyParam)
	param.Appkey = "输入您在听悟管控台创建的Appkey"
	param.Input.SourceLanguage = "cn"
	param.Input.Format = "pcm"
	param.Input.SampleRate = 16000
	param.Input.TaskKey = "task_" + fmt.Sprint(time.Now().Unix())
	param.Paramerters = init_request_param()

	b, _ := json.Marshal(param)
	log.Default().Print("request body:\n", string(b))
	request.SetContent(b)
	request.SetScheme("https")

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		log.Default().Fatalln(err)
		return ""
	}

	log.Default().Print("response body:\n", string(response.GetHttpContentBytes()))

	var resp CreateTaskResponse
	err = json.Unmarshal(response.GetHttpContentBytes(), &resp)
	if err != nil {
		log.Default().Fatalln(err)
		return ""
	}

	log.Default().Println("TaskId:", resp.Data.TaskId)
	log.Default().Println("MeetingJoinUrl:", resp.Data.MeetingJoinUrl)

	return resp.Data.MeetingJoinUrl
}

func main() {
	test_submit_realtime_meeting_task()
}
#include <cstdlib>
#include <iostream>
#include <string>
#include <alibabacloud/core/AlibabaCloud.h>
#include <alibabacloud/core/CommonRequest.h>
#include <alibabacloud/core/CommonClient.h>
#include <alibabacloud/core/CommonResponse.h>
#include "jsoncpp/json.h"
/**
 * @author tingwu2023
 * @desc 演示了通过OpenAPI 创建实时转写记录 的调用方式。
 */
int main( int argc, char** argv ) {
    AlibabaCloud::InitializeSdk();
    AlibabaCloud::ClientConfiguration configuration( "cn-beijing" );
    // specify timeout when create client.
    configuration.setConnectTimeout(1500);
    configuration.setReadTimeout(4000);
    // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
    AlibabaCloud::Credentials credential( getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET") );
    AlibabaCloud::CommonClient client( credential, configuration );
    AlibabaCloud::CommonRequest request(AlibabaCloud::CommonRequest::RequestPattern::RoaPattern);
    request.setHttpMethod(AlibabaCloud::HttpRequest::Method::Put);
    request.setDomain("tingwu.cn-beijing.aliyuncs.com");
    request.setVersion("2023-09-30");
    request.setResourcePath("/openapi/tingwu/v2/tasks");
    request.setQueryParameter("type", "realtime");
    request.setHeaderParameter("Content-Type", "application/json");
    
    Json::Value root;
    root["Appkey"] = "输入您在听悟管控台创建的Appkey";
    root["Appkey"] = "tEA3SDcxTKire0ut";

    Json::Value input;
    input["SourceLanguage"] = "cn";
    input["Format"]         = "pcm";
    input["SampleRate"]     = "16000";
    input["SourceLanguage"] = "cn";
    input["TaskKey"] = "输入您为该次请求自定义的标识";
    root["Input"] = input;

    Json::Value parameters;
    // 音视频文件转换 通常来说,不需要设置此参数
    // Json::Value transcoding;
    // transcoding["TargetAudioFormat"] = "mp3";
    // parameters["Transcoding"] = transcoding;

    // 语音转写: 以下是开启说话人分离功能(角色分离),若您不需要,则无须设置
    Json::Value transcription;
    transcription["DiarizationEnabled"] = true;
    Json::Value speakerCount;
    speakerCount["SpeakerCount"] = 2;
    transcription["Diarization"] = speakerCount;
    parameters["Transcription"] = transcription;

    // 翻译: 可选
    Json::Value translation;
    Json::Value langauges;
    langauges.append("en");
    translation["TargetLanguages"] = langauges;
    parameters["Translation"] = translation;
    parameters["TranslationEnabled"] = true;

    // 章节速览: 可选
    parameters["AutoChaptersEnabled"] = true;

    // 智能纪要: 可选,包括: 待办、关键信息(关键词、重点内容、场景识别)
    parameters["MeetingAssistanceEnabled"] = true;
    Json::Value meetingAssistance;
    Json::Value meetingAssistanceTypeList;
    meetingAssistanceTypeList.append("Actions");
    meetingAssistanceTypeList.append("KeyInformation");
    meetingAssistance["Types"] = meetingAssistanceTypeList;
    parameters["MeetingAssistanceTypeList"] = meetingAssistanceTypeList;

    // 摘要相关: 可选, 以下设置将3种摘要类型都启用了,您可以按需增删
    parameters["SummarizationEnabled"] = true;
    Json::Value summarization;
    Json::Value summarizationTypeList;
    summarizationTypeList.append("Paragraph");
    summarizationTypeList.append("Conversational");
    summarizationTypeList.append("QuestionsAnswering");
    summarization["Types"] = summarizationTypeList;
    parameters["Summarization"] = summarization;
  	
    // 口语书面化: 可选
    parameters["TextPolishEnabled"] = true;

    root["Parameters"] = parameters;

    Json::FastWriter writer;
    std::string body = writer.write(root);
    printf("input json: [%s]\n", body.c_str());
    request.setContent(body.c_str(), body.size());

    auto response = client.commonResponse(request);
    if (response.isSuccess()) {
        printf("request success.\n");
        printf("result: %s\n", response.result().payload().c_str());
    } else {
        printf("error: %s\n", response.error().errorMessage().c_str());
        printf("request id: %s\n", response.error().requestId().c_str());
    }
      
    AlibabaCloud::ShutdownSdk();
    return 0;
} 

示例输出

{
    "Code":"0",
    "Data":{
        "TaskId":"3190978427bb43z09c01dfff********",
        "TaskKey":"task16988********",
        "MeetingJoinUrl":"ws://127.0.0.1:9021/api/ws/v1?mc=g9ySw5kiwXM4K7tBnIajKq6Fh9G1aUokzkptBIFixj7e7zv6c8AKxUDTW2Oz8AFFONWXtTQedh-NpKZUffqIYdW7yAlivqlo9B0TdeM88fzgWaYk2Ifg********"
    },
    "Message":"success",
    "RequestId":"6582c654-cc37-4f2d-b80d-e5e7********"
}

协议解析

具体字段定义如下。

参数名

类型

说明

TaskId

string

创建任务时生成的TaskId,用于查询任务状态、结果以及排查问题时使用。

TaskKey

string

您创建任务时设置的TaskKey

MeetingJoinUrl

string

实时记录场景下生成的音频流推送地址,您可以在后续实时音频流识别时通过该地址进行

RequestId

string

RequestId用于排查问题使用。

实时记录语音推流

推流过程说明

1:建立推流通道,对应交互流程3-5。

2:推送识别语音,对应交互流程6、8、10、12。

  • 线下记录时:单路语音,推流输入格式为PCM。

  • 在线记录时:多路语音,创建记录时设置了参数AudioPackagemulti时,基于听悟约定的Protobuf格式封装多路音频,封装协议如下:

syntax = "proto3";

message MultiAudioFrame {
 int32 frame_size = 1; // 数据包音频时长,单位毫秒
 bytes mixed_data = 2; // 混音数据包,pcm格式
 repeated ActiveAudioFrame active_frame = 3; // 活跃通道数据
 int64 send_time = 4; // 数据包发送时间戳,单位毫秒
}

message ActiveAudioFrame {
 bytes data = 2; // 发言人数据包,pcm格式
 string speaker_id = 3; // 业务方发言人id标识
}

3:接收识别结果,对应交互流程7、9、11、13。

客户端循环发送语音数据,持续接收识别结果:

  • 句子开始事件(SentenceBegin)

句子开始事件表示服务端检测到了一句话的开始,听悟服务的智能断句功能会判断出一句话的开始与结束,示例如下。

{
    "header":{
        "namespace":"SpeechTranscriber",
        "name":"SentenceBegin",
        "status":20000000,
        "message_id":"a426f3d4618447519c9d85d1a0d1****",
        "task_id":"5ec521b5aa104e3abccf3d361822****",
        "status_text":"Gateway:SUCCESS:Success."
    },
    "payload":{
        "index":0,
        "time":0,
        "speaker_id":"用户1"
    }
}

对象参数说明:

参数

类型

说明

header

object

返回结果头信息。

namespace

string

消息所属的命名空间,固定为:SpeechTranscriber。

name

string

消息名称,SentenceBegin表示一个句子的开始。

task_id

string

推流任务全局唯一ID,请记录该值,便于排查问题。

message_id

string

本次消息的ID。

status

int

状态码,表示请求是否成功,见公共错误码

status_text

string

状态消息。

payload

object

返回结果。

index

int

句子编号,从0开始递增。

time

int

当前已处理的音频时长,单位是毫秒。

speaker_id

string

识别结果对应的说话人,单路识别和混音识别时不返回。

  • 句中识别结果变化事件(TranscriptionResultChanged)

句中识别结果变化事件表示识别结果发生了变化,示例如下。

{
    "header":{
        "namespace":"SpeechTranscriber",
        "name":"TranscriptionResultChanged",
        "status":20000000,
        "message_id":"dc21193fada84380a3b6137875ab****",
        "task_id":"5ec521b5aa104e3abccf3d361822****",
        "status_text":"Gateway:SUCCESS:Success."
    },
    "payload":{
        "index":0,
        "time":1835,
        "result":"北京的天",
        "words":[
            {
                "text":"北京",
                "startTime":630,
                "endTime":930
            },
            {
                "text":"的",
                "startTime":930,
                "endTime":1110
            },
            {
                "text":"天",
                "startTime":1110,
                "endTime":1140
            }
        ],
        "speaker_id":"用户1"
    }
}

对象参数说明:

参数

类型

说明

header

object

返回结果头信息。

namespace

string

消息所属的命名空间,固定为:SpeechTranscriber。

name

string

消息名称,TranscriptionResultChanged表示句中识别结果变化。

task_id

string

推流任务全局唯一ID,请记录该值,便于排查问题。

message_id

string

本次消息的ID。

status

int

状态码,表示请求是否成功,见公共错误码

status_text

string

状态消息。

payload

object

返回结果。

index

int

句子编号,从0开始递增。

time

int

当前已处理的音频时长,单位是毫秒。

result

string

当前句子的识别结果。

words

list[]

当前句子的词信息。

text

string

文本。

startTime

int

词开始时间,单位为毫秒。

endTime

int

词结束时间,单位为毫秒。

speaker_id

string

识别结果对应的说话人,单路识别和混音识别时不返回。

  • 句子结束事件(SentenceEnd)

句子结束事件表示服务端检测到了一句话的结束,并附带返回该句话的识别结果,示例如下。

{
    "header":{
        "namespace":"SpeechTranscriber",
        "name":"SentenceEnd",
        "status":20000000,
        "message_id":"c3a9ae4b231649d5ae05d4af36fd****",
        "task_id":"5ec521b5aa104e3abccf3d361822****",
        "status_text":"Gateway:SUCCESS:Success."
    },
    "payload":{
        "index":0,
        "time":1820,
        "begin_time":0,
        "result":"北京的天气。",
        "words":[
            {
                "text":"北京",
                "startTime":630,
                "endTime":930
            },
            {
                "text":"的",
                "startTime":930,
                "endTime":1110
            },
            {
                "text":"天气",
                "startTime":1110,
                "endTime":1380
            }
        ],
        "speaker_id":"用户1"
    }
}

对象参数说明:

参数

类型

说明

header

object

返回结果头信息。

namespace

string

消息所属的命名空间,固定为:SpeechTranscriber。

name

string

消息名称,SentenceEnd表示句子结束。

task_id

string

推流任务全局唯一ID,请记录该值,便于排查问题。

message_id

string

本次消息的ID。

status

int

状态码,表示请求是否成功,见公共错误码

status_text

string

状态消息。

payload

object

返回结果。

index

int

句子编号,从0开始递增。

time

int

当前已处理的音频时长,单位是毫秒。

result

string

当前句子的识别结果。

words

list[]

当前句子的词信息。

text

string

文本。

startTime

int

词开始时间,单位为毫秒。

endTime

int

词结束时间,单位为毫秒。

speaker_id

string

识别结果对应的说话人,单路识别和混音识别时不返回。

  • 识别结果翻译事件(ResultTranslated)

识别结果翻译事件表示在开启翻译时服务端检测到识别结果并进行目标语言文本翻译,示例如下。

{
    "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
            }
        ]
    }
}

对象参数说明:

参数

类型

说明

header

object

返回结果头信息。

namespace

string

消息所属的命名空间,固定为:SpeechTranscriber。

name

string

消息名称,ResultTranslated表示识别结果翻译。

task_id

string

推流任务全局唯一ID,请记录该值,便于排查问题。

message_id

string

本次消息的ID。

source_message_id

string

本次翻译的源识别结果消息ID。

status

int

状态码,表示请求是否成功,见公共错误码

status_text

string

状态消息。

payload

object

返回结果。

speaker_id

string

识别结果对应的说话人标识,同推流pb传入;无此字段时表示单通道识别或混音流识别的翻译。

source_lang

string

翻译的源语言。

target_lang

string

翻译的目标语言。

translate_result

list[]

识别结果翻译信息。

text

string

翻译后的文本。

index

int

翻译句子编号,从0开始递增。

partial

boolean

为true时对应非SentenceEnd的识别内容的翻译结果。

beginTime

int

翻译句子的开始时间,单位为毫秒,在翻译SentenceEnd识别结果时会返回。

endTime

int

翻译句子的结束时间,单位为毫秒,在翻译SentenceEnd识别结果时会返回。

  • 记录中更新配置的Ack响应事件(UpdateConfigAck)

客户端发送UpdateConfig指令后听悟服务端会返回该指令的Ack消息,示例如下。

{
    "header":{
        "namespace":"SpeechTranscriber",
        "name":"UpdateConfigAck",
        "status":20000000,
        "message_id":"a426f3d4618447519c9d85d1a0d1****",
        "task_id":"5ec521b5aa104e3abccf3d361822****",
        "status_text":"Success."
    },
    "payload":{
        "instruction_id":"9d139c48057ee287e0efe7e*****",
        "error_code":"***",
        "error_message":"***"
    }
}

对象参数说明:

参数

类型

说明

header

object

返回结果头信息。

namespace

string

消息所属的命名空间,固定为:SpeechTranscriber。

name

string

消息名称,SentenceBegin表示一个句子的开始。

task_id

string

推流任务全局唯一ID,请记录该值,便于排查问题。

message_id

string

本次消息的ID。

status

int

状态码,表示请求是否成功,公共错误码

status_text

string

状态消息。

payload

object

返回结果。

instruction_id

string

指令ID,会原样返回会中发送的UpdateConfig指令中的instruction_id。

error_code

string

会中发送的UpdateConfig指令参数异常时该字段会返回错误码。

error_message

string

会中发送的UpdateConfig指令参数异常时该字段会返回错误描述。

4:暂停推流识别,对应交互流程14-15。

  • 结束识别完成事件

参数

类型

说明

header

object

返回结果头信息。

namespace

string

消息所属的命名空间,固定为:SpeechTranscriber。

name

string

消息名称,TranscriptionCompleted表示此次推流识别完成,TaskFailed表示此次推流识别异常中断。

task_id

string

推流任务全局唯一ID,请记录该值,便于排查问题。

message_id

string

本次消息的ID。

status

int

状态码,表示请求是否成功,公共错误码

status_text

string

状态消息。

payload

object

返回结果。

5:继续推流识别,对应交互流程16-17。

结束实时记录

当该记录结束时,您务必参考如下内容及时调用API结束该记录。若您之前在创建实时记录时设置了后续的比如摘要、章节速览、智能纪要等功能参数,那么在结束记录之后,该实时记录状态并不是COMPLETED,而是ONGOING,表示此时进入到后处理阶段。

请求参数

参数名

类型

是否必填

说明

TaskId

string

您提交任务时 返回的TaskId信息

代码示例

package com.alibaba.tingwu.client.demo.realtimemeeting;

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.FormatType;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import org.junit.Test;

/**
 * @author tingwu2023
 * @desc 演示了通过OpenAPI 结束实时会议 的调用方式。
 */
public class StopRealtimeMeetingTaskTest {

    @Test
    public void stopTask() throws ClientException {
        CommonRequest request = createCommonRequest("tingwu.cn-beijing.aliyuncs.com", "2023-09-30", ProtocolType.HTTPS, MethodType.PUT, "/openapi/tingwu/v2/tasks");
        request.putQueryParameter("type", "realtime");
        // 必须设置 operation=stop
        request.putQueryParameter("operation", "stop");

        JSONObject root = new JSONObject();
        JSONObject input = new JSONObject();
        input.put("TaskId", "请输入实时会议的TaskId");
        root.put("Input", input);
        System.out.println(root.toJSONString());
        request.setHttpContent(root.toJSONString().getBytes(), "utf-8", FormatType.JSON);

        // TODO 请通过环境变量设置您的AccessKeyId、AccessKeySecret
        DefaultProfile profile = DefaultProfile.getProfile("cn-beijing", System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
        IAcsClient client = new DefaultAcsClient(profile);
        CommonResponse response = client.getCommonResponse(request);
        System.out.println(response.getData());
    }
  
    public static CommonRequest createCommonRequest(String domain, String version, ProtocolType protocolType, MethodType method, String uri) {
        CommonRequest request = new CommonRequest();
        request.setSysDomain(domain);
        request.setSysVersion(version);
        request.setSysProtocol(protocolType);
        request.setSysMethod(method);
        request.setSysUriPattern(uri);
        request.setHttpContentType(FormatType.JSON);
        return request;
    }
}
package main

import (
	"encoding/json"
	"log"
	"os"

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

type TranscodeingParam struct {
	TargetAudioFormat     string `json:"TargetAudioFormat,omitempty"`
	TargetVideoFormat     string `json:"TargetVideoFormat,omitempty"`
	VideoThumbnailEnabled bool   `json:"VideoThumbnailEnabled,omitempty"`
	SpectrumEnabled       bool   `json:"SpectrumEnabled,omitempty"`
}

type DiarizationParam struct {
	SpeakerCount int `json:"SpeakerCount,omitempty"`
}

type TranscriptionParam struct {
	AudioEventDetectionEnabled bool              `json:"AudioEventDetectionEnabled,omitempty"`
	DiarizationEnabled         bool              `json:"DiarizationEnabled,omitempty"`
	Diarization                *DiarizationParam `json:"Diarization,omitempty"`
}

type TranslationParam struct {
	TargetLanguages []string `json:"TargetLanguages,omitempty"`
}

type SummarizationParam struct {
	Types []string `json:"Types,omitempty"`
}

type ExtraParamerters struct {
	Transcoding              *TranscodeingParam  `json:"Transcoding,omitempty"`
	Transcription            *TranscriptionParam `json:"Transcription,omitempty"`
	TranslationEnabled       bool                `json:"TranslationEnabled,omitempty"`
	Translation              *TranslationParam   `json:"Translation,omitempty"`
	AutoChaptersEnabled      bool                `json:"AutoChaptersEnabled,omitempty"`
	MeetingAssistanceEnabled bool                `json:"MeetingAssistanceEnabled,omitempty"`
	SummarizationEnabled     bool                `json:"SummarizationEnabled,omitempty"`
	Summarization            *SummarizationParam `json:"Summarization,omitempty"`
}

type InputParam struct {
	SourceLanguage string `json:"SourceLanguage"`
	FileUrl        string `json:"FileUrl,omitempty"`
	TaskKey        string `json:"TaskKey,omitempty"`
	TaskId         string `json:"TaskId,omitempty"`
	Format         string `json:"Format,omitempty"`
	SampleRate     int    `json:"SampleRate,omitempty"`
}

type TaskBodyParam struct {
	Appkey      string            `json:"AppKey"`
	Input       InputParam        `json:"Input"`
	Paramerters *ExtraParamerters `json:"Parameters,omitempty"`
}

type CreateTaskResponse struct {
	RequestId string `json:"RequestId"`
	Code      string `json:"Code"`
	Message   string `json:"Message"`
	Data      struct {
		TaskId         string `json:"TaskId"`
		TaskKey        string `json:"TaskKey"`
		MeetingJoinUrl string `json:"MeetingJoinUrl,omitempty"`
	} `json:"Data"`
}

func test_stop_realtime_meeting_task() {
	akkey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
	aksecret := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
	client, err := sdk.NewClientWithAccessKey("cn-beijing", akkey, aksecret)
	if err != nil {
		log.Default().Fatalln(err)
		return
	}

	request := requests.NewCommonRequest()
	request.Method = "PUT"
	request.Domain = "tingwu.cn-beijing.aliyuncs.com"
	request.Version = "2023-09-30"
	request.SetContentType("application/json")
	request.PathPattern = "/openapi/tingwu/v2/tasks"
	request.QueryParams["type"] = "realtime"
	request.QueryParams["operation"] = "stop"

	param := new(TaskBodyParam)
	param.Appkey = "输入您在听悟管控台创建的Appkey"
	param.Input.TaskId = "请输入实时会议的TaskId"

	b, _ := json.Marshal(param)
	log.Default().Print("request body:\n", string(b))
	request.SetContent(b)
	request.SetScheme("https")

	response, err := client.ProcessCommonRequest(request)
	if err != nil {
		log.Default().Fatalln(err)
		return
	}

	log.Default().Print("response body:\n", string(response.GetHttpContentBytes()))
	return
}

func main() {
	test_stop_realtime_meeting_task()
}
#include <cstdlib>
#include <iostream>
#include <string>
#include <string.h>
#include <alibabacloud/core/AlibabaCloud.h>
#include <alibabacloud/core/CommonRequest.h>
#include <alibabacloud/core/CommonClient.h>
#include <alibabacloud/core/CommonResponse.h>
#include "jsoncpp/json.h"
/**
 * @author tingwu2023
 * @desc 演示了通过OpenAPI 结束实时记录 的调用方式。
 */
int main( int argc, char** argv ) {
    std::string taskId = "请输入创建任务(含离线转写、实时会议)的TaskId";

    AlibabaCloud::InitializeSdk();
    AlibabaCloud::ClientConfiguration configuration( "cn-beijing" );
    // specify timeout when create client.
    configuration.setConnectTimeout(1500);
    configuration.setReadTimeout(4000);
    // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
    AlibabaCloud::Credentials credential( getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"), getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET") );
    AlibabaCloud::CommonClient client( credential, configuration );
    AlibabaCloud::CommonRequest request(AlibabaCloud::CommonRequest::RequestPattern::RoaPattern);
    request.setHttpMethod(AlibabaCloud::HttpRequest::Method::Put);
    request.setDomain("tingwu.cn-beijing.aliyuncs.com");
    request.setVersion("2023-09-30");
    request.setResourcePath("/openapi/tingwu/v2/tasks");
    request.setQueryParameter("type", "realtime");
    request.setQueryParameter("operation", "stop");
    request.setHeaderParameter("Content-Type", "application/json");

    Json::Value root;
    Json::Value input;
    input["TaskId"] = taskId;
    root["Input"] = input;

    Json::FastWriter writer;
    std::string body = writer.write(root);
    printf("input json: [%s]\n", body.c_str());
    request.setContent(body.c_str(), body.size());

    auto response = client.commonResponse(request);
    if (response.isSuccess()) {
        printf("request success.\n");
        printf("result: %s\n", response.result().payload().c_str());
    } else {
        printf("error: %s\n", response.error().errorMessage().c_str());
        printf("request id: %s\n", response.error().requestId().c_str());
    }
      
    AlibabaCloud::ShutdownSdk();
    return 0;
} 

示例输出

当仅使用实时语音识别时:

{
    "Code":"0",
    "Data":{
        "TaskId":"e8adc0b3bc4b42d898fcadb0a*******",
        "TaskStatus":"COMPLETED"
    },
    "Message":"success",
    "RequestId":"1b20e0d9-c55c-4cc3-85af-80b********"
}

当开启语音识别的同时开启了摘要、章节速览、智能纪要等功能时:

{
    "Code":"0",
    "Data":{
        "TaskId":"e8adc0b3bc4b42d898fcadb0*******",
        "TaskStatus":"ONGOING"
    },
    "Message":"success",
    "RequestId":"5fa32fc6-441f-4dd1-bb86-c030*******"
}

协议解析

具体字段定义如下。

参数名

类型

说明

TaskId

string

创建任务时生成的TaskId

TaskStatus

string

任务状态,包括:

  • ONGOING :运行中

  • COMPLETED : 已完成

  • FAILED : 任务失败

  • INVALID :无效,可能是TaskId不存在

ErrorCode

string

错误原因

ErrorMessage

string

错误详细信息

常见问题

相比离线转写,为什么实时记录参数里缺少了PPT提取功能参数?

PPT提取(包括PPT抽取和PPT摘要)主要是针对在离线转写场景下,原文件是视频格式的情况下发挥作用的。不论是音频文件还是实时记录里的二进制音频流都没有视频信息,因此也不会产生PPT相关结果。

  • 本页导读 (0)
文档反馈