import 'dart:async'; import 'package:flutter/services.dart'; /// 讯飞 SparkChain。事件从 [events] 来,方法调用只返回启动码。 class SparkChain { static const _method = MethodChannel('sparkchain'); static const _events = EventChannel('sparkchain/events'); static Stream>? _stream; static Stream> get events { _stream ??= _events.receiveBroadcastStream().map((event) { final raw = Map.from(event as Map); return raw.map((key, value) => MapEntry(key.toString(), value)); }); return _stream!; } /// 0 成功。不打印密钥。 static Future init({ required String appId, required String apiKey, required String apiSecret, int apiType = 1, }) async { final code = await _method.invokeMethod('init', { 'appId': appId, 'apiKey': apiKey, 'apiSecret': apiSecret, 'apiType': apiType, }); return code ?? -1; } static Future translate({ required String id, required String from, required String to, required String text, }) async { final code = await _method.invokeMethod('translate', { 'id': id, 'from': from, 'to': to, 'text': text, }); return code ?? -1; } static Future speak({ required String id, required String lang, required String text, String? voice, bool msft = false, }) async { final code = await _method.invokeMethod('speak', { 'id': id, 'lang': lang, 'text': text, if (voice != null) 'voice': voice, 'msft': msft, }); return code ?? -1; } static Future stopSpeak() async { await _method.invokeMethod('stopSpeak'); } /// 文本对话。结果从事件 `kind=llm` 回来,这里只返回启动码。 static Future chat({ required String id, required String query, required String system, required String tools, required bool fresh, }) async { final code = await _method.invokeMethod('chat', { 'id': id, 'query': query, 'system': system, 'tools': tools, 'fresh': fresh, }); return code ?? -1; } /// [lang] 用短码 zh / en / ga。ga 走实时转写,其余走听写。 static Future startListen({ required String id, required String lang, }) async { final code = await _method.invokeMethod('startListen', { 'id': id, 'lang': lang, }); return code ?? -1; } /// 微软区域实时转写。[locale] 是界面语言的区域码,例如 zh-CN。 static Future startMsftListen({ required String id, required String locale, }) async { final code = await _method.invokeMethod('startListen', { 'id': id, 'lang': locale, 'msft': true, 'locale': locale, }); return code ?? -1; } /// 同声拼接用的微软实时转写。lang / accent / domain 由原生写成固定值, /// [locale] 只进 language_name。 static Future startSpliceListen({ required String id, required String locale, }) async { final code = await _method.invokeMethod('startSpliceListen', { 'id': id, 'locale': locale, }); return code ?? -1; } /// 微软同传。识别、翻译、合成在这一条会话里完成。SDK 不自己开麦。 static Future startAst({ required String id, required String lang, required String targetLang, required String speaker, required String astAppId, required String astApiKey, required String astApiSecret, }) async { final code = await _method.invokeMethod('startAst', { 'id': id, 'lang': lang, 'targetLang': targetLang, 'speaker': speaker, 'astAppId': astAppId, 'astApiKey': astApiKey, 'astApiSecret': astApiSecret, }); return code ?? -1; } static Future write(Uint8List pcm) async { final code = await _method.invokeMethod('write', {'pcm': pcm}); return code ?? -1; } static Future stopListen() async { await _method.invokeMethod('stopListen'); } } /// 把界面上的 BCP-47 收成插件认的短码。不认识的原样返回,让原生按失败处理。 String sparkChainShortCode(String code) { final raw = code.trim().toLowerCase().replaceAll('_', '-'); if (raw.isEmpty) return raw; if (raw == 'ga' || raw.startsWith('ga-')) return 'ga'; if (raw == 'zh' || raw.startsWith('zh-')) return 'zh'; if (raw == 'en' || raw.startsWith('en-')) return 'en'; final dash = raw.indexOf('-'); return dash < 0 ? raw : raw.substring(0, dash); }