AR-Test-Demo/avatar_flutter_app/lib/voice_chat/speech_engine_plugin.dart
zyc 689fa8936b Integrate Volcengine realtime voice + Live2D mouth driving
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 15:39:23 +08:00

66 lines
2.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:flutter/services.dart';
/// Dart 侧对 iOS SpeechEnginePlugin 的包装。
///
/// 所有方法都 forwards 到 MethodChannel事件流通过 [events] 暴露原始字典,
/// 上层 VoiceChatController 负责解析为状态变化。
class SpeechEnginePlugin {
static const MethodChannel _method =
MethodChannel('avatar_flutter_app/speech_engine');
static const EventChannel _event =
EventChannel('avatar_flutter_app/speech_events');
Stream<Map<String, dynamic>>? _events;
/// 事件流:每个事件都是 `{type: ..., ...payload}` 形式的 Map。
/// type 取值engine_start / engine_stop / engine_error /
/// asr_partial / asr_end / chat_partial / chat_end /
/// mouth_value / raw
Stream<Map<String, dynamic>> get events =>
_events ??= _event.receiveBroadcastStream().map(_castMap);
static Map<String, dynamic> _castMap(dynamic raw) {
if (raw is Map) {
return raw.map((k, v) => MapEntry(k.toString(), v));
}
return {'type': 'raw', 'payload': raw?.toString() ?? ''};
}
Future<void> init({
required String appId,
required String appKey,
required String token,
required String dialogId,
required String uid,
required String address,
required String uri,
String botName = '豆包',
String aecModelPath = '',
}) async {
await _method.invokeMethod('init', {
'appId': appId,
'appKey': appKey,
'token': token,
'dialogId': dialogId,
'uid': uid,
'address': address,
'uri': uri,
'botName': botName,
'aecModelPath': aecModelPath,
});
}
Future<void> start() => _method.invokeMethod('start');
Future<void> startTalking() => _method.invokeMethod('startTalking');
Future<void> finishTalking() => _method.invokeMethod('finishTalking');
Future<void> pauseTalking() => _method.invokeMethod('pauseTalking');
Future<void> resumeTalking() => _method.invokeMethod('resumeTalking');
Future<void> cancelCurrentDialog() => _method.invokeMethod('cancelCurrentDialog');
Future<void> sayHello(String content) =>
_method.invokeMethod('sayHello', {'content': content});
Future<void> stop() => _method.invokeMethod('stop');
Future<void> destroy() => _method.invokeMethod('destroy');
}