You need to enable JavaScript to run this app.
文档中心
豆包语音

豆包语音

复制全文
下载 pdf
端到端实时语音大模型
实时语音(Android)
复制全文
下载 pdf
实时语音(Android)
豆包实时语音模型3.0-全双工端到端语音大模型(Seeduplex),主要实现语音对话交互功能,可提供更加拟人,更低时延的语音对话效果,以下为面向开发者的Android SDK接入说明。​
接入端到端实时语音-全双工版本前,请您务必完成接入必读的阅读,了解全双工版本协议设计原则、相关注意事项、最佳实践等。​
SDK版本​
Android: com.bytedance.speechengine:speechengine_tob: 0.0.15.0​
​
// Speech Engine​
implementation 'com.bytedance.speechengine:speechengine_tob:0.0.15.0'​
// Net okhttp:4.9.1为默认依赖的网络库版本,若有其它版本需要,可引用相应okhttp版本​
implementation("com.squareup.okhttp3:okhttp:4.9.1")​
​
示例demo​
主要参考DialogDuplexActivity​
​
​
SpeechDemoAndroid.zip
​
​
兼容性 ​
​
类别​
兼容范围​
系统​
最低支持Android 4.4 以上版本,API LEVEL 19​
架构​
armeabi-v7a,arm64-v8a​
网络​
支持移动数据与 WiFi 两种网络环境​
​
AndroidManifest.xml 文件 ​
​
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />​
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />​
<uses-permission android:name="android.permission.RECORD_AUDIO" />​
<uses-permission android:name="android.permission.INTERNET" />​
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />​
​
混淆规则 ​
​
-keep class com.bytedance.speech.speechengine.SpeechEngineImpl {*;}​
​
回声消除 AEC ​
Dialog 语音对话过程中,如果既启用录音机,又启用播放器,则设备会录入播放的人声而影响对话。故Dialog SDK 内置 AEC能力,对回声进行消除处理。(需要开启AEC功能,并配置AEC模型文件路径)​
特别的,在自定义输入音频或自定义输出音频场景,如果能确保输入音频没有回声,可以选择关闭AEC。如果不能,则需要自行保证输出音频和输入回声所处的时间位置一致,以便AEC进行处理。​
(当前硬件AEC为强制开启,故可能存在可能关闭Dialog SDK内置AEC之后,硬件AEC继续生效不会自打断。主要原因是为了设备当前有其它APP存在播放的声音时,该声音Dialog SDK内置AEC消除不掉,故强制开启硬件AEC 作为保底。)​
AEC 模型如下:​
​
​
aec.model
​
​
调用流程​
初始化引擎实例​
​
// 初始化引擎实例​
int ret = engine.initEngine();​
if (ret != SpeechEngineDefines.ERR_NO_ERROR) {​
Log.e(SpeechDemoDefines.TAG, "初始化失败,返回值: " + ret);​
return;​
}​
engine.setContext(getApplicationContext());​
engine.setListener(this);​
​
启动引擎​
session.create事件说明&示例请参考:S2S-全双工版本API文档。​
​
// 启动Dialog引擎​
int ret = engine.sendDirective(SpeechEngineDefines.DIRECTIVE_START_ENGINE, "{\"type\":\"session.create\",\"session\":{}}");​
if (ret != SpeechEngineDefines.ERR_NO_ERROR) {​
Log.e(SpeechDemoDefines.TAG, "启动失败,返回值: " + ret);​
return;​
}​
​
参数配置(必要)​
​
//【必需配置】API Key 可以从 控制台>API Key管理 获取​
mSpeechEngine.setOptionString(SpeechEngineDefines.PARAMS_KEY_API_KEY_STRING, "your-api-key");​
// 【必需配置】设置使用全双工json协议​
engine.setOptionInt(SpeechEngineDefines.PARAMS_KEY_PROTOCOL_TYPE_INT,SpeechEngineDefines.PROTOCOL_TYPE_SEED_DUPLEX);​
//【必需配置】Engine Name​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_ENGINE_NAME_STRING, SpeechEngineDefines.DIALOG_ENGINE);​
//【必需配置】User ID(用以辅助定位线上用户问题,如无法提供可提供固定字符串)​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_UID_STRING, "UID");​
//【必需配置】对话服务域名​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_ADDRESS_STRING, "wss://openspeech.bytedance.com");​
//【必需配置】对话服务Uri​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_URI_STRING, "/api/v3/duplex/realtime/dialogue");​
​
参数配置(可选)​
​
//【可选配置】本地日志文件路径,SDK会在该路径文件夹下生成名为 speech_sdk.log 的日志文件,开发时设置,线上关闭。​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DEBUG_PATH_STRING, "已存在的文件夹路径,或者空字符串");​
//【可选配置】日志级别,开发时设置为 TRACE(最低级别),线上设置 WARN;​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_LOG_LEVEL_STRING, SpeechEngineDefines.LOG_LEVEL_TRACE);​
// AEC​
//【可选配置】是否开启AEC,默认不开启,同时启用设备录音和播放时必须开启​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_ENABLE_AEC_BOOL, true);​
//【可选配置】AEC模型路径,开启AEC时必填​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_AEC_MODEL_PATH_STRING, "AEC 模型文件路径,路径需包含文件名,示例:/xxx/xxx/aec.model");​
// 输入音频 & 录音机​
//【可选配置】配置音频来源,默认使用设备麦克风录音(Dialog 仅支持 RECORDER 和 STREAM 模式,RECORDER表示设备麦克风录音,STREAM表示自定义音频输入)​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_RECORDER_TYPE_STRING, SpeechEngineDefines.RECORDER_TYPE_RECORDER);​
//【可选配置】录音文件保存路径,如不为空字符串,则SDK会将录音机音频保存到该路径下,文件格式为 .wav​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_RECORDER_PATH_STRING, "已存在的文件夹路径,或者空字符串");​
//【可选配置】启用录音机音频回调,开启后录音音频数据将通过MESSAGE_TYPE_DIALOG_RECORDER_AUDIO消息回调,默认不启用​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_RECORDER_AUDIO_CALLBACK_BOOL, false);​
// 输出音频 & 播放器​
//【可选配置】是否开启播放器,默认开启​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_PLAYER_BOOL, true);​
//【可选配置】启用播放器音频回调,默认不启用(为当前正在播放的音频数据,会随着播放进度回调)​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_PLAYER_AUDIO_CALLBACK_BOOL, false);​
//【可选配置】启用解码后原始音频回调,默认不启用(为解码后的需要播报的数据,会在解码完成后立刻回调,不等待播放进度)​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_DECODER_AUDIO_CALLBACK_BOOL, false);​
//【可选配置】播放文件保存路径,如不为空字符串,则SDK会将播放器音频保存到该路径下,文件格式为 .wav​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_DIALOG_PLAYER_PATH_STRING, "已存在的文件夹路径,或者空字符串");​
​
发送上行指令​
语音对话 SDK 通过发送指令接口 sendDirective 触发各种操作,需要注意不建议在 SDK 的回调线程中调用该接口。​
S2S-全双工版本采取通用的DIRECTIVE_SEND_UPLINK_EVENT指令,透传对应上行事件的的payload,上行事件说明&示例请参考:S2S-全双工版本API文档。​
​
// 会等待回调函数执行完成,不可在回调线程中执行。​
engine.sendDirective(SpeechEngineDefines.DIRECTIVE_SEND_UPLINK_EVENT, "{\"type\":\"xxx.yyy\"}");​
​
回调接收返回数据 ​
启动引擎后,SDK会不断回调消息。S2S-全双工版本采取通用的MESSAGE_TYPE_DIALOG_DOWNLINK_EVENT回调事件,透传对应下行事件的的payload,下行事件说明&示例请参考:S2S-全双工版本API文档。​
​
@Override public void onSpeechMessage(int type, byte[] data, int len) {​
String strData = new String(data);​
switch (type) {​
case SpeechEngineDefines.MESSAGE_TYPE_ENGINE_START:​
// Callback: 引擎启动成功回调​
Log.i(SpeechDemoDefines.TAG, "Callback: 引擎启动成功: " + strData);​
break;​
case SpeechEngineDefines.MESSAGE_TYPE_ENGINE_STOP:​
// Callback: 引擎关闭回调,启动引擎成功后,此消息必定发生且为最后一个回调消息​
Log.i(SpeechDemoDefines.TAG, "Callback: 引擎关闭: " + strData);​
break;​
case SpeechEngineDefines.MESSAGE_TYPE_ENGINE_ERROR:​
// Callback: 错误信息回调​
Log.e(SpeechDemoDefines.TAG, "Callback: 错误信息: " + type + " data: " + strData);​
break;​
case SpeechEngineDefines.MESSAGE_TYPE_DIALOG_DOWNLINK_EVENT:​
// Callback: 具体Event可参考demo DialogDuplexActivity的handleDialogDownlinkEvent方法​
Log.i(SpeechDemoDefines.TAG, "Callback: Downlink event: " + strData);​
break;​
default:​
break;​
}​
}​
​
销毁引擎实例 ​
当不再需要语音对话后,建议对引擎实例进行销毁,释放内存资源。​
session.close事件说明&示例请参考:S2S-全双工版本API文档。​
​
// 会等待回调函数执行完成,不可在回调线程中执行。​
engine.sendDirective(SpeechEngineDefines.DIRECTIVE_SYNC_STOP_ENGINE, "{\"type\":\"session.close\",\"event_id\":\"event_close\"}");​
​
客户端相关指令​
暂停播放 ​
​
int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_PAUSE_PLAYER, "");​
if (ret != SpeechEngineDefines.ERR_NO_ERROR) {​
String tips = "Send directive pause player failed, " + ret;​
Log.e(SpeechDemoDefines.TAG, tips);​
mEngineStatusTv.setText(tips);​
}​
​
恢复播放 ​
​
int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_RESUME_PLAYER, "");​
if (ret != SpeechEngineDefines.ERR_NO_ERROR) {​
String tips = "Send directive resume player failed, " + ret;​
Log.e(SpeechDemoDefines.TAG, tips);​
mEngineStatusTv.setText(tips);​
}​
​
暂停麦克风录音 ​
发送DIRECTIVE_PAUSE_RECORDER用于暂停麦克风录音,此时SDK会持续给服务端发送静音包以保活session(静音最长维持时间为10min)。注:S2S全双工版本静音音频仍会计费,调用该指令需注意该影响。​
​
int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_PAUSE_RECORDER, "");​
if (ret != SpeechEngineDefines.ERR_NO_ERROR) {​
String tips = "Send directive pause recorder failed, " + ret;​
Log.e(SpeechDemoDefines.TAG, tips);​
mEngineStatusTv.setText(tips);​
}​
​
恢复麦克风录音 ​
​
int ret = mSpeechEngine.sendDirective(SpeechEngineDefines.DIRECTIVE_RESUME_RECORDER, "");​
if (ret != SpeechEngineDefines.ERR_NO_ERROR) {​
String tips = "Send directive resume recorder failed, " + ret;​
Log.e(SpeechDemoDefines.TAG, tips);​
mEngineStatusTv.setText(tips);​
}​
​
自定义音频输入 ​
Dialog 可以选择不使用系统录音机,而通过feedAudio接口,传入原始音频数据作为用户的输入音频。注意:​
  • 输入音频仅支持 PCM 16bit位深音频格式,且采样率需要为16k,通道数为1即单通道。​
  • 如果采样率不为16k,或者通道数不为1,可以开启SDK 内部重采样,SDK会自动重采为16k、单通道音频。​
