tmk_translation_flutter

Timekettle Translation SDK 的 Flutter 插件,通过统一 Dart API 接入 Android 和 iOS 原生翻译能力。

安装

dependencies:
  tmk_translation_flutter: 1.3.1-rc.2
flutter pub get

Android 的原生依赖来自公开 Maven 仓库。iOS 正式接入需要组织批准的 CocoaPods 制品源;该源当前不在本地可访问范围内。本地验证使用 Git LFS 拉取并从 tmk_offline 1.0.9 源码生成的 XCFramework,证据见 SDK 的 docs/flutter_api/verification.md,不会把绝对路径或临时 Pod source 写入项目。

Android 应用必须在 Gradle 仓库配置中同时声明 Maven Central 和公共 Jiagouyun Maven:

repositories {
    google()
    mavenCentral()
    maven(url = "https://mvnrepo.jiagouyun.com/repository/maven-releases")
}

优先将上述仓库加入 settings.gradle.kts 的 dependencyResolutionManagement.repositories;若工程允许项目级仓库,也应在实际生效的 repositories 块中加入相同地址。Jiagouyun 仅用于解析原生 SDK 1.3.1-rc.2 的公开传递依赖,不需要账号或 token。企业网络若启用仓库白名单,需要允许访问 mvnrepo.jiagouyun.com。

Requirements

  • Flutter 3.22 或更高版本、Dart 3.10 或更高版本。
  • Android minSdk 28、Java 17;Timekettle Translation SDK 1.3.1-rc.2 来自 Maven Central,其公开传递依赖通过公共 Jiagouyun Maven 解析。
  • iOS 17.0 或更高版本;使用 CocoaPods Trunk 上的 TmkTranslationSDK 1.3.1-rc.2。

基本用法(冻结的高层 Session API)

import 'package:tmk_translation_flutter/tmk_translation_flutter.dart';

final sdk = TmkTranslationSdk.instance;
await sdk.initialize(const TmkTranslationGlobalConfig(
  appId: String.fromEnvironment('TMK_APP_ID'),
  appSecret: String.fromEnvironment('TMK_APP_SECRET'),
));
await sdk.verifyAuth();

final creation = sdk.createSession(TmkTranslationSessionConfig(
  mode: TmkTranslationMode.online,
  scenario: TmkTranslationScenario.listen,
  sourceLang: 'zh-CN',
  targetLang: 'en-US',
));
final session = await creation.result;
final subscription = session.streams.all.listen((event) {
  // 识别、翻译、状态、音频和结构化错误均为类型化事件。
});

// Example/Sample 负责录音、权限和固定 PCM;Plugin 只接收已经准备好的 PCM。
await session.pushStreamAudioData(pcmBytes, channelCount: 1);
await session.dispose();
await subscription.cancel();
await sdk.destroy();

离线模型联调可在初始化时传入仓库根地址:

await sdk.initialize(TmkTranslationGlobalConfig(
  appId: const String.fromEnvironment('TMK_APP_ID'),
  appSecret: const String.fromEnvironment('TMK_APP_SECRET'),
  offlineModelBaseUrl: Uri.parse(
    'http://192.168.0.56:9999/tmk-models/v3.3/',
  ),
));

offlineModelBaseUrl 为 null 时沿用 Android/iOS 原生 SDK 的默认逻辑。模型仓库需保持 asr/、mt/、tts/ 包路径约定;切源后的下载包只有通过长度、ZIP CRC/结构和模型关键文件校验才会逐包替换旧模型。当前无 SHA-256 元数据,内网 HTTP 仅建议用于测试,宿主也需按平台配置明文网络访问。

如果宿主已经通过原生配置提供凭证(iOS 的 Info.plist/xcconfig 或 Android 的 manifest metadata),appId 和 appSecret 可以传空字符串。Flutter wrapper 会把空值转为 null 交给原生解析;只有宿主配置也缺失时,原生初始化才返回结构化错误。

createSession() 成功即表示原生通道已经创建并启动;创建操作和成功的 TmkTranslationSession 共享同一个 broadcast Streams 实例。取消是幂等的, 取消中的操作统一映射为 2002006 REQUEST_CANCELLED。

Sample 只能通过 package:tmk_translation_flutter/tmk_translation_flutter.dart 消费公开 API。录音、权限申请、固定 PCM、系统播放、页面状态、导航和 UI 均属于 Example/Sample 职责;Plugin 不公开 start()、stop()、Room、Channel、 Listener、MethodChannel 或 Pigeon 类型。

架构

Flutter App
  → tmk_translation_flutter
    → Pigeon host/callback transport(插件内部)
    → Android/iOS Timekettle Translation SDK 1.3.1-rc.2

生成的 Pigeon 代码、原生 coordinator 和 legacy platform-interface compatibility adapter 都是内部实现细节,业务应用无需也不得导入。

License

本包中的 Flutter/Dart wrapper 源代码使用 Apache License 2.0。该许可证不适用于 Android/iOS 原生 Timekettle Translation SDK、翻译服务、账号凭据、翻译/离线模型及模型文件、Timekettle 商标或其他专有材料;这些内容继续受适用的 Timekettle SDK 与服务协议约束。