using FISLib.Connect; using FISLib.Hardware; using FISLib.LiveVideo; using FISLib.Remedical; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Vinno.FIS.Sonopost.Common; using Vinno.FIS.Sonopost.Features.Dicom; using Vinno.FIS.Sonopost.Managers.Interfaces; using Vinno.FIS.Sonopost.Settings; using Vinno.IUS.Common.Log; namespace Vinno.FIS.Sonopost.Managers { internal class LiveVideoManager : SonopostManager, ILiveVideoManager { private readonly ILoginManager _loginManager; private readonly ILiveVideoService _fisLiveVideoService; private readonly IRemedicalManager _remedicalManager; private readonly IKeyBoardListenManager _keyBoardListenManager; private IDeviceManager _deviceManager; private CameraSettingForSonopost _cameraSetting; private bool _isRecording; private AutoResetEvent _checkImageRecordEvent = new AutoResetEvent(false); /// /// 超声高清采集卡名称列表 /// public List SonoDeviceNames { get; private set; } /// /// 超声采集卡名称 /// public FISCameraInfo SonoDevice { get; private set; } public event EventHandler PreviewImageReceived; public LiveVideoManager() { _loginManager = AppManager.Instance.GetManager(); _loginManager.LoginStatusChanged += OnLoginStatusChanged; _keyBoardListenManager = AppManager.Instance.GetManager(); _keyBoardListenManager.LeftKeyPressedEvent += OnLeftKeyPressedEvent; _keyBoardListenManager.RightKeyPressedEvent += OnRightKeyPressedEvent; _fisLiveVideoService = AppManager.Instance.GetManager().FISLiveVideoService; _fisLiveVideoService.PreviewCameraCaptured += OnPreviewCameraCaptured; _fisLiveVideoService.CaptureImageGenerated += OnCaptureImageGenerated; _fisLiveVideoService.RecordVideoGenerated += OnRecordVideoGenerated; _remedicalManager = AppManager.Instance.GetManager(); _cameraSetting = new CameraSettingForSonopost(false, FISLiveChannelCategory.Main, new List(), new FISRainbowImageDetectConfig() { IsDetectRainbowImage = SonopostSystemSettings.Instance.RainbowImageDetectSetting.IsDetectRainbowImage, BeforeDisableIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.BeforeDisableIntervalTime, BeforeEnableIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.BeforeEnableIntervalTime, AfterEnableIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.AfterEnableIntervalTime, ScanIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.ScanIntervalTime, CaptureCardList = SonopostSystemSettings.Instance.RainbowImageDetectSetting.CaptureCardList.ToList(), }, new FISMicDeviceInfo()); } public void Init() { _deviceManager = AppManager.Instance.GetManager(); SonoDeviceNames = SonopostSystemSettings.Instance.InputDeviceNames.ToList(); var cameras = _deviceManager.GetCameras(); if (cameras != null) { foreach (var camera in cameras) { if (SonoDeviceNames.Contains(camera.Name.Trim())) { var capbilities = camera.Capabilities.Where(x => x.Width <= 1920 && x.Height <= 1080).ToList(); SonoDevice = new FISCameraInfo(camera.Id, camera.Name, camera.HardwareId, capbilities); } } } } private void OnLeftKeyPressedEvent(object sender, EventArgs e) { try { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { Logger.WriteLineError($"LiveVideoManager OnLeftKeyPressedEvent Invoke Error,please connect the vCloud Server first"); return; } if (!SonopostUserDefinedSettings.Instance.CaptureSetting.RealTimeCaptureEnabled) { Logger.WriteLineError($"LiveVideoManager OnLeftKeyPressedEvent Invoke,But the CaptureEnable is False,so skipped it"); return; } if (SonopostUserDefinedSettings.Instance.CaptureSetting.ImageCaptureKeyForFootToogle == EnumFootToggleKey.LeftKey) { _fisLiveVideoService.CaptureCurrentImage(); } else if (SonopostUserDefinedSettings.Instance.CaptureSetting.VideoCaptureKeyForFootToggle == EnumFootToggleKey.LeftKey) { if (!_isRecording) { _fisLiveVideoService.StartRecordVideo(); TimeJudgment(); _isRecording = true; } else { _fisLiveVideoService.StopRecordVideo(false); _isRecording = false; _checkImageRecordEvent.Set(); } } else { Logger.WriteLineError($"LiveVideoManager OnLeftKeyPressedEvent Error,capture or record is all not left key"); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager OnLeftKeyPressedEvent Error:{ex}"); } } private void OnRightKeyPressedEvent(object sender, EventArgs e) { try { if (_loginManager.DeviceStatus != DeviceStatus.Logon) { Logger.WriteLineError($"LiveVideoManager OnRightKeyPressedEvent Invoke Error,please connect the vCloud Server first"); return; } if (!SonopostUserDefinedSettings.Instance.CaptureSetting.RealTimeCaptureEnabled) { Logger.WriteLineError($"LiveVideoManager OnRightKeyPressedEvent Invoke,But the CaptureEnable is False,so skipped it"); return; } if (SonopostUserDefinedSettings.Instance.CaptureSetting.ImageCaptureKeyForFootToogle == EnumFootToggleKey.RightKey) { _fisLiveVideoService.CaptureCurrentImage(); } else if (SonopostUserDefinedSettings.Instance.CaptureSetting.VideoCaptureKeyForFootToggle == EnumFootToggleKey.RightKey) { if (!_isRecording) { _fisLiveVideoService.StartRecordVideo(); TimeJudgment(); _isRecording = true; } else { _fisLiveVideoService.StopRecordVideo(false); _isRecording = false; _checkImageRecordEvent.Set(); } } else { Logger.WriteLineError($"LiveVideoManager OnRightKeyPressedEvent Error,capture or record is all not left key"); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager OnRightKeyPressedEvent Error:{ex}"); } } private void TimeJudgment() { Task.Run(() => { try { _checkImageRecordEvent.Reset(); _checkImageRecordEvent.WaitOne(30000); if (_isRecording) { _fisLiveVideoService.StopRecordVideo(true); _isRecording = false; } } catch (Exception ex) { Logger.WriteLineError($"LivevideoManager TimeJudgment Error:{ex}"); } }); } private void OnCaptureImageGenerated(object sender, string e) { try { if (string.IsNullOrEmpty(e)) { Logger.WriteLineError($"Capture Image Generated Failed ,File Path is null"); return; } if (!File.Exists(e)) { Logger.WriteLineError($"Capture Image Generated Failed: {e} is not exist"); return; } if (Path.GetExtension(e).ToLower() != $".{SonopostConstants.VidFileName}") { Logger.WriteLineError($"Capture Image Generated Failed: {e} is not vid file"); return; } var vidInfo = new VidInfo() { VidFilePath = e, }; if (_loginManager.DeviceStatus == DeviceStatus.Logon) { var examRecordId = _remedicalManager.GetCollcetingRecordCode(); if (!string.IsNullOrEmpty(examRecordId)) { Logger.WriteLineInfo($"LiveVideoManager GetCollcetingRecordCode Result is {examRecordId}"); var detailInfo = _remedicalManager.GetCloudExamInfo(examRecordId); if (detailInfo == null) { Logger.WriteLineError($"LiveVideoManager GetCloudExamInfo {examRecordId} Result is null"); } else { if (detailInfo.RecordStatus == FISRecordStatus.NotScanned || detailInfo.RecordStatus == FISRecordStatus.Uploaded) { vidInfo.ExamRecordId = examRecordId; vidInfo.PatientInfo = detailInfo.PatientScanInfo; } Logger.WriteLineInfo($"{examRecordId} ExamStatus is {detailInfo.RecordStatus}"); } } } DicomUploadQueue.Instance.Enqueue(vidInfo); } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager OnCaptureImageGenerated Error:{ex}"); } } private void OnRecordVideoGenerated(object sender, string e) { try { if (string.IsNullOrEmpty(e)) { Logger.WriteLineError($"Record Video Generated Failed, File Path is null"); return; } if (!File.Exists(e)) { Logger.WriteLineError($"Record Video Generated Failed: {e} is not exist"); return; } if (Path.GetExtension(e).ToLower() != $".{SonopostConstants.VidFileName}") { Logger.WriteLineError($"Record Video Generated Failed: {e} is not vid file"); return; } var vidInfo = new VidInfo() { VidFilePath = e, }; if (_loginManager.DeviceStatus == DeviceStatus.Logon) { var examRecordId = _remedicalManager.GetCollcetingRecordCode(); if (!string.IsNullOrEmpty(examRecordId)) { var detailInfo = _remedicalManager.GetCloudExamInfo(examRecordId); if (detailInfo == null) { Logger.WriteLineError($"LiveVideoManager GetCloudExamInfo Result is null"); } else { if (detailInfo.RecordStatus == FISRecordStatus.NotScanned || detailInfo.RecordStatus == FISRecordStatus.Uploaded) { vidInfo.ExamRecordId = examRecordId; vidInfo.PatientInfo = detailInfo.PatientScanInfo; } Logger.WriteLineInfo($"{examRecordId} ExamStatus is {detailInfo.RecordStatus}"); } } } DicomUploadQueue.Instance.Enqueue(vidInfo); } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager OnCaptureImageGenerated Error:{ex}"); } } private void OnPreviewCameraCaptured(object sender, FISImageFrameData e) { try { PreviewImageReceived?.Invoke(this, e); } catch (Exception ex) { Logger.WriteLineError($"Live Video Manager On Preview Camera Captured Error:{ex}"); } } public List GetBrandList() { try { if (_loginManager.DeviceStatus == DeviceStatus.Logon) { return _fisLiveVideoService.GetBrandList(); } return new List(); } catch (Exception e) { Logger.WriteLineError($"GetBrandList Error:{e}"); return new List(); } } public List GetModelList(string brand) { try { if (string.IsNullOrEmpty(brand)) { return new List(); } if (_loginManager.DeviceStatus == DeviceStatus.Logon) { return _fisLiveVideoService.GetModelList(brand); } return new List(); } catch (Exception e) { Logger.WriteLineError($"GetModelList Error:{e}"); return new List(); } } public FISDeviceRecommandResolution GetRecommandResolution(string brand, string model) { try { if (string.IsNullOrEmpty(brand) || string.IsNullOrEmpty(model)) { return null; } return _fisLiveVideoService.GetRecommandResolution(brand, model); } catch (Exception e) { Logger.WriteLineError($"GetRecommandResolution Error:{e}"); return null; } } public void UpdateDeviceResoution() { try { _cameraSetting.CameraPreviewEnabled = false; Logger.WriteLineInfo("LiveVideoManager UpdateDeviceResoution"); var list = new List(); foreach (var device in SonopostUserDefinedSettings.Instance.HardwareSetting.VideoDeviceInfoList) { if (device.IsAvailable && device.IsEnable) { var item = device.Clone() as FISVideoDeviceInfo; list.Add(item); } } _cameraSetting.VideoDeviceInfoList = list; _cameraSetting.MicDeviceInfo = SonopostUserDefinedSettings.Instance.HardwareSetting.MicDeviceInfo; if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisLiveVideoService.ChangeCameraSettingForSonopost(_cameraSetting); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager Update Device Resoution Error:{ex}"); } } public void UpdateRainbowImageDetectSetting() { try { _cameraSetting.RainbowImageDetectConfig.IsDetectRainbowImage = SonopostSystemSettings.Instance.RainbowImageDetectSetting.IsDetectRainbowImage; _cameraSetting.RainbowImageDetectConfig.BeforeDisableIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.BeforeDisableIntervalTime; _cameraSetting.RainbowImageDetectConfig.BeforeEnableIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.BeforeEnableIntervalTime; _cameraSetting.RainbowImageDetectConfig.AfterEnableIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.AfterEnableIntervalTime; _cameraSetting.RainbowImageDetectConfig.ScanIntervalTime = SonopostSystemSettings.Instance.RainbowImageDetectSetting.ScanIntervalTime; if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisLiveVideoService.ChangeCameraSettingForSonopost(_cameraSetting); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager Update RainbowImageDetectSetting Error:{ex}"); } } public void StartPreview(string id, int width, int height, int fps) { try { _cameraSetting.CameraPreviewEnabled = true; var deviceParameter = SonopostUserDefinedSettings.Instance.HardwareSetting.VideoDeviceInfoList; var capturingDevice = deviceParameter.FirstOrDefault(d => d.Id == id && d.IsEnable); if (capturingDevice != null) { _cameraSetting.CurrentLiveChannelCategory = capturingDevice.Category; } else { _cameraSetting.CameraPreviewEnabled = false; _cameraSetting.CurrentLiveChannelCategory = FISLiveChannelCategory.Main; } if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisLiveVideoService.ChangeCameraSettingForSonopost(_cameraSetting); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager Start Preview Error:{ex}"); } } public void StopPreview() { try { _cameraSetting.CameraPreviewEnabled = false; if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisLiveVideoService.ChangeCameraSettingForSonopost(_cameraSetting); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager Stop Preview Error:{ex}"); } } public void ChangeRealTimeCaptureSetting() { try { if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisLiveVideoService.ChangeRealTimeCaptureSetting(SonopostUserDefinedSettings.Instance.CaptureSetting.RealTimeCaptureEnabled); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager ChangeRealTimeCaptureSetting Error:{ex}"); } } private void ReUploadAll() { try { if (_loginManager.DeviceStatus == DeviceStatus.Logon) { _fisLiveVideoService.ReUploadRestVid(); } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager ReuploadRestVids Error:{ex}"); } } public override void DoDispose() { try { _loginManager.LoginStatusChanged -= OnLoginStatusChanged; _keyBoardListenManager.LeftKeyPressedEvent -= OnLeftKeyPressedEvent; _keyBoardListenManager.RightKeyPressedEvent -= OnRightKeyPressedEvent; _fisLiveVideoService.PreviewCameraCaptured -= OnPreviewCameraCaptured; _fisLiveVideoService.CaptureImageGenerated -= OnCaptureImageGenerated; _fisLiveVideoService.RecordVideoGenerated -= OnRecordVideoGenerated; } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager DoDispose Error:{ex}"); } base.DoDispose(); } private void OnLoginStatusChanged(object sender, DeviceStatus e) { switch (e) { case DeviceStatus.Logon: UpdateDeviceResoution(); if (!_loginManager.IsConnectWithOldServer) { ChangeRealTimeCaptureSetting(); ReUploadAll(); } break; default: _isRecording = false; _checkImageRecordEvent.Set(); break; } } public FISBase64ImageData GetCurrentCaptureFrame() { try { return _fisLiveVideoService.GetCurrentCaptureFrame(); } catch (Exception ex) { Logger.WriteLineError($"LiveVideoManager GetCurrentCaptureFrame Error:{ex}"); return new FISBase64ImageData(0, 0, "", FailReasonForNullBase64Data.Unknown); } } } }