​
//【可选配置】配置音频来源,STREAM 模式表示使用自定义音频输入​
engine.setOptionString(SpeechEngineDefines.PARAMS_KEY_RECORDER_TYPE_STRING, SpeechEngineDefines.RECORDER_TYPE_STREAM);​
​
// 当输入音频采样率不为16k,或通道数不为1时,使用下述方式开启重采样​
//【可选配置】启用 SDK 内部的重采样,默认不启用。​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_ENABLE_RESAMPLER_BOOL, true);​
​
//【可选配置】设置为输入音频的实际采样率,这里以采样率44.1k 通道数2 为例,sdk内部会重采为采样率16k 通道1。​
engine.setOptionInt(SpeechEngineDefines.PARAMS_KEY_CUSTOM_SAMPLE_RATE_INT, 44100);​
engine.setOptionInt(SpeechEngineDefines.PARAMS_KEY_CUSTOM_CHANNEL_INT, 2);​
​
// ...初始化引擎实例 并 发送指令-启动引擎...​
​
byte[] buffer = new byte[mBufferSize];​
​
// ...业务自行将音频读入到 buffer 中...​
​
int ret = engine.feedAudio(buffer, buffer.length);​
if (ret != 0) {​
Log.e(SpeechDemoDefines.TAG, "Feed audio failed.");​
break; // 确保外层有循环​
}​
​
自定义音频输出 ​
Dialog 可以关闭设备播放器,业务方通过回调拿到原始音频数据,再视需要进行使用。​
  • 播放器数据回调:即使关闭播放器,也会跟随现实时间播放进度,每100ms现实时间就回调100ms的音频数据。​
  • 解码器数据回调:不跟随现实时间,只要收到Dialog服务的音频数据并解码后,就立刻回调接收到的所有音频数据。​
