11 KiB
科大讯飞 SparkChain —— 真机自测与回改
配合 科大讯飞SparkChain-全面替换第三方-落地文档.md。
客户端 1.0.3+45 起,连着 ym-dev.ymaikj.com 时 AI 不再调用微软、阿里、字节、谷歌、灵犀:文本和同声优先走端上 SparkChain,密钥还没配时这些能力直接失败,不再退回旧服务。面对面、通话、音视频、EMAI、会议转写还没接到讯飞,所以在这把锁下也不可用。测试后台还没填 sparkchain 密钥时,init 不会被调用。测试服容器要有 AI_ONLY_IFLYTEK=1,正式服不要设。
2026-10-15 电脑上已经连着的两台,下面的命令都用这两台,不要换别的机器对日志:
| 设备 | 标识 | |
|---|---|---|
| 安卓 | 华为 ALN-AL80,Android 12 | 序列号 2MM0223B09017126 |
| 苹果 | 李蒙蒙的 iPhone,iPhone 12 | UDID 00008101-001C684A2651003A |
服务器只连测试服 https://ym-dev.ymaikj.com。.env 的 SERVER_URL 保持这个。不要装到连着 ym.ymaikj.com 的包上测,也不要上架。
耳机用 Echo-one。没戴耳机的用例用手机麦,两套都要测,不要只测一种。
1. 每一轮怎么装
改完代码再升 apps/client/pubspec.yaml 的构建号,日志里要能对上是哪一轮。
安卓(在 apps/client 下):
export GRADLE_USER_HOME="$HOME/.gradle"
~/flutter/bin/flutter build apk --release --no-pub --obfuscate --split-debug-info=./build/app/outputs/symbols
adb -s 2MM0223B09017126 install -r build/app/outputs/flutter-apk/app-release.apk
苹果:
./ios/sync_spm_platform.sh
~/flutter/bin/flutter build ipa --release --no-pub --obfuscate --split-debug-info=./build/ios/symbols --export-method development
xcrun devicectl device install app --device 00008101-001C684A2651003A build/ios/ipa/EAIMAR.ipa
flutter build ipa 会改 ios/Runner.xcodeproj/project.pbxproj,那是本地噪声,不要提交。
装完先看关于页或日志里的构建号,对不上就不要开始用例。
2. 日志怎么拿
安卓。*:S 在 zsh 里必须加引号,否则会被当成通配符:
adb -s 2MM0223B09017126 logcat -c
adb -s 2MM0223B09017126 logcat -v time 'EmaiFocus:I' 'flutter:I' '*:S'
苹果不靠 syslog。App 自己的文件在 Documents/logs/:
xcrun devicectl device info files --device 00008101-001C684A2651003A \
--domain-type appDataContainer --domain-identifier com.yimai.eaimar | grep logs
xcrun devicectl device copy from --device 00008101-001C684A2651003A \
--domain-type appDataContainer --domain-identifier com.yimai.eaimar \
--source Documents/logs/<刚列出来的最新文件> --destination /tmp/eaimar.log
copy from 不要加 --username。
日志里允许出现 init 返回码和 sid。出现 apiKey、apiSecret、ast_apisecret 的原文,这一轮算失败,先把打印删掉再测功能。
3. 测之前确认
- 手机网络正常,打开 App 后请求的是
ym-dev,不是ym.ymaikj.com。 - 测试后台应用是
ym,sparkchain已启用,三个密钥非空。sparkchain的类别不是端到端(类别 4)。 - 旧的微软/阿里语音服务先还留着,等第 9 步全部用例过了再在测试服停用。
- 杀进程冷启动一次再测。热重载看不出原生 SDK 有没有 init。
init 失败时先看这三行,不要改业务页面:
| 日志 | 含义 | 改哪里 |
|---|---|---|
返回码 18400 或 18105 |
工作目录不可写 | workDir 改到应用私有目录 |
| 配置为空、init 没被调用 | 没拿到 v3 密钥 | 测试后台、白名单 user_getappconfig_v3、客户端是否连的 ym-dev |
| 只有一路有识别 | 第二路回调被释放,或两路同时 start | 回调改强引用;A 起来约 1.2 秒再起 B |
4. 用例
每一条都要在华为和 iPhone 上各做一次。结果记在第 6 节的表里。没写「通过」的不要进入下一条的代码修改,先把失败的这一条收掉。
耳机相关的条目前提是 Echo-one 已连接。日志里要能看到对应的麦,而不是手机麦。
4.1 插件冒烟(不进业务页也能看日志)
| 编号 | 做什么 | 通过 |
|---|---|---|
| S1 | 冷启动 | 日志有 init 成功,节点是新加坡(欧洲账号未加白时,人在欧洲也是新加坡)。无私钥 |
| S2 | 中文说一句短句 | 听写出中文 |
| S3 | 文本「你好」译成英文 | 安卓走 GTRANS。iOS 四个翻译类型里,把能返回英文的那个类型写进第 6 节 |
| S4 | 文本「你好」译成爱尔兰语 | 译文是爱尔兰语,语种码 ga。iOS 实际用的 TransType 写进第 6 节 |
| S5 | 把 S4 的爱尔兰语再合成 | 安卓出声,音色是 ga-IE-OrlaNeural。iOS 不出声就停在这一条,不要装进同声翻译冒充已支持 |
S3 到 S5 没过,不要测同声和通话。后面全靠这三步。
4.2 同声翻译
| 编号 | 做什么 | 通过 | 失败先看 |
|---|---|---|---|
| M1 | 连耳机,中文→英文 | 日志是「同声翻译收音:耳机麦」,有首帧;译文从耳机出 | 麦走错了看 _attachSimultaneousHeadsetMic。声音在手机扬声器看 pinSpeaker 是不是被改成 true,以及 SDK 有没有自己开麦 |
| M2 | 不连耳机,中文→英文 | 手机麦能出字、出声 | SDK 自己开麦会和现有采集抢,改成只 write 现有 PCM |
| M3 | M1 进行中按 Home 切后台,继续说 | 还能出字 | 前台服务 keepalive: true, pinSpeaker: false,iOS BackgroundKeepalive('simultaneous') |
| M4 | 连耳机,中文→爱尔兰语 | 文字和声音都是爱尔兰语,不走 AST |
安卓:识别 ga-IE,翻译 GTRANS/ga,合成 ga-IE-OrlaNeural。iOS 用 S4/S5 记下来的参数 |
4.3 面对面
| 编号 | 做什么 | 通过 |
|---|---|---|
| F1 | 双耳戴上,左中文、右英文 | 方向相反,两边都有声音。协议帧没有改 |
| F2 | 右耳改说爱尔兰语 | 本端有中文译文。iOS 若 S5 没过,这条只要求出字,出声标成「等音色」 |
| F3 | 摘掉耳机再开 | 手机麦仍能翻,不要退回成失败 |
| F4 | 翻译中来电 | 现有文案还在,会话停 |
安卓面对面不要顺手加上同声那种静音保活。
4.4 音视频
| 编号 | 做什么 | 通过 |
|---|---|---|
| V1 | 安卓:允许悬浮窗和录屏,切到别的 App 播一段中文 | 悬浮窗有英文译文,原视频声音还在,没有被译文盖住 |
| V2 | 安卓:拒绝悬浮窗 | 不开始识别 |
| V3 | iPhone:开始广播,切后台 | 小窗有字,原视频声音还在 |
| V4 | 从音视频切到同声 | 小窗关掉 |
4.5 通话翻译
不退出通话翻译页,按顺序做。A 是近端(自己),B 是远端(对方)。
| 编号 | 做什么 | 通过 | 失败先看 |
|---|---|---|---|
| C1 | 中文↔英文,双方各说一句 | 两边都有字,声音在耳机里 | pinSpeaker: false。PCM 走 callPcmTap / com.eaimar.bes.callpcm.uplink,不要接成面对面那条 |
| C2 | 停掉,不退出页面,再开一场中英 | 仍有识别和声音 | ready 被 disable 清掉了。只在会话销毁时清 |
| C3 | 中文→爱尔兰语。自己说中文 | 自己这边有爱尔兰语文字,对方耳机里听到爱尔兰语 | A 路合成。iOS 依赖 S5 |
| C4 | 接着对方说爱尔兰语 | 自己这边有爱尔兰语原文、中文译文、耳机里的中文。不要做中文/爱尔兰语自动检测 | B 路回调是不是强引用。日志里 B 路有帧但没有识别,就是回调被释放 |
C1 里如果只有近端有字、远端完全没有,先看 B 路回调和 1.2 秒间隔,不要改语种码。
4.6 EMAI
手机里按住说话的那一页不测。
| 编号 | 做什么 | 通过 |
|---|---|---|
| E1 | 耳机按键唤醒 | 听到「我在 / 回来了 / 有什么可以帮到你」里的一句,不等用户先说话 |
| E2 | 问一句 | 有文字和声音。说完再答,不要按百炼那种边听边说来判失败 |
| E3 | 「明天下午三点提醒我开会」 | 能进待办。进不去就只记「工具未通」,不要改待办解析 |
| E4 | 对话中切后台 | 不断开 |
| E5 | 没在播音乐时唤醒再结束 | 不要自己把音乐播出来 |
| E6 | 有音乐在播时唤醒 | 音乐变小或暂停;结束后恢复。香薰也做这一条 |
| E7 | 密钥配错或 init 失败时按唤醒 | 设备退出聆听,不空等 |
声音发飘、像慢放或快放:合成没有按 16 kHz 送进喇叭,百炼的 24000 被套过来了。
4.7 文本页、图片、纪要
| 编号 | 做什么 | 通过 |
|---|---|---|
| T1 | 文本页中英、中文→爱尔兰语 | 出字。断网或端上失败时,请求打到测试服 user_translate,不是微软直连 |
| P1 | 图片翻译一张带字的图 | 有原文和译文。没有把译文贴回原图,这是现状 |
| R1 | 同声或通话翻完进语音纪要 | 有音频、端上那份转写、总结。服务端没有把这段再转写一遍 |
| R2 | 纪要首页新录一条中文、一条英文 | 测试服日志里的转写服务是 asrfile_iflytek,总结是 llm_iflytek。失败退算力只退一次 |
R2 依赖测试服已经按落地文档第 6 节发过 home,并且会议配置里讯飞的优先级高于旧服务。正式服不会有这条数据。
5. 一轮失败了怎么改
一次只改失败表里指出的那一处,然后两台都重装,重测失败的那一条,再加一条已经通过的相邻用例,防止改坏。
| 现象 | 只改 |
|---|---|
| 安卓有、iOS 没有,或相反 | 该端原生枚举。不要改 Dart 的 zh / en / ga,也不要把另一端的枚举抄过来 |
| 有识别文字、没有声音 | 合成回调有没有把 PCM 交给现有播放器或 CallTranslationDownlink。不要在插件里新开 AudioTrack |
| 声音从耳机跑到手机喇叭 | pinSpeaker 和 SDK 是否自己开了麦、改了音频会话 |
| 同页第二场通话没声音 | ready |
| 切后台没反应 | 保活调用点。不要改音乐焦点那一套 |
| 没播的音乐被拉起来 | 设备对话的焦点。没在播就不要抢焦点、不要发播放键 |
| 爱尔兰语走成了中英同传 | 选路把 ga 送进了 AST。ga 强制三段 |
| 纪要仍是字节/阿里/微软 | 测试服会议配置的优先级,或 home 镜像还是旧的。不要去正式服改 |
iOS 爱尔兰语翻译类型、识别 region、音色名,一旦真机确定,写回落地文档第 4.5 节,把「先试四个类型」改成确定值。没确定之前不要在文档里写成已经支持。
6. 记录
每轮测完填一行。构建号和日志对不上的结果不算。
| 日期 | 构建号 | 端 | 用例 | 结果 | 日志里的一句 | 下一轮只改 |
|---|---|---|---|---|---|---|
| 华为 / iPhone | 过 / 不过 |
iOS 爱尔兰语定下来之后补这一行,后面的用例都用它:
| 项 | 真机确定的值 |
|---|---|
翻译 TransType |
|
| 识别 region 和语种码 | |
| 合成 region 和音色 | |
| 是否出声 |