import 'dart:async'; import 'dart:convert'; import 'package:flutter_webrtc/flutter_webrtc.dart'; import '../models/signal_message.dart'; import '../proto/control_message.pb.dart'; import '../signaling/signaling_client.dart'; import '../webrtc/webrtc_controller.dart'; /// 控制端编排器:组合信令客户端与 WebRTC 控制器, /// 对外暴露连接/断开/发送指令等高层接口(对应 Android 端 MainActivity 的流程)。 class RemoteController { final String serverUrl; final String deviceId; final String targetDeviceId; late final SignalingClient _signaling; WebRtcController? _webRtc; Timer? _statsTimer; /// 信令状态变化(如“正在连接…”、“已连接…”)。 void Function(String status)? onStatusChanged; /// WebRTC 连接建立(可开始远程控制)。 void Function()? onConnectionEstablished; /// 连接断开。 void Function()? onDisconnected; /// ICE 连接断开(用于提示用户并返回连接设置)。 void Function(String message)? onIceDisconnected; /// 目标被控端不在线(服务器回送 TARGET_OFFLINE,用于提示用户并复位 UI)。 void Function(String message)? onTargetOffline; /// 远端视频渲染器就绪。 void Function(RTCVideoRenderer renderer)? onRemoteStream; /// 统计信息刷新(每秒一次)。 void Function(String stats)? onStats; RemoteController({ required this.serverUrl, required this.deviceId, required this.targetDeviceId, }); /// 发起连接:先连接信令服务器,成功后建立 WebRTC 并创建 Offer。 void connect() { onStatusChanged?.call('状态: 正在连接信令服务器...'); _signaling = SignalingClient(serverUrl: serverUrl, deviceId: deviceId); _signaling.onConnected = () { onStatusChanged?.call('状态: 已连接信令服务器,正在发起连接...'); _initWebRtc(); }; _signaling.onMessage = _handleSignalMessage; _signaling.onDisconnected = () { onStatusChanged?.call('状态: 已断开连接'); onDisconnected?.call(); }; _signaling.onError = (error) { onStatusChanged?.call('状态: 连接错误 - $error'); }; _signaling.connect(); } void _initWebRtc() { _webRtc = WebRtcController( signaling: _signaling, deviceId: deviceId, targetDeviceId: targetDeviceId, ); _webRtc!.onConnectionEstablished = () { onConnectionEstablished?.call(); _startStats(); }; _webRtc!.onDisconnected = () { onDisconnected?.call(); }; _webRtc!.onIceDisconnected = (message) => onIceDisconnected?.call(message); _webRtc!.onRemoteStream = (renderer) => onRemoteStream?.call(renderer); _webRtc!.initialize().catchError((e) { onStatusChanged?.call('状态: 连接失败 - $e'); }); } void _handleSignalMessage(SignalMessage message) { switch (message.type?.toUpperCase()) { case 'ANSWER': final payload = jsonDecode(message.payload!) as Map; _webRtc?.handleAnswer(payload['sdp'] as String); break; case 'ICE_CANDIDATE': final payload = jsonDecode(message.payload!) as Map; _webRtc?.handleIceCandidate(payload); break; case 'TARGET_OFFLINE': final text = message.payload ?? '目标被控端不在线,请确认设备已开启并连接服务器'; onStatusChanged?.call('状态: $text'); onTargetOffline?.call(text); break; } } void _startStats() { _statsTimer?.cancel(); _statsTimer = Timer.periodic(const Duration(seconds: 1), (_) async { final text = await _webRtc?.getStatsText(); if (text != null && text.isNotEmpty) { onStats?.call(text); } }); } /// 发送控制指令(protobuf 二进制)。 void sendControlCommand(ControlMessage command) { _webRtc?.sendControlCommand(command); } /// 断开连接并释放资源。 Future disconnect() async { _statsTimer?.cancel(); _statsTimer = null; await _webRtc?.close(); _webRtc = null; _signaling.disconnect(); } }