123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- using System;
- using System.Runtime.InteropServices;
- using System.Threading.Tasks;
- using Vinno.FIS.TRTCClient.Common.Enum;
- using Vinno.IUS.Common.Log;
- using Vinno.vCloud.Common.FIS.LiveVideos;
- using Vinno.vCloud.FIS.CrossPlatform.Common;
- using Vinno.vCloud.FIS.CrossPlatform.Common.Consultation.Interface;
- using Vinno.vCloud.FIS.CrossPlatform.Common.Enum;
- using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo;
- using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo.Interface;
- using WingInterfaceLibrary.LiveConsultation;
- namespace Vinno.vCloud.Common.FIS.Consultation
- {
- public abstract class VideoProviderV2 : IDisposable
- {
- private readonly ConsultationVideoFrameData _consultationVideoFrameData;
- private readonly object _connectionKeeperLock = new object();
- private PushHeartRateKeeperV2 _connectionKeeper;
- protected ConsultationMemberInfo _consultationMemberInfo;
- protected bool _disposed;
- public event EventHandler Offlined;
- public ConsultationMemberInfo ConsultationMemberInfo
- {
- get => _consultationMemberInfo;
- set
- {
- _consultationMemberInfo = value;
- }
- }
- /// <summary>
- /// Video frame arrived
- /// </summary>
- public event EventHandler<ConsultationVideoFrameData> VideoFrameArrived;
- public VideoProviderV2(ConsultationMemberInfo consultationMemberInfo)
- {
- _consultationMemberInfo = consultationMemberInfo;
- _consultationVideoFrameData = new ConsultationVideoFrameData(null, _consultationMemberInfo);
- }
- public abstract void Dispose();
- protected void UpdateFrame(CPVideoFrameData data)
- {
- _consultationVideoFrameData.VideoFrameData = data;
- VideoFrameArrived?.Invoke(this, _consultationVideoFrameData);
- }
- public void StartConsultationConnectionKeeper(string token, string consultationCode, int heartRateInterval, ILiveConsultationService liveConsultationService)
- {
- lock (_connectionKeeperLock)
- {
- _connectionKeeper = new PushHeartRateKeeperV2(token, consultationCode, heartRateInterval, liveConsultationService);
- _connectionKeeper.Offlined += OnOfflined;
- _connectionKeeper.Start();
- }
- }
- public void ChangeConsultationCode(string consultationCode)
- {
- lock (_connectionKeeperLock)
- {
- if (_connectionKeeper != null)
- {
- _connectionKeeper.SetHeartRateCode(consultationCode);
- Logger.WriteLineInfo($"Consultation Connection Keeper Change Consultation Code {consultationCode}");
- }
- }
- }
- private void OnOfflined(object sender, EventArgs e)
- {
- Offlined?.Invoke(this, e);
- Logger.WriteLineInfo($"Connection keeper offline ");
- }
- internal void DisposeConnectionKeeper()
- {
- if (_connectionKeeper != null)
- {
- _connectionKeeper.Offlined -= OnOfflined;
- _connectionKeeper.Stop();
- _connectionKeeper = null;
- }
- }
- }
- public class RtcVideoProviderV2 : VideoProviderV2
- {
- public RtcVideoProviderV2(ConsultationMemberInfo consultationMemberInfo) : base(consultationMemberInfo)
- {
- }
- public override void Dispose()
- {
- if (_disposed)
- return;
- DisposeConnectionKeeper();
- _disposed = true;
- }
- }
- public class RtmpVideoProviderV2 : VideoProviderV2
- {
- public RtmpVideoProviderV2(ConsultationMemberInfo consultationMemberInfo) : base(consultationMemberInfo)
- {
- }
- public override void Dispose()
- {
- if (_disposed)
- return;
- DisposeConnectionKeeper();
- _disposed = true;
- }
- }
- public class RtmpVideoPlayerV2 : VideoProviderV2
- {
- private IRtmpPlayer _smartPlayer;
- private int _videoBufferSize = 300;
- private bool _isClosed;
- private readonly object _locker = new object();
- public RtmpVideoPlayerV2(ConsultationMemberInfo consultationMemberInfo) : base(consultationMemberInfo)
- {
- CreateSmartPlayer(consultationMemberInfo.PullRtmpUrl);
- }
- private void CreateSmartPlayer(string url)
- {
- if (!string.IsNullOrEmpty(url))
- {
- _smartPlayer = CrossPlatformHelper.Instance.RtmpPlayerCreator.CreateLivePlayer(url);
- _smartPlayer.Buffer = _videoBufferSize;
- _smartPlayer.VideoFrameReceived += OnVideoFrameReceived;
- Task.Run(async () =>
- {
- await Task.Delay(3000);
- lock (_locker)
- {
- if (!_isClosed)
- {
- _smartPlayer.Play();
- }
- }
- });
- }
- }
- private void CloseSmartPlayer()
- {
- if (_smartPlayer != null)
- {
- lock (_locker)
- {
- _isClosed = true;
- }
- _smartPlayer.VideoFrameReceived -= OnVideoFrameReceived;
- _smartPlayer.Stop();
- _smartPlayer = null;
- }
- }
- private void OnVideoFrameReceived(object sender, CPVideoFrameData e)
- {
- UpdateFrame(e);
- }
- public override void Dispose()
- {
- if (_disposed)
- return;
- DisposeConnectionKeeper();
- CloseSmartPlayer();
- _disposed = true;
- }
- ~RtmpVideoPlayerV2()
- {
- }
- }
- public class RtmpVideoPusherV2 : VideoProviderV2
- {
- private IRtmpPusherV2 _smartPublisher;
- private CPVideoFrameData _videoFrameData;
- public RtmpVideoPusherV2(ConsultationMemberInfo consultationMemberInfo, string videoDeviceId, string micDeviceId, bool onlyForRtmpPushing) : base(consultationMemberInfo)
- {
- var deviceInfo = new CPVideoDeviceOutputInfo
- {
- VideoDeviceId = videoDeviceId,
- IdForServer = "",
- VideoDeviceSourceType = EnumVideoDeviceSourceType.Camera,
- OutputWidth = 640,
- OutputHeight = 480,
- Category = EnumLiveChannelCategory.Main,
- };
- _smartPublisher = CrossPlatformHelper.Instance.RtmpPusherCreator.CreateLivePusherV2(deviceInfo, consultationMemberInfo.PushUrl, micDeviceId, 640, 480);
- if (!onlyForRtmpPushing)
- {
- _smartPublisher.ImageFrameReceived += OnImageFrameReceived;
- }
- _smartPublisher.Start();
- }
- ~RtmpVideoPusherV2()
- {
- }
- private void OnImageFrameReceived(object sender, ImageFrameData e)
- {
- if (_videoFrameData == null)
- {
- _videoFrameData = new CPVideoFrameData(e.Width, e.Height, new byte[e.Size]);
- }
- else if (_videoFrameData.Height != e.Height || _videoFrameData.Width != e.Width)
- {
- _videoFrameData.Height = e.Height;
- _videoFrameData.Width = e.Width;
- _videoFrameData.Data = new byte[e.Size];
- }
- Marshal.Copy(e.Data, _videoFrameData.Data, 0, e.Size);
- UpdateFrame(_videoFrameData);
- }
- public override void Dispose()
- {
- if (_disposed)
- return;
- LiveVideoStatusChecker.Instance.IsConsultationLivingInCurrentMachine = false;
- if (_smartPublisher != null)
- {
- _smartPublisher.ImageFrameReceived -= OnImageFrameReceived;
- _smartPublisher.Stop();
- _smartPublisher.Dispose();
- _smartPublisher = null;
- }
- DisposeConnectionKeeper();
- _disposed = true;
- }
- public void SetMute(bool isMute)
- {
- if (_smartPublisher != null)
- {
- _smartPublisher.SetMute(isMute);
- }
- }
- public void SwitchCamera()
- {
- if (_smartPublisher != null)
- {
- //TODOFelix
- }
- }
- }
- }
|