Web (JavaScript)

概述

通过本文,您可以使用Web版本的云上曲率实时语音翻译SDK,来实现实时语音场景下的翻译业务。

SDK集成

服务开通

云上曲率实时语音翻译SDK的使用,需要在云上曲率官网(https://www.ilivedata.com/) 注册账号并创建实时语音翻译服务项目。完成后,获取到项目对应的参数,更新到SDK中,再进行集成使用。

使用要求

  • 实时音频格式支持:只支持PCM格式音频
  • 采样率:16K Hz
  • 编码:16bit位深
  • 声道:单声道
  • 帧长:20ms,每帧固定640字节

集成依赖

引入以下依赖库:

<script src="libs/msgpack.min.js"></script>
<script src="libs/md5.min.js"></script>
<script src="libs/int64.min.js"></script>
<script src="libs/crypto-js.min.js"></script>
<script src="libs/fpnn.min.js"></script>
<script src="dist/rtvt.sdk.min.js"></script>

初始化

let rtvtClient = new RTVTClient({
    endpoint: endpoint,
    pid: pid,
    uid: uid,
});
参数 类型 说明
endpoint string 控制台提供的SDK接入地址
pid long 项目id,通过云上控制台获取
uid string 用户id,业务侧自行生成,可选

登录

rtvtClient.login(token, ts, callback);
参数 类型 说明
token string token生成方式参见下文
ts int 时间戳,单位秒,与生成token时使用的时间戳一致
callback function callback(ok, errorCode);成功时为(true, 0),失败时返回(false, 800001)

开始实时语音翻译

rtvtClient.createStream(srcLang, destLang, asrResult, tempResult, transResult, callback);
参数 类型 说明
srcLang string 源语言
destLang string 目标语言
asrResult boolean 是否返回识别结果,必须显式传入true或false
tempResult boolean 是否返回临时识别和临时翻译结果,必须显式传入true或false
transResult boolean 是否返回翻译结果,必须显式传入true或false
callback function callback(stream, errorCode);成功返回RTVTStream对象和0,失败返回null和错误码
  • 当有识别结果时,如果asrResult设置为true,会触发recognizedResult事件:
rtvtClient.on("recognizedResult", function(data) { console.log(data); });
  • 当有翻译结果时,如果transResult设置为true,会触发translatedResult事件:
rtvtClient.on("translatedResult", function(data) { console.log(data); });
  • 当有临时识别结果时,如果asrResult设置为true,且tempResult设置为true,会触发recognizedTempResult事件:
rtvtClient.on("recognizedTempResult", function(data) { console.log(data); });
  • 当有临时翻译结果时,如果transResult设置为true,且tempResult设置为true,会触发translatedTempResult事件:
rtvtClient.on("translatedTempResult", function(data) { console.log(data); });

发送语音片段

rtvtClient.sendVoice(stream, seq, pcm);
参数 类型 说明
stream RTVTStream createStream成功回调返回的流对象,不能传数字形式的streamId
seq long 语音片段序号(尽量有序)
pcm ArrayBuffer PCM音频数据,每帧固定640字节

多语种翻译

多目标语种翻译必须使用multi_startTranslate接口开启语音流,并使用multi_sendVoice接口发送音频。

开始实时语音翻译

rtvtClient.multi_startTranslate(srcLanguage, srcAltLanguage, asrResult, tempResult, ttsResult, userId, callback);
参数 类型 说明
srcLanguage string 源语言,必传
srcAltLanguage string[] / null 备选源语言列表;不需要时传null或[],传入备选语言可能增加首句返回耗时
asrResult boolean 是否返回语音识别结果;设置为true时,通过recognizedResult回调返回
tempResult boolean 是否返回临时识别结果和临时翻译结果,用于长句快速返回;设置为true时,分别通过recognizedTempResult和translatedTempResult回调返回临时结果
ttsResult boolean 是否返回TTS结果;TTS仅合成最终翻译结果
userId string 用于后台显示和查询,业务端可与返回的streamId绑定
callback function callback(stream, errorCode);成功返回RTVTStream对象和0,失败返回null和错误码。发送音频时传入该流对象

多语种模式固定开启翻译结果(transResult=true);第五个参数是ttsResult,不是翻译开关。布尔参数应显式传入,userId不需要时可传空字符串。

发送语音片段

rtvtClient.multi_sendVoice(stream, seq, voicedata, voiceDataTs, dstLanguageList, callback);
参数 类型 说明
stream RTVTStream multi_startTranslate成功回调返回的流对象,不能传数字形式的streamId
seq long 语音片段序号(尽量有序)
voicedata ArrayBuffer PCM音频数据,16kHz、16bit、单声道,每20ms一帧,每帧固定640字节
voiceDataTs number 音频帧对应的Unix时间戳,单位毫秒;按采集时间传入,不是token使用的秒级时间戳
dstLanguageList string[] 目标语言列表,例如["en", "ja"],可按帧调整
callback function 可选;callback(ok, errorCode),成功为(true, 0),失败为(false, errorCode)

返回值与错误处理

sendVoice和multi_sendVoice在本地校验失败时返回300002(音频不是640字节)或300003(流不存在);返回undefined仅表示通过本地校验,不代表服务端已确认。multi_sendVoice还会通过可选回调报告本地校验失败和服务端发送结果。网络或服务端发送错误会触发ErrorRecorder事件。

结果事件与TTS

多语种模式沿用上述四类识别、翻译事件,使用结果中的lang区分目标语言。事件处理函数收到服务器原始推送对象,不是流创建或发送完成回调。ttsResult=true时还可订阅:

rtvtClient.on("ttsResult", function(data) {
    console.log(data.lang, data.text, data.data); // 目标语言、合成文本、音频数据
});
rtvtClient.on("ErrorRecorder", function(error) {
    console.error(error);
});

streamId等64位整数按Int64对象解码;展示或用作字符串键时调用.toString(),避免转换为JavaScript数字后丢失精度。需要业务侧查看流ID时可调用stream.getStreamID(),发送音频仍传流对象。

RTVTStream流对象

createStream和multi_startTranslate的成功回调均返回RTVTStream实例。

方法 说明
stream.getStreamID() 获取服务端流ID,使用.toString()展示;发送音频仍传stream对象
stream.close() 请求停止当前流,没有完成回调

多语种调用示例

下面的onPcmFrame由业务的音频采集回调调用,每次传入一个640字节ArrayBuffer及其采集时间戳(毫秒)。停止采集后,应等待所需最终结果,再关闭流和释放客户端。

let activeStream = null;
let seq = 0;

function onPcmFrame(pcm, captureTs) {
    if (!activeStream) return;
    rtvtClient.multi_sendVoice(activeStream, ++seq, pcm, captureTs, ["en", "ja"], function(ok, errorCode) {
        if (!ok) console.error("send voice failed", errorCode);
    });
}

rtvtClient.login(token, ts, function(ok, errorCode) {
    if (!ok) {
        console.error("login failed", errorCode);
        return;
    }
    rtvtClient.multi_startTranslate("zh", null, true, true, true, "user-123", function(stream, errorCode) {
        if (!stream) {
            console.error("create stream failed", errorCode);
            return;
        }
        activeStream = stream;
        seq = 0;
        // 此时开始采集音频,并由采集回调调用onPcmFrame。
    });
});

如果一次采集回调产生多帧音频,应按每帧20ms的采集位置计算时间戳,不要为同一批音频统一填写发送时刻。发送完成回调表示音频请求的处理结果,识别和翻译内容通过结果事件返回。

停止翻译

关闭单个流使用stream.close();停止全部流使用rtvtClient.stopAllStreams()。停止后再次翻译需要重新创建流。

rtvtClient.stopAllStreams();

释放对象

rtvtClient.destory();

注意,使用结束时调用。下次使用需要重新登录

Token生成

Token生成方式请参考以下代码示例:

var pid = pid;
var key = key;
var ts = parseInt(new Date().getTime() / 1000);
var coreString = pid + ":" + ts;
var token = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA256(coreString, atob(key)));

SDK下载

SDK下载和更多说明请前往Github。