Skip to main content
Version: v1.2.0

快速开始

本章节将引导您在 10 分钟内完成 Tmk Translation SDK 的 Demo 体验,并给出最小接入示例。

获取演示 Demo

SDK 已发布到 CocoaPodsMaven Central,可直接安装使用。

集成 SDK

Android

通过 Gradle 依赖引入 SDK。

implementation("co.timekettle.translation:tmk-translation-sdk:1.2.0")

iOS

通过 CocoaPods 集成,使用命令 pod install --repo-update 安装,CocoaPods 建议升级到 1.16.2。

pod 'TmkTranslationSDK', '1.2.0'

配置演示 Demo

获取凭证

请联系时空壶技术团队申请 AppID 和 AppSecret。

Android:在 gradle.properties 中填写 GitHub 用户名和 PAT,以及申请到的凭证。

# GitHub Packages credentials (recommended in ~/.gradle/gradle.properties)
gpr.user=your_github_user
gpr.key=ghp_xxx

TMK_SAMPLE_APP_ID=your_app_id
TMK_SAMPLE_APP_SECRET=your_app_secret

iOS:复制一份 LocalSecrets.xcconfig,将占位值替换为真实凭证。注意值本身不要包裹引号、撇号或尖括号;且不要提交 LocalSecrets.xcconfig

TMK_SAMPLE_APP_ID = your_app_id
TMK_SAMPLE_APP_SECRET = your_app_secret

配置好后即可运行 Demo,体验 SDK 相关翻译场景。

最小接入示例

以下示例演示"在线收听"与"离线收听"两种最小链路。

iOS:在线收听

import TmkTranslationSDK

final class OnlineListenHandler: TmkTranslationListener {
func onRecognized(from engine: AbstractChannelEngine, result: TmkResult<String>, isFinal: Bool) {
print("Recognized: \(result.data)")
}

func onTranslate(from engine: AbstractChannelEngine, result: TmkResult<String>, isFinal: Bool) {
print("Translated: \(result.data)")
}

func onAudioDataReceive(from engine: AbstractChannelEngine,
result: TmkResult<String>,
data: Data,
channelCount: Int) {
print("Audio bytes: \(data.count)")
}

func onError(_ error: TmkTranslationError) {
print(error.message)
}
}

let handler = OnlineListenHandler()

let config = TmkTranslationGlobalConfig.Builder()
.setAuth(appId: "your_app_id", secret: "your_app_secret")
.setOnlineAuthContext(
tenantId: "your_tenant_id",
externalUserId: "your_external_user_id",
installId: nil
)
.setNetworkEnvironment(.test)
.build()

TmkTranslationSDK.shared.sdkInit(config)
TmkTranslationSDK.shared.verifyAuth { result in
switch result {
case .success:
TmkTranslationSDK.shared.createTmkTranslationRoom(
config: TmkTranslationRoomConfig(
sourceLang: "zh-CN",
targetLang: "en-US",
scenario: .toSpeech,
channelScenario: .listen
)
) { result in
switch result {
case .success(let room):
let channelConfig = TmkTranslationChannelConfig.Builder()
.setRoom(room)
.setScenario(.listen)
.setMode(.online)
.setSourceLang("zh-CN")
.setTargetLang("en-US")
.setPCMSampleRate(16_000)
.setPCMChannels(1)
.build()

TmkTranslationSDK.shared.createTranslationChannel(channelConfig, listener: handler) { result in
switch result {
case .success(let channel):
// 业务侧持续推送 PCM 数据
channel.pushStreamAudioData(pcmData, channelCount: 1)
case .failure(let error):
print(error.message)
}
}
case .failure(let error):
print(error.message)
}
}
case .failure(let error):
print(error.message)
}
}

// 关闭引擎
TmkTranslationSDK.releaseChannel()

iOS:离线收听

import TmkTranslationSDK

let modelRootDirectory = "/path/to/offline_models"

