using JsonRpcLite.Rpc; using System; using System.Collections.Generic; using Vinno.IUS.Common.Log; using Vinno.vCloud.Common.FIS.Remedicals; using Vinno.vCloud.FIS.CrossPlatform.Common; using Vinno.vCloud.FIS.CrossPlatform.Common.Enum; using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo; using Vinno.vCloud.Protocol.Infrastructures; using WingInterfaceLibrary.DTO.Device; using WingInterfaceLibrary.Interface; using WingInterfaceLibrary.LiveConsultation; namespace Vinno.vCloud.Common.FIS.Consultation { internal class ConsultationV2 : IConsultationV2 { private readonly string _deviceId; private readonly JsonRpcClient _client; private readonly string _deviceToken; private bool _disposed; public string ConsultationUrl { get; private set; } /// /// device image frame arrived /// public event EventHandler UltrasoundImageFrameArrived; /// /// device camera frame arrived /// public event EventHandler UltrasoundCameraFrameArrived; /// /// Local camera video frame arrived only for consultation /// public event EventHandler ConsultationLocalVideoFrameArrived; /// /// Remote camera frame arrived only for consultation /// public event EventHandler ConsultationRemoteVideoFrameArrived; /// /// Raised when receive a consultation request from server. /// public event EventHandler ConsultationRequestArrived; /// /// Raised when the consultation is disconnect. /// public event EventHandler ConsultationDisconnected; /// /// Raised when consultation Member Changed /// public event EventHandler ConsultationMemberChangedNotificationArrived; /// /// The consultation recipient /// public ConsultationRecipientV2 ConsultationRecipient { get; } /// /// Chat live video provider, handle different video /// public ConsultationLiveVideoProviderV2 ConsultationLiveVideoProvider { get; } public ConsultationManagerV2 ConsultationManager { get; } /// /// 接收到其他用户的白板信息 /// public event EventHandler InteractiveBoardInfoArrived; /// /// 接收到清除白板信息 /// public event EventHandler ClearInteractiveBoardArrived; /// /// 收到关闭摄像头的通知 /// public event EventHandler> MuteVideoUserListNotifyArrived; /// /// 通知切换到本地病人,当vCloudExamInfo的ExamPairInfo的PatientIdInUSMachine为空时需先创建病人及检查,否则直接跳到该病人。 /// public event EventHandler SwitchToLocalPatientEvent; /// /// 当开始Web会诊时 /// public event EventHandler StartWebConsultationEvent; /// /// 当切换病人时触发,病人信息与会诊code变更 /// public event EventHandler ChangeLiveConsultationEvent; /// /// 当扫查手法摄像头开启或关闭时触发 /// public event EventHandler TerminalInfoChangedEvent; public ConsultationV2(JsonRpcClient client, string token, CacheDeviceDTO deviceInfo) { if (!string.IsNullOrEmpty(vCloudServerConfig.Instance.FISWebUrl)) { ConsultationUrl = vCloudServerConfig.Instance.FISWebUrl + "#/login/"; } _deviceId = deviceInfo?.DeviceCode; _client = client; _deviceToken = token; var liveConsultationService = _client?.CreateProxy(); var userService = _client?.CreateProxy(); var deviceService = _client?.CreateProxy(); var organizationService = _client?.CreateProxy(); ConsultationLiveVideoProvider = new ConsultationLiveVideoProviderV2(liveConsultationService, organizationService); ConsultationLiveVideoProvider.OnTRTCRoomEnterError += OnTRTCRoomEnterErrorHappened; ConsultationLiveVideoProvider.ConsultationLocalVideoFrameArrived += OnConsultationLocalVideoFrameArrived; ConsultationLiveVideoProvider.ConsultationRemoteVideoFrameArrived += OnConsultationRemoteVideoFrameArrived; ConsultationLiveVideoProvider.DeviceCameraFrameArrived += OnUltrasoundCameraFrameArrived; ConsultationManager = new ConsultationManagerV2(liveConsultationService); ConsultationManager.SwitchToLocalPatientEvent += OnSwitchToLocalPatientEvent; ConsultationRecipient = new ConsultationRecipientV2(ConsultationLiveVideoProvider, ConsultationManager, _deviceId, liveConsultationService, userService, deviceService); ConsultationRecipient.ConsultationDisconnected += OnConsultationDisconnected; ConsultationRecipient.ConsultationRequestArrived += OnConcultationRequestArrived; ConsultationRecipient.ConsultationMemberChangedNotificationArrived += OnConsultationMemberChangedNotificationArrived; ConsultationRecipient.InteractiveBoardInfoArrived += OnInteractiveBoardInfoArrived; ConsultationRecipient.ClearInteractiveBoardArrived += OnClearInteractiveBoardArrived; ConsultationRecipient.MuteVideoUserListNotifyArrived += OnMuteVideoUserListNotifyArrived; ConsultationRecipient.StartWebConsultationEvent += OnStartWebConsultationEvent; ConsultationRecipient.ChangeLiveConsultationEvent += OnChangeLiveConsultationEvent; ConsultationRecipient.TerminalInfoChangedEvent += OnTerminalInfoChangedEvent; } private void OnTerminalInfoChangedEvent(object sender, TerminalInfo e) { TerminalInfoChangedEvent?.Invoke(this, e); } private void OnStartWebConsultationEvent(object sender, string e) { StartWebConsultationEvent?.Invoke(this, e); } private void OnSwitchToLocalPatientEvent(object sender, vCloudExamInfo e) { SwitchToLocalPatientEvent?.Invoke(this, e); } private void OnMuteVideoUserListNotifyArrived(object sender, List muteVideoUserList) { MuteVideoUserListNotifyArrived?.Invoke(this, muteVideoUserList); } private void OnInteractiveBoardInfoArrived(object sender, InteractiveBoardInfo e) { InteractiveBoardInfoArrived?.Invoke(this, e); } private void OnClearInteractiveBoardArrived(object sender, string e) { ClearInteractiveBoardArrived?.Invoke(this, e); } /// /// Gets the live states of the current chat. /// /// public LiveStates GetCurrentConsultationLiveStates() { return ConsultationRecipient.CurrentLiveStatus; } /// /// Dispose consultation /// public void Dispose() { DoDispose(); GC.SuppressFinalize(this); } private void DoDispose() { if (!_disposed) { var consultationtatus = GetCurrentConsultationLiveStates(); var isConsultation = consultationtatus == LiveStates.RecipientAcceptted || consultationtatus == LiveStates.ChatRequestArrived || consultationtatus == LiveStates.InitiatorRequestingChat || consultationtatus == LiveStates.RecipientAcceptting; if (isConsultation) { HangupLiveConsultationFromFlutter(true); } ConsultationLiveVideoProvider.OnTRTCRoomEnterError -= OnTRTCRoomEnterErrorHappened; ConsultationLiveVideoProvider.ConsultationLocalVideoFrameArrived -= OnConsultationLocalVideoFrameArrived; ConsultationLiveVideoProvider.ConsultationRemoteVideoFrameArrived -= OnConsultationRemoteVideoFrameArrived; ConsultationLiveVideoProvider.DeviceCameraFrameArrived -= OnUltrasoundCameraFrameArrived; ConsultationLiveVideoProvider.Dispose(); ConsultationRecipient.ConsultationDisconnected -= OnConsultationDisconnected; ConsultationRecipient.ConsultationRequestArrived -= OnConcultationRequestArrived; ConsultationRecipient.ConsultationMemberChangedNotificationArrived -= OnConsultationMemberChangedNotificationArrived; ConsultationRecipient.InteractiveBoardInfoArrived -= OnInteractiveBoardInfoArrived; ConsultationRecipient.ClearInteractiveBoardArrived -= OnClearInteractiveBoardArrived; ConsultationRecipient.MuteVideoUserListNotifyArrived -= OnMuteVideoUserListNotifyArrived; ConsultationRecipient.StartWebConsultationEvent -= OnStartWebConsultationEvent; ConsultationRecipient.ChangeLiveConsultationEvent -= OnChangeLiveConsultationEvent; ConsultationRecipient.TerminalInfoChangedEvent -= OnTerminalInfoChangedEvent; ConsultationRecipient.Dispose(); ConsultationManager.SwitchToLocalPatientEvent -= OnSwitchToLocalPatientEvent; ConsultationManager.Dispose(); _disposed = true; } } private void OnChangeLiveConsultationEvent(object sender, ChangeLiveConsultationrResult e) { ChangeLiveConsultationEvent?.Invoke(this, e); } private void OnConcultationRequestArrived(object sender, ConsultationInfo e) { CrossPlatformHelper.Instance.HardwareDetector.StopCameraPreview(); ConsultationRequestArrived?.Invoke(this, e); } private void OnConsultationMemberChangedNotificationArrived(object sender, ConsultationMemberNotificaiton e) { ConsultationMemberChangedNotificationArrived?.Invoke(this, e); } private void OnTRTCRoomEnterErrorHappened(object sender, EnumTRTCRoomError e) { Logger.WriteLineError($"Consultation TRTCRoomEnterErrorHappened:{e}"); } private void OnUltrasoundCameraFrameArrived(object sender, CPVideoFrameData e) { UltrasoundCameraFrameArrived?.Invoke(this, e); } private void OnConsultationRemoteVideoFrameArrived(object sender, ConsultationVideoFrameData e) { ConsultationRemoteVideoFrameArrived?.Invoke(this, e); } private void OnConsultationLocalVideoFrameArrived(object sender, ConsultationVideoFrameData e) { ConsultationLocalVideoFrameArrived?.Invoke(this, e); } private void OnConsultationDisconnected(object sender, ConsultationDisconnectedType e) { ConsultationDisconnected?.Invoke(this, e); } public ResultInfoDTO StartLiveConsultationFromFlutter(LiveConsultationRequestDTO liveConsultationRequestDTO, string cameraId, string micId, string speakerId) { if (liveConsultationRequestDTO == null) { return new ResultInfoDTO { IsSuccess = false, FailMessage = "ConsultationV2 StartLiveConsultationFromFlutter Fail:Args is null", }; } return ConsultationRecipient.StartLiveConsultation(liveConsultationRequestDTO, cameraId, micId, speakerId); } public ResultInfoDTO StartLiveConsultationFromFlutter(StartOnlyForRtmpPushingDTO startOnlyForRtmpPushingDTO, string cameraId, string micId) { if (startOnlyForRtmpPushingDTO == null) { return new ResultInfoDTO { IsSuccess = false, FailMessage = "ConsultationV2 StartLiveConsultationFromFlutter Fail:Args is null", }; } return ConsultationRecipient.StartLiveConsultation(startOnlyForRtmpPushingDTO, cameraId, micId); } public string GetUserInfo(string token) { return ConsultationRecipient.GetUserInfo(token); } public ResultInfoDTO HangupLiveConsultationFromFlutter(bool isInteractiveExit) { var result = ConsultationRecipient.Hangup(); if (isInteractiveExit) { OnConsultationDisconnected(this, ConsultationDisconnectedType.HangUpBySelf); } else { OnConsultationDisconnected(this, ConsultationDisconnectedType.HangupByOther); } return result; } /// /// 切换会诊病人 /// /// /// public ResultInfoDTO ChangeLiveConsultationFromFlutter(ChangeLiveConsultationRequestDTO changeLiveConsultation0RequestDTO) { return ConsultationRecipient.ChangeLiveConsultation(changeLiveConsultation0RequestDTO); } public ResultInfoDTO SwitchToLocalPatientFromFlutter(SwitchToLocalPatientRequestDTO switchToLocalPatientRequestDTO) { return ConsultationManager.SwitchToLocalPatientFromFlutter(switchToLocalPatientRequestDTO); } /// /// 上报本地与云端病人的关联信息 /// /// /// public bool UpdatePatientPairInfo(PatientPairInfo patientPairInfo) { return ConsultationManager.UpdatePatientPairInfo(patientPairInfo); } public ResultInfoDTO LiveConsultationMemberChangedFromFlutter(ConsultationMemberChangeDTO consultationMemberChangeDTO) { return ConsultationRecipient.LiveConsultationMemberChanged(consultationMemberChangeDTO); } /// /// 当收到白板信息的时候 /// /// /// public ResultInfoDTO ReceiveWhiteBoardDataFromFlutter(WhiteBoardDataDTO whiteBoardDataDTO) { return ConsultationRecipient.ReceiveWhiteBoardData(whiteBoardDataDTO); } public ResultInfoDTO SendFlutterLiveConsultationInfo(FlutterLiveConsultationInfo flutterLiveConsultationInfo) { if (flutterLiveConsultationInfo == null) { Logger.WriteLineError($"SendFlutterLiveConsultationInfo Error:Args is null"); return new ResultInfoDTO { IsSuccess = false, FailMessage = "Args is null", }; } if (!flutterLiveConsultationInfo.IsStartLiveConsultation) { ConsultationRecipient.Hangup(true); OnConsultationDisconnected(this, ConsultationDisconnectedType.HangUpBySelf); return new ResultInfoDTO { IsSuccess = true, }; } else { if (string.IsNullOrEmpty(flutterLiveConsultationInfo.LiveConsultationFlutterUrl)) { Logger.WriteLineError($"SendFlutterLiveConsultationInfo Error:url is null"); return new ResultInfoDTO { IsSuccess = false, FailMessage = "Url is null", }; } if (string.IsNullOrEmpty(flutterLiveConsultationInfo.ConsulationId)) { Logger.WriteLineError($"SendFlutterLiveConsultationInfo Error:consultationId is null"); return new ResultInfoDTO { IsSuccess = false, FailMessage = "consultationId is null", }; } else { return ConsultationRecipient.StartWebConsultation(flutterLiveConsultationInfo); } } } public ResultInfoDTO SwitchVideoPlayFromFlutter(string userId, bool isVideoOpen) { if (string.IsNullOrEmpty(userId)) { return new ResultInfoDTO { IsSuccess = false, FailMessage = "UserId is null", }; } return ConsultationRecipient.SwitchVideoPlay(userId, isVideoOpen); } /// /// 是否第二屏会诊或者使用FIS会诊中 /// /// public bool CheckLiveConsultationState() { return ConsultationRecipient.IsSecondViewMode || ConsultationRecipient.CurrentLiveStatus == LiveStates.RecipientAcceptted || ConsultationRecipient.CurrentLiveStatus == LiveStates.RecipientAcceptting; } } }