LiveVideoPusherManagerV2.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using Vinno.FIS.TRTCClient.Common.Enum;
  6. using Vinno.IUS.Common.Log;
  7. using Vinno.vCloud.Common.FIS.Helper;
  8. using Vinno.vCloud.FIS.CrossPlatform.Common;
  9. using Vinno.vCloud.FIS.CrossPlatform.Common.Enum;
  10. using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo;
  11. using WingInterfaceLibrary.Enum;
  12. using WingInterfaceLibrary.Interface;
  13. using WingInterfaceLibrary.LiveConsultation;
  14. using WingInterfaceLibrary.Request.Device;
  15. namespace Vinno.vCloud.Common.FIS.LiveVideos
  16. {
  17. internal class LiveVideoPusherManagerV2 : ILiveVideoPusherManagerV2
  18. {
  19. private readonly string _token;
  20. private readonly IDeviceService _deviceService;
  21. private readonly LiveVideoPusherV2 _liveVideoPusher;
  22. private readonly List<CPVideoDeviceOutputInfo> _currentVideoDeviceInfoList;
  23. private readonly string _uniqueId;
  24. private bool _disposed;
  25. public bool IsPushing => _liveVideoPusher?.IsPushing ?? false;
  26. public event EventHandler<ImageFrameData> PreviewImageReceived;
  27. public event EventHandler<PusherState> PusherStateChanged;
  28. /// <summary>
  29. /// The event to notificate the US to show or hide the live video out put window
  30. /// </summary>
  31. public event EventHandler<LiveNotificationArgs> LiveVideoNotification;
  32. public LiveVideoPusherManagerV2(string token, ILiveConsultationService liveConsultationService, IDeviceService deviceService, IEducationService educationService, string uniqueId, string deviceModel, string deviceType, string softwareVersion)
  33. {
  34. _uniqueId = uniqueId;
  35. _token = token;
  36. _deviceService = deviceService;
  37. _currentVideoDeviceInfoList = new List<CPVideoDeviceOutputInfo>();
  38. _liveVideoPusher = new LiveVideoPusherV2(token, liveConsultationService, deviceService, educationService, deviceModel, deviceType, softwareVersion);
  39. _liveVideoPusher.PusherStateChanged += OnPusherStateChanegd;
  40. _liveVideoPusher.LiveNotification += OnLiveNotification;
  41. RegisterPusherCreations();
  42. }
  43. public List<string> GetBrandList()
  44. {
  45. try
  46. {
  47. var getBrandRequest = new GetBrandsRequest
  48. {
  49. Token = _token,
  50. };
  51. return JsonRpcHelper.GetBrands(_deviceService, getBrandRequest);
  52. }
  53. catch (Exception ex)
  54. {
  55. Logger.WriteLineError($"LiveVideoPusherManagerV2 GetBrandList Error:{ex}");
  56. return new List<string>();
  57. }
  58. }
  59. public List<string> GetModelList(string brand)
  60. {
  61. try
  62. {
  63. if (string.IsNullOrWhiteSpace(brand))
  64. {
  65. Logger.WriteLineError($"LiveVideoPusherManagerV2 GetModelList Error:brand is null");
  66. return new List<string>();
  67. }
  68. var getModelsRequest = new GetModelsRequest
  69. {
  70. Token = _token,
  71. Brand = brand,
  72. };
  73. return JsonRpcHelper.GetModels(_deviceService, getModelsRequest);
  74. }
  75. catch (Exception ex)
  76. {
  77. Logger.WriteLineError($"LiveVideoPusherManagerV2 GetModelList Error:{ex}");
  78. return new List<string>();
  79. }
  80. }
  81. public DeviceRecommandResolution GetRecommandResolution(string brand, string model)
  82. {
  83. try
  84. {
  85. if (string.IsNullOrWhiteSpace(brand))
  86. {
  87. Logger.WriteLineError($"LiveVideoPusherManagerV2 GetRecommandResolution Error:brand is null");
  88. return null;
  89. }
  90. if (string.IsNullOrWhiteSpace(model))
  91. {
  92. Logger.WriteLineError($"LiveVideoPusherManagerV2 GetRecommandResolution Error:model is null");
  93. return null;
  94. }
  95. var syncBrandModelOutputConfigRequest = new SyncBrandModelOutputConfigRequest
  96. {
  97. Token = _token,
  98. Brand = brand,
  99. Model = model,
  100. ShortCode = _uniqueId,
  101. };
  102. var result = JsonRpcHelper.SyncBrandModelOutputConfig(_deviceService, syncBrandModelOutputConfigRequest);
  103. if (result == null || result.Count == 0)
  104. {
  105. throw new InvalidDataException($"JsonRPCHelper SyncBrandModelOutputConfig Result is null");
  106. }
  107. else
  108. {
  109. var selected = result.FirstOrDefault(x => x.IsSelect);
  110. if (selected != null)
  111. {
  112. return new DeviceRecommandResolution(brand, null, model, selected.VideoWidth, selected.VideoHeight);
  113. }
  114. else
  115. {
  116. return new DeviceRecommandResolution(brand, null, model, result[0].VideoWidth, result[0].VideoHeight);
  117. }
  118. }
  119. }
  120. catch (Exception ex)
  121. {
  122. Logger.WriteLineError($"LiveVideoPusherManagerV2 GetRecommandResolution Error:{ex}");
  123. return null;
  124. }
  125. }
  126. private void OnLiveNotification(object sender, LiveNotificationArgs e)
  127. {
  128. LiveVideoNotification?.Invoke(this, e);
  129. }
  130. public void StartHeartRateKeeper(string heartRateCode, int interval, EnumHeartRateType heartRateType)
  131. {
  132. _liveVideoPusher?.StartHeartRateKeeper(heartRateCode, interval, heartRateType);
  133. }
  134. public void StopHeartRateKeeper()
  135. {
  136. _liveVideoPusher?.StopHeartRateKeeper();
  137. }
  138. private void RegisterPusherCreations()
  139. {
  140. if (_liveVideoPusher != null)
  141. {
  142. _liveVideoPusher.RegisterPusher(EnumPusherType.RtcMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTCMergePusherV2());
  143. _liveVideoPusher.RegisterPusher(EnumPusherType.RtcMulti, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTCMultiPusherV2());
  144. _liveVideoPusher.RegisterPusher(EnumPusherType.RtcSingle, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTCSinglePusherV2());
  145. _liveVideoPusher.RegisterPusher(EnumPusherType.USRtcMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateUSRTCMergePusherV2());
  146. _liveVideoPusher.RegisterPusher(EnumPusherType.RtmpMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTMPMergePusherV2());
  147. _liveVideoPusher.RegisterPusher(EnumPusherType.RtmpMulti, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTMPMultiPusherV2());
  148. _liveVideoPusher.RegisterPusher(EnumPusherType.RtmpSingle, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateRTMPSinglePusherV2());
  149. _liveVideoPusher.RegisterPusher(EnumPusherType.USRtmpMerge, () => CrossPlatformHelper.Instance.LiveVideoPusherCreatorV2.CreateUSRTMPMergePusherV2());
  150. }
  151. }
  152. public void LiveStateChanged(LiveEventArgs liveEventArgs)
  153. {
  154. _liveVideoPusher?.LiveStateChanged(liveEventArgs);
  155. }
  156. public void SetIsPaused(bool isPaused)
  157. {
  158. _liveVideoPusher?.SetIsPaused(isPaused);
  159. }
  160. public void RestartPusher()
  161. {
  162. _liveVideoPusher?.ReStartPusher();
  163. }
  164. private void OnPusherStateChanegd(object sender, PusherState e)
  165. {
  166. PusherStateChanged?.Invoke(this, e);
  167. }
  168. public void SetMute(bool isMute)
  169. {
  170. _liveVideoPusher?.SetMute(isMute);
  171. }
  172. public void SwitchMic(string micId)
  173. {
  174. switch (vCloudServerConfig.Instance.LiveProtocolType)
  175. {
  176. case TransactionStatusEnum.TRTC:
  177. _liveVideoPusher?.SwitchMic(micId);
  178. break;
  179. default:
  180. if (_liveVideoPusher != null && _liveVideoPusher.IsPushing)
  181. {
  182. _liveVideoPusher.StopPusher(false, true);
  183. }
  184. break;
  185. }
  186. }
  187. private void UpdateDeviceResoution(List<CPVideoDeviceOutputInfo> videoDeviceInfos)
  188. {
  189. try
  190. {
  191. Logger.WriteLineInfo("UpdateDeviceResoution");
  192. var list = new List<CPVideoDeviceOutputInfo>();
  193. if (videoDeviceInfos != null)
  194. {
  195. foreach (var device in videoDeviceInfos)
  196. {
  197. var item = device.Clone() as CPVideoDeviceOutputInfo;
  198. list.Add(item);
  199. }
  200. }
  201. UpdateLiveChannelInfos(list);
  202. _liveVideoPusher?.StopPusher(false, true);
  203. }
  204. catch (Exception ex)
  205. {
  206. Logger.WriteLineError($"UpdateDeviceResoution Error:{ex}");
  207. }
  208. }
  209. private void UpdateLiveChannelInfos(IEnumerable<CPVideoDeviceOutputInfo> infos)
  210. {
  211. try
  212. {
  213. bool liveOpened = true;
  214. var videoDeviceInfoList = new List<VideoDeviceInfo>();
  215. if (infos != null && infos.Count() > 0)
  216. {
  217. foreach (var info in infos)
  218. {
  219. videoDeviceInfoList.Add(new VideoDeviceInfo
  220. {
  221. VideoDeviceId = info.IdForServer,
  222. Height = info.OutputHeight,
  223. Width = info.OutputWidth,
  224. VideoDeviceSourceType = (VideoDeviceSourceTypeEnum)info.VideoDeviceSourceType,
  225. });
  226. }
  227. }
  228. else
  229. {
  230. liveOpened = false;
  231. }
  232. var reportVideoDeviceInfoRequest = new ReportVideoDeviceInfoRequest
  233. {
  234. Token = _token,
  235. VideoDeviceInfos = videoDeviceInfoList,
  236. LiveOpened = liveOpened,
  237. };
  238. ReportVideoDeviceInfoResult result = JsonRpcHelper.ReportVideoDeviceInfo(_deviceService, reportVideoDeviceInfoRequest);
  239. if (result == null)
  240. {
  241. string channelInfos = string.Empty;
  242. if (infos != null)
  243. {
  244. foreach (var info in infos)
  245. {
  246. channelInfos += info.ToString();
  247. }
  248. }
  249. throw new InvalidDataException($"JsonRPCHelper ReportVideoDeviceInfoAsync Result is null: {channelInfos}");
  250. }
  251. else
  252. {
  253. if (result.Success)
  254. {
  255. string channelInfos = string.Empty;
  256. if (result.VideoDeviceOutputInfos != null)
  257. {
  258. foreach (var info in result.VideoDeviceOutputInfos)
  259. {
  260. 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}";
  261. }
  262. }
  263. Logger.WriteLineInfo($"LiveVideoPusherManagerV2 UpdateLiveChannelInfos Sucess: {channelInfos}");
  264. }
  265. else
  266. {
  267. string channelInfos = string.Empty;
  268. if (infos != null)
  269. {
  270. foreach (var info in infos)
  271. {
  272. channelInfos += info.ToString();
  273. }
  274. }
  275. Logger.WriteLineError($"LiveVideoPusherManagerV2 UpdateLiveChannelInfos Fail: {channelInfos}");
  276. }
  277. }
  278. }
  279. catch (Exception ex)
  280. {
  281. Logger.WriteLineError($"LiveVideoPusherManagerV2 ReportVideoDeviceInfoAsync Error:{ex} ");
  282. }
  283. }
  284. public void StartPreview(EnumLiveChannelCategory category)
  285. {
  286. if (_liveVideoPusher?.LiveVideoPusher is PusherBase pusher)
  287. {
  288. pusher.PreviewImageReceived += OnPreviewImageReceived;
  289. pusher.StartPreview(category);
  290. }
  291. }
  292. public void StartOnlyPreview(EnumLiveChannelCategory category)
  293. {
  294. if (_liveVideoPusher?.LiveVideoPusher is PusherBase pusher)
  295. {
  296. pusher.StartPreview(category);
  297. }
  298. }
  299. public void StopPreview()
  300. {
  301. if (_liveVideoPusher?.LiveVideoPusher is PusherBase pusher)
  302. {
  303. pusher.PreviewImageReceived -= OnPreviewImageReceived;
  304. pusher.StopPreview();
  305. }
  306. }
  307. private void OnPreviewImageReceived(object sender, ImageFrameData e)
  308. {
  309. PreviewImageReceived?.Invoke(sender, e);
  310. }
  311. public void Dispose()
  312. {
  313. if (!_disposed)
  314. {
  315. DoDispose();
  316. GC.SuppressFinalize(this);
  317. _disposed = true;
  318. }
  319. }
  320. public void DoDispose()
  321. {
  322. StopPreview();
  323. _liveVideoPusher.Dispose();
  324. _liveVideoPusher.LiveNotification -= OnLiveNotification;//若先注销事件,则Dispose收不到关闭的事件
  325. _liveVideoPusher.PusherStateChanged -= OnPusherStateChanegd;
  326. }
  327. public void UpdateCurrentVideoDeviceInfoList(List<CPVideoDeviceOutputInfo> infos)
  328. {
  329. _currentVideoDeviceInfoList.Clear();
  330. if (infos != null)
  331. {
  332. foreach (var info in infos)
  333. {
  334. var item = info.Clone() as CPVideoDeviceOutputInfo;
  335. _currentVideoDeviceInfoList.Add(item);
  336. }
  337. }
  338. _liveVideoPusher.UpdateCurrentVideoDeviceInfoList(infos);
  339. UpdateDeviceResoution(_currentVideoDeviceInfoList);
  340. }
  341. public void ChangeHeartRateCode(string consultationCode)
  342. {
  343. _liveVideoPusher?.ChangeConsultationCode(consultationCode);
  344. }
  345. public bool StartSpeedTest()
  346. {
  347. if (_liveVideoPusher != null)
  348. {
  349. return _liveVideoPusher.StartSpeedTest();
  350. }
  351. return false;
  352. }
  353. ~LiveVideoPusherManagerV2()
  354. {
  355. Dispose();
  356. }
  357. }
  358. }