​
//【可选配置】是否开启播放器,默认开启,不使用设备播放器时需要关闭。​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_PLAYER_BOOL, false);​
//【可选配置】启用播放器音频回调,默认不启用(为当前正在播放的音频数据,会随着播放进度回调)​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_PLAYER_AUDIO_CALLBACK_BOOL, true);​
//【可选配置】启用解码后原始音频回调,默认不启用(为解码后的需要播报的数据,会在解码完成后立刻回调,不等待播放进度)​
engine.setOptionBoolean(SpeechEngineDefines.PARAMS_KEY_DIALOG_ENABLE_DECODER_AUDIO_CALLBACK_BOOL, true);​
​
// ...// 初始化引擎实例 并 发送指令-启动引擎// ...// 消息回调中,对接收到的音频数据进行处理​
@Override public void onSpeechMessage(int type, byte[] data, int len) {​
switch (type) {​
case SpeechEngineDefines.MESSAGE_TYPE_PLAYER_AUDIO_DATA:​
// Callback: 播放器音频数据回调​
Log.e(SpeechDemoDefines.TAG, "Callback: 播放器音频数据回调: len: " + len);​
break;​
case SpeechEngineDefines.MESSAGE_TYPE_DECODER_AUDIO_DATA:​
// Callback: 解码器音频数据回调​
Log.e(SpeechDemoDefines.TAG, "Callback: 解码器音频数据回调: len: " + len);​
break;​
default:​
break;​
}​
}​
​
​
​
​
最近更新时间:2026.09.28 19:16:24
这个页面对您有帮助吗?
有用
有用
无用
无用