TmkTranslationSDK.shared.verifyAuth { result in
switch result {
case .success:
guard TmkTranslationSDK.shared.isOfflineTranslationSupported() else {
print("Offline translation is not supported for this account")
return
}

guard TmkTranslationSDK.shared.isOfflineModelReady(
srcLang: "zh",
dstLang: "en",
modelRootDirectory: modelRootDirectory,
scenario: .listen,
needMt: true,
needTts: true
) else {
print("Offline model is not ready")
return
}

let channelConfig = TmkTranslationChannelConfig.Builder()
.setMode(.offline)
.setScenario(.listen)
.setSourceLang("zh")
.setTargetLang("en")
.setPCMSampleRate(16_000)
.setPCMChannels(1)
.setModelRootDirectory(modelRootDirectory)
.build()

TmkTranslationSDK.shared.createTranslationChannel(channelConfig, listener: handler) { result in
switch result {
case .success(let channel):
channel.pushStreamAudioData(pcmData, channelCount: 1)
case .failure(let error):
print(error.message)
}
}
case .failure(let error):
print(error.message)
}
}

// 关闭引擎
TmkTranslationSDK.releaseChannel()

Android:在线收听

val globalConfig = TmkTransGlobalConfig.Builder()
.setAuth("your_app_id", "your_app_secret")
.build()

TmkTranslationSDK.sdkInit(applicationContext, globalConfig)

TmkTranslationSDK.verifyAuth(object : AuthCallback {
override fun onSuccess() {
TmkTranslationSDK.createTmkTranslationRoom(object : CreateRoomCallback {
override fun onSuccess(room: TmkTranslationRoom) {
val channelConfig = TmkTransChannelConfig.Builder()
.setRoom(room)
.setMode(TranslationMode.ONLINE)
.setScenario(Scenario.LISTEN)
.setTransModeType(TransModeType.LISTEN)
.setSourceLang("zh-CN")
.setTargetLang("en-US")
.setSampleRate(16000)
.setChannelNum(1)
.build()

TmkTranslationSDK.createTranslationChannel(
applicationContext,
channelConfig,
listener,
object : CreateChannelCallback {
override fun onSuccess(channel: TmkTranslationChannel) {
// 四参数重载已自动 start,之后可开始推 PCM
}

override fun onError(errorId: Int, e: Exception) { }
}
)
}

override fun onError(errorId: Int, e: Exception) { }
})
}

override fun onError(errorId: Int, e: Exception) { }
})

// 关闭引擎
TmkTranslationSDK.releaseChannel()

Android:离线收听

if (!TmkTranslationSDK.isOfflineTranslationSupported()) {
// 提示当前账号未开通离线能力或尚未完成鉴权
return
}

TmkTranslationSDK.checkOfflineModelReadyAsync(
context = applicationContext,
srcLang = "zh-CN",
dstLang = "en-US",
scenario = Scenario.LISTEN,
needMt = true,
needTts = true,
) { ready ->
if (!ready) {
TmkTranslationSDK.downloadOfflineModels(
context = applicationContext,
srcLang = "zh-CN",
dstLang = "en-US",
scenario = Scenario.LISTEN,
listener = offlineModelListener,
)
return@checkOfflineModelReadyAsync
}

TmkTranslationSDK.createTmkTranslationRoom(object : CreateRoomCallback {
override fun onSuccess(room: TmkTranslationRoom) {
val channelConfig = TmkTransChannelConfig.Builder()
.setRoom(room)
.setMode(TranslationMode.OFFLINE)
.setScenario(Scenario.LISTEN)
.setSourceLang("zh-CN")
.setTargetLang("en-US")
.setSampleRate(16000)
.setChannelNum(1)
.setModelRootDirectory(
TmkTranslationSDK.defaultOfflineModelRootDirectory(applicationContext)
)
.build()

TmkTranslationSDK.createTranslationChannel(
applicationContext,
channelConfig,
listener,
createChannelCallback,
)
}

override fun onError(errorId: Int, e: Exception) { }
})
}

// 关闭引擎
TmkTranslationSDK.releaseChannel()

一对一模式与收听模式的区别

iOS

项目收听模式一对一模式
Scenario.listen.oneToOne
pcmChannels12
在线是否建房
离线是否建房

Android

项目收听模式一对一模式
ScenarioLISTENONE_TO_ONE
channelNum12
输入 PCM单声道双声道交织
语言方向sourceLang -> targetLang左声道 sourceLang -> targetLang,右声道 targetLang -> sourceLang
TTS 播放单路播放建议按声道缓存后统一播放

下一步