using System; using System.Collections.Generic; using System.IO; using System.Linq; using Vinno.FIS.TRTCClient.Common.Enum; using Vinno.IUS.Common.Log; using Vinno.vCloud.Common.FIS.Helper; using Vinno.vCloud.FIS.CrossPlatform.Common; using Vinno.vCloud.FIS.CrossPlatform.Common.Enum; using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo; using WingInterfaceLibrary.Enum; using WingInterfaceLibrary.Interface; using WingInterfaceLibrary.LiveConsultation; using WingInterfaceLibrary.Request.Device; namespace Vinno.vCloud.Common.FIS.LiveVideos { internal class LiveVideoPusherManagerV2 : ILiveVideoPusherManagerV2 { private readonly string _token; private readonly IDeviceService _deviceService; private readonly LiveVideoPusherV2 _liveVideoPusher; private readonly List _currentVideoDeviceInfoList; private readonly string _uniqueId; private bool _disposed; public bool IsPushing => _liveVideoPusher?.IsPushing ?? false; public event EventHandler PreviewImageReceived; public event EventHandler PusherStateChanged; /// /// The event to notificate the US to show or hide the live video out put window /// public event EventHandler LiveVideoNotification; public LiveVideoPusherManagerV2(string token, ILiveConsultationService liveConsultationService, IDeviceService deviceService, IEducationService educationService, string uniqueId, string deviceModel, string deviceType, string softwareVersion) { _uniqueId = uniqueId; _token = token; _deviceService = deviceService; _currentVideoDeviceInfoList = new List(); _liveVideoPusher = new LiveVideoPusherV2(token, liveConsultationService, deviceService, educationService, deviceModel, deviceType, softwareVersion); _liveVideoPusher.PusherStateChanged += OnPusherStateChanegd; _liveVideoPusher.LiveNotification += OnLiveNotification; RegisterPusherCreations(); } public List GetBrandList() { try { var getBrandRequest = new GetBrandsRequest { Token = _token, }; return JsonRpcHelper.GetBrands(_deviceService, getBrandRequest); } catch (Exception ex) { Logger.WriteLineError($"LiveVideoPusherManagerV2 GetBrandList Error:{ex}"); return new List(); } } public List GetModelList(string brand) { try { if (string.IsNullOrWhiteSpace(brand)) { Logger.WriteLineError($"LiveVideoPusherManagerV2 GetModelList Error:brand is null"); return new List(); } var getModelsRequest = new GetModelsRequest { Token = _token, Brand = brand, }; return JsonRpcHelper.GetModels(_deviceService, getModelsRequest); } catch (Exception ex) { Logger.WriteLineError($"LiveVideoPusherManagerV2 GetModelList Error:{ex}"); return new List(); } } public DeviceRecommandResolution GetRecommandResolution(string brand, string model) { try { if (string.IsNullOrWhiteSpace(brand)) { Logger.WriteLineError($"LiveVideoPusherManagerV2 GetRecommandResolution Error:brand is null"); return null; } if (string.IsNullOrWhiteSpace(model)) { Logger.WriteLineError($"LiveVideoPusherManagerV2 GetRecommandResolution Error:model is null"); return null; } var syncBrandModelOutputConfigRequest = new SyncBrandModelOutputConfigRequest { Token = _token, Brand = brand, Model = model, ShortCode = _uniqueId, }; var result = JsonRpcHelper.SyncBrandModelOutputConfig(_deviceService, syncBrandModelOutputConfigRequest); if (result == null || result.Count == 0) { throw new InvalidDataException($"JsonRPCHelper SyncBrandModelOutputConfig Result is null"); } else { var selected = result.FirstOrDefault(x => x.IsSelect); if (selected != null) { return new DeviceRecommandResolution(brand, null, model, selected.VideoWidth, selected.VideoHeight); } else { return new DeviceRecommandResolution(brand, null, model, result[0].VideoWidth, result[0].VideoHeight); } } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoPusherManagerV2 GetRecommandResolution Error:{ex}"); return null; } } private void OnLiveNotification(object sender, LiveNotificationArgs e) { LiveVideoNotification?.Invoke(this, e); } public void StartHeartRateKeeper(string heartRateCode, int interval, EnumHeartRateType heartRateType) { _liveVideoPusher?.StartHeartRateKeeper(heartRateCode, interval, heartRateType); } public void StopHeartRateKeeper() { _liveVideoPusher?.StopHeartRateKeeper(); } private void RegisterPusherCreations() { if (_liveVideoPusher != null) { _liveVideoPusher.RegisterPusher(EnumPusherType.RtcMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTCMergePusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.RtcMulti, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTCMultiPusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.RtcSingle, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTCSinglePusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.USRtcMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateUSRTCMergePusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.RtmpMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTMPMergePusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.RtmpMulti, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTMPMultiPusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.RtmpSingle, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTMPSinglePusherV2()); _liveVideoPusher.RegisterPusher(EnumPusherType.USRtmpMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateUSRTMPMergePusherV2()); } } public void LiveStateChanged(LiveEventArgs liveEventArgs) { _liveVideoPusher?.LiveStateChanged(liveEventArgs); } public void SetIsPaused(bool isPaused) { _liveVideoPusher?.SetIsPaused(isPaused); } public void RestartPusher() { _liveVideoPusher?.ReStartPusher(); } private void OnPusherStateChanegd(object sender, PusherState e) { PusherStateChanged?.Invoke(this, e); } public void SetMute(bool isMute) { _liveVideoPusher?.SetMute(isMute); } public void SwitchMic(string micId) { switch (vCloudServerConfig.Instance.LiveProtocolType) { case TransactionStatusEnum.TRTC: _liveVideoPusher?.SwitchMic(micId); break; default: if (_liveVideoPusher != null && _liveVideoPusher.IsPushing) { _liveVideoPusher.StopPusher(false, true); } break; } } private void UpdateDeviceResoution(List videoDeviceInfos) { try { Logger.WriteLineInfo("UpdateDeviceResoution"); var list = new List(); if (videoDeviceInfos != null) { foreach (var device in videoDeviceInfos) { var item = device.Clone() as CPVideoDeviceOutputInfo; list.Add(item); } } UpdateLiveChannelInfos(list); _liveVideoPusher?.StopPusher(false, true); } catch (Exception ex) { Logger.WriteLineError($"UpdateDeviceResoution Error:{ex}"); } } private void UpdateLiveChannelInfos(IEnumerable infos) { try { bool liveOpened = true; var videoDeviceInfoList = new List(); if (infos != null && infos.Count() > 0) { foreach (var info in infos) { videoDeviceInfoList.Add(new VideoDeviceInfo { VideoDeviceId = info.IdForServer, Height = info.OutputHeight, Width = info.OutputWidth, VideoDeviceSourceType = (VideoDeviceSourceTypeEnum)info.VideoDeviceSourceType, }); } } else { liveOpened = false; } var reportVideoDeviceInfoRequest = new ReportVideoDeviceInfoRequest { Token = _token, VideoDeviceInfos = videoDeviceInfoList, LiveOpened = liveOpened, }; ReportVideoDeviceInfoResult result = JsonRpcHelper.ReportVideoDeviceInfo(_deviceService, reportVideoDeviceInfoRequest); if (result == null) { string channelInfos = string.Empty; if (infos != null) { foreach (var info in infos) { channelInfos += info.ToString(); } } throw new InvalidDataException($"JsonRPCHelper ReportVideoDeviceInfoAsync Result is null: {channelInfos}"); } else { if (result.Success) { string channelInfos = string.Empty; if (result.VideoDeviceOutputInfos != null) { foreach (var info in result.VideoDeviceOutputInfos) { channelInfos += $"VideoDeviceId:{info.VideoDeviceId},SourceType:{info.VideoDeviceSourceType},Width:{info.Width},Height:{info.Height},OutputWidth:{info.OutputWidth},OutputHeight:{info.OutputHeight},VideoFps:{info.VideoFps},VideoBitrate:{info.VideoBitrate},MinVideoBitrate:{info.MinVideoBitrate}"; } } Logger.WriteLineInfo($"LiveVideoPusherManagerV2 UpdateLiveChannelInfos Sucess: {channelInfos}"); } else { string channelInfos = string.Empty; if (infos != null) { foreach (var info in infos) { channelInfos += info.ToString(); } } Logger.WriteLineError($"LiveVideoPusherManagerV2 UpdateLiveChannelInfos Fail: {channelInfos}"); } } } catch (Exception ex) { Logger.WriteLineError($"LiveVideoPusherManagerV2 ReportVideoDeviceInfoAsync Error:{ex} "); } } public void StartPreview(EnumLiveChannelCategory category) { if (_liveVideoPusher?.LiveVideoPusher is PusherBase pusher) { pusher.PreviewImageReceived += OnPreviewImageReceived; pusher.StartPreview(category); } } public void StartOnlyPreview(EnumLiveChannelCategory category) { if (_liveVideoPusher?.LiveVideoPusher is PusherBase pusher) { pusher.StartPreview(category); } } public void StopPreview() { if (_liveVideoPusher?.LiveVideoPusher is PusherBase pusher) { pusher.PreviewImageReceived -= OnPreviewImageReceived; pusher.StopPreview(); } } private void OnPreviewImageReceived(object sender, ImageFrameData e) { PreviewImageReceived?.Invoke(sender, e); } public void Dispose() { if (!_disposed) { DoDispose(); GC.SuppressFinalize(this); _disposed = true; } } public void DoDispose() { StopPreview(); _liveVideoPusher.Dispose(); _liveVideoPusher.LiveNotification -= OnLiveNotification;//若先注销事件,则Dispose收不到关闭的事件 _liveVideoPusher.PusherStateChanged -= OnPusherStateChanegd; } public void UpdateCurrentVideoDeviceInfoList(List infos) { _currentVideoDeviceInfoList.Clear(); if (infos != null) { foreach (var info in infos) { var item = info.Clone() as CPVideoDeviceOutputInfo; _currentVideoDeviceInfoList.Add(item); } } _liveVideoPusher.UpdateCurrentVideoDeviceInfoList(infos); UpdateDeviceResoution(_currentVideoDeviceInfoList); } public void ChangeHeartRateCode(string consultationCode) { _liveVideoPusher?.ChangeConsultationCode(consultationCode); } public bool StartSpeedTest() { if (_liveVideoPusher != null) { return _liveVideoPusher.StartSpeedTest(); } return false; } ~LiveVideoPusherManagerV2() { Dispose(); } } }