123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Vinno.FIS.TRTCClient.Common.Enum;
- using Vinno.FIS.TRTCClient.Common.Models;
- using Vinno.IUS.Common.Log;
- using Vinno.IUS.Common.Network.Leaf;
- using Vinno.vCloud.Common.FIS.Helper;
- using Vinno.vCloud.FIS.CrossPlatform.Common;
- using Vinno.vCloud.FIS.CrossPlatform.Common.Consultation;
- 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.Protocol.Infrastructures;
- using Vinno.vCloud.Protocol.Messages.Live;
- namespace Vinno.vCloud.Common.FIS.Consultation
- {
- internal class ConsultationLiveVideoProvider : IDisposable
- {
- private readonly object _lock = new object();
- private readonly object _startConsultationLocker = new object();//Felix之所以加这个lock,会有Start没跑完就Stop的情况。
- private readonly IImageHelper _imageHelper;
- private readonly List<VideoProvider> _videoProviders;
- private IRtcRoom _rtcRoom;
- private IRtmpPlayer _terminalMergePlayer; //拉超声机图像与摄像机流
- private IRtmpPlayer _terminalVideoPlayer; //拉超声机图像流
- private IRtmpPlayer _terminalCameraPlayer; //拉超声机摄像机流
- private bool _isConsulting;
- private LiveProtocol _liveProtocol;
- private string _accountId;
- private ConsultationInfo _consultationInfo;
- private CPVideoFrameData _terminalVideoFrameData;
- private CPVideoFrameData _cameraVideoFrameData;
- private CPVideoFrameData _rtcTerminaVideoFrameData;
- private CPVideoFrameData _completeVideoFrameData;
- private int _videoBufferSize = 300;
- private int _imagePreviewErrorLogCount;
- //单路超声机数据缓存区
- private byte[] _rtcTerminalLiveDataBuffer;
- private LiveDataBytes _liveDataBytes = new LiveDataBytes();
- private TerminalLiveDataBytes _termialLiveDataBytes = new TerminalLiveDataBytes();
- public event EventHandler<EnumTRTCRoomError> OnTRTCRoomEnterError;
- /// <summary>
- /// 本地的摄像头数据
- /// </summary>
- public event EventHandler<ConsultationVideoFrameData> ConsultationLocalVideoFrameArrived;
- /// <summary>
- /// 其余所有用户的摄像头数据
- /// </summary>
- public event EventHandler<ConsultationVideoFrameData> ConsultationRemoteVideoFrameArrived;
- /// <summary>
- /// 超声机画面
- /// </summary>
- public event EventHandler<CPVideoFrameData> TerminalImageFrameArrived;
- /// <summary>
- /// 超声机摄像头画面
- /// </summary>
- public event EventHandler<CPVideoFrameData> TerminalCameraFrameArrived;
- public event EventHandler<RefreshStatus> TerminalRefreshCaseHappened;
- public event EventHandler<CPLiveStatusData> CameraLiveStatusChanged;
- public event EventHandler<CPLiveStatusData> TerminalLiveStatusChanged;
- public event EventHandler<RemoteUserLeaveRoomArgs> RemoteUserLeaveRoomArrived;
- public event EventHandler CloseConsultation;
- public event EventHandler TryToReconnect;
- public ConsultationLiveVideoProvider()
- {
- _videoProviders = new List<VideoProvider>();
- _imageHelper = CrossPlatformHelper.Instance.ImageHelperCreator.CreateImageHelper();
- }
- /// <summary>
- /// 开始会诊
- /// </summary>
- /// <param name="consultationInfo"></param>
- public void StartConsultationVideo(ConsultationInfo consultationInfo, string accountId, string accountName, string videoDeviceId, string micDeviceId, string speakerDeviceId, ClientLeaf leaf)
- {
- if (_isConsulting)
- {
- return;
- }
- lock (_startConsultationLocker)
- {
- _isConsulting = true;
- _liveProtocol = consultationInfo.LiveProtocol;
- _accountId = accountId;
- _consultationInfo = consultationInfo;
- var terminalInfo = consultationInfo.TerminalInfo;
- var consultationMembers = consultationInfo.ConsultationMemberInfos;
- if (consultationInfo.LiveTalkingMode == Protocol.Messages.Client.LiveTalking.LiveTalkingMode.Speech)
- {
- videoDeviceId = string.Empty;
- }
- if (_liveProtocol == LiveProtocol.RTC)
- {
- if (consultationInfo.State == LiveStates.OK)
- {
- foreach (var member in consultationMembers)
- {
- if (member.Id == _accountId)
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider == null)
- {
- Logger.WriteLineInfo($"Start To Create RTC Video Provider, Name:{member.Name},Id:{member.Id}");
- _videoProviders.Add(new RtcVideoProvider(member));
- }
- else
- {
- Logger.WriteLineInfo($"RTC Video Provider Already exist, Name:{member.Name},Id:{member.Id}");
- videoProvider.ConsultationMemberInfo = member;
- }
- var userSign = member.UserSign;
- var integerRoomId = consultationInfo.IntegerRoomId;
- var appId = consultationInfo.AppId;
- var mode = consultationInfo.LiveTalkingMode;
- _rtcRoom = CrossPlatformHelper.Instance.RtcRoomCreator.CreateRtcRoom();
- _rtcRoom.LocalVideoFrameArrived += OnRtcLocalVideoFrameArrived;
- _rtcRoom.RemoteVideoFrameArrived += OnRtcRemoteVideoFrameArrived;
- _rtcRoom.OnTRTCRoomEnterError += OnTRTCRoomEnterErrorHappened;
- _rtcRoom.RemoteUserLeaveRoomArrived += OnRemoteUserLeaveRoomArrived;
- _rtcRoom.TryToReconnect += OnTryToReconnect;
- var roomInfo = new TRTCRoomInfo
- {
- AppId = (uint)appId,
- UserSig = userSign,
- UserId = accountId,
- RoomId = (uint)integerRoomId,
- VideoDeviceId = videoDeviceId,
- MicDeviceId = micDeviceId,
- SpeakerDeviceId = speakerDeviceId,
- TerminalIsPushing = _consultationInfo.TerminalInfo?.State == LiveStates.OK,
- TerminalId = _consultationInfo.TerminalInfo?.Id,
- CameraId = _consultationInfo.TerminalInfo?.CameraId,
- IsMultiChannel = _consultationInfo.TerminalInfo == null ? false : _consultationInfo.TerminalInfo.IsMultiChannels,
- TerminalRoomId = (uint)_consultationInfo.TerminalInfo?.TerminalIntegerRoomId,
- IsLiveMode = false,
- IsOldServerMode = true,
- Category = EnumLiveChannelCategory.Main,
- };
- _rtcRoom.Enter(roomInfo);
- Logger.WriteLineInfo($"{accountName} enterred room {integerRoomId}");
- }
- else
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider == null)
- {
- Logger.WriteLineInfo($"Start To Create RTC Video Provider, Name:{member.Name},Id:{member.Id}");
- _videoProviders.Add(new RtcVideoProvider(member));
- }
- else
- {
- Logger.WriteLineInfo($"RTC Video Provider Already exist, Name:{member.Name},Id:{member.Id}");
- videoProvider.ConsultationMemberInfo = member;
- }
- }
- }
- }
- }
- else if (_liveProtocol == LiveProtocol.Rtmp)
- {
- foreach (var member in consultationMembers)
- {
- if (member.Id == _accountId)
- {
- RtmpVideoPusher rtmpVideoPusher = null;
- try
- {
- var pusherUrl = member.PushUrl;
- if (!string.IsNullOrEmpty(pusherUrl))
- {
- Logger.WriteLineInfo($"Start push with rtmp address {pusherUrl}");
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider == null)
- {
- Logger.WriteLineInfo($"Start To Create Rtmp Video Pusher, Name:{member.Name},Id:{member.Id}");
- rtmpVideoPusher = new RtmpVideoPusher(member, videoDeviceId, micDeviceId);
- rtmpVideoPusher.VideoFrameArrived += OnLocalVideoFrameArrived;
- _videoProviders.Add(rtmpVideoPusher);
- if (member.State == LiveStates.OK)
- {
- rtmpVideoPusher.StartConnectionKeeper(consultationInfo.RoomId, accountId, leaf);
- rtmpVideoPusher.Offlined += OnOfflined;
- }
- }
- else
- {
- Logger.WriteLineInfo($"Rtmp video Pusher already exists,Name:{member.Name},Id:{member.Id}");
- videoProvider.ConsultationMemberInfo = member;
- }
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineError($"Exception happened while play rtmp{ex}");
- }
- }
- else
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider == null)
- {
- Logger.WriteLineInfo($"Start To Create Rtmp Player,Name:{member.Name},Id:{member.Id}");
- CreateRtmpPlayer(member);
- }
- else
- {
- Logger.WriteLineInfo($"Rtmp Player already exists,Name:{member.Name},Id:{member.Id}");
- videoProvider.ConsultationMemberInfo = member;
- }
- }
- }
- }
- if (terminalInfo.TerminalLiveProtocol == LiveProtocol.RTC)
- {
- Logger.WriteLineInfo($"Wait for terminal state arriving, then start cross-room communication");
- terminalInfo.IsSupportRtc = true;
- //if (terminalInfo.State == LiveStates.OK)
- //{
- // Logger.WriteLineInfo($"Connect terminal room when already pushing- {terminalInfo.IntegerRoomId}-{terminalInfo.Id}");
- // _rtcRoom.ConnectRoom((uint)terminalInfo.IntegerRoomId, terminalInfo.Id);
- //}
- //var isAvailableTerminal = terminalInfo?.State != LiveStates.TerminalOffLine;
- //if (isAvailableTerminal)
- //{
- // var isRecipient = consultationInfo?.ChatRole == ChatRole.Recipient;
- // //ResetTheTerminalLiveStatusWatcher(isRecipient, true);
- //}
- }
- else if (terminalInfo.TerminalLiveProtocol == LiveProtocol.Rtmp && terminalInfo.State == LiveStates.OK)
- {
- var terminalUrl = terminalInfo.TerminalUrl;
- Logger.WriteLineInfo($"Start to create ultrasouind player,Name{terminalInfo?.Name},TerminalUrl:{terminalUrl}");
- if (terminalInfo.IsMergeChannel)
- {
- if (!string.IsNullOrEmpty(terminalUrl))
- {
- _terminalMergePlayer = CrossPlatformHelper.Instance.RtmpPlayerCreator.CreateLivePlayer(terminalUrl);
- _terminalMergePlayer.Buffer = _videoBufferSize;
- _terminalMergePlayer.VideoFrameReceived += OnRtmpUltrasoundMergeImageFrameReceived;
- _terminalMergePlayer.StatusChanged += OnRtmpUltrasoundMergeVideoStatusChanged;
- _terminalMergePlayer.Play();
- Logger.WriteLineInfo($"{terminalInfo?.Name}: play single merge channel success,terminalUrl:{terminalUrl}");
- }
- }
- else
- {
- var cameraUrl = terminalInfo.CameraUrl;
- if (!string.IsNullOrEmpty(terminalUrl))
- {
- _terminalVideoPlayer = CrossPlatformHelper.Instance.RtmpPlayerCreator.CreateLivePlayer(terminalUrl);
- _terminalVideoPlayer.Buffer = _videoBufferSize;
- _terminalVideoPlayer.VideoFrameReceived += OnTerminalVideoFrameArrived;
- _terminalVideoPlayer.StatusChanged += OnTerminalVideoStatusChanged;
- _terminalVideoPlayer.Play();
- }
- if (!string.IsNullOrEmpty(cameraUrl))
- {
- _terminalCameraPlayer = CrossPlatformHelper.Instance.RtmpPlayerCreator.CreateLivePlayer(cameraUrl);
- _terminalCameraPlayer.Buffer = _videoBufferSize;
- _terminalCameraPlayer.VideoFrameReceived += OnTerminalCameraFrameArrived;
- _terminalCameraPlayer.StatusChanged += OnTerminalCameraVideoStatusChanged;
- _terminalCameraPlayer.Play();
- }
- Logger.WriteLineInfo($"{terminalInfo?.Name}: play dual channel success,terminal url {terminalUrl}" +
- $",camara url {cameraUrl}");
- }
- }
- }
- }
- private void OnTerminalVideoFrameArrived(object sender, CPVideoFrameData e)
- {
- TerminalImageFrameArrived?.Invoke(this, e);
- }
- private void OnTerminalCameraFrameArrived(object sender, CPVideoFrameData e)
- {
- TerminalCameraFrameArrived?.Invoke(this, e);
- }
- private void OnRtcLocalVideoFrameArrived(object sender, CPVideoFrameData e)
- {
- var consultationMembers = _consultationInfo.ConsultationMemberInfos;
- var consultationMember = consultationMembers.FirstOrDefault(x => x.Id == _accountId);
- if (consultationMember != null)
- {
- OnLocalVideoFrameArrived(this, new ConsultationVideoFrameData(e, consultationMember));
- }
- }
- private void OnLocalVideoFrameArrived(object sender, ConsultationVideoFrameData e)
- {
- ConsultationLocalVideoFrameArrived?.Invoke(this, e);
- }
- private void OnRtcRemoteVideoFrameArrived(object sender, CPRemoteVideoFrameData e)
- {
- try
- {
- if (_consultationInfo != null)
- {
- var terminalInfo = _consultationInfo.TerminalInfo;
- if (terminalInfo == null)
- {
- return;
- }
- var terminaId = terminalInfo.Id;
- var cameraId = terminalInfo.CameraId;
- if (terminalInfo.IsMultiChannels && terminalInfo.PullDataMode == LiveDataMode.OnlyLive)
- {
- if (e.UserId == terminaId)
- {
- OnTerminalVideoFrameArrived(sender, e.Data);
- }
- else if (!string.IsNullOrEmpty(cameraId) && e.UserId == cameraId)
- {
- OnTerminalCameraFrameArrived(sender, e.Data);
- }
- else
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == e.UserId);
- if (videoProvider != null)
- {
- OnVideoFrameArrived(videoProvider, e.Data);
- }
- }
- }
- else
- {
- if (terminaId == e.UserId)
- {
- var remoteTerminalRawData = e.Data;
- int terminalCompleteWidth = terminalInfo.TerminalWidth;
- int terminalCompleteHeight = terminalInfo.TerminalHeight;
- int cameraCompleteWidth = terminalInfo.CameraWidth;
- int cameraCompleteHeight = terminalInfo.CameraHeight;
- byte[] terminalData;
- byte[] cameraData;
- var terminalBytes = terminalCompleteWidth * terminalCompleteHeight * 4;
- var cameraBytes = cameraCompleteWidth * cameraCompleteHeight * 4;
- var isMergeImage = terminalInfo.CameraLiveEnabled && terminalInfo.TerminalLiveEnabled;
- if (isMergeImage)
- {
- _termialLiveDataBytes.Update(remoteTerminalRawData.Data, terminalBytes, cameraBytes,
- terminalCompleteWidth, terminalCompleteHeight, remoteTerminalRawData.Width, _imageHelper.OSType);
- }
- else
- {
- if (terminalInfo.CameraLiveEnabled)
- {
- OnTerminalCameraFrameArrived(sender, e.Data);
- return;
- }
- if (terminalInfo.TerminalLiveEnabled)
- {
- var usWidth = terminalInfo.TerminalWidth;
- var usHeight = terminalInfo.TerminalHeight;
- var terminallength = usWidth * usHeight * 4;
- if (_rtcTerminalLiveDataBuffer == null)
- {
- _rtcTerminalLiveDataBuffer = new byte[terminallength];
- }
- else if (terminallength != _rtcTerminalLiveDataBuffer.Length)
- {
- Array.Resize(ref _rtcTerminalLiveDataBuffer, terminallength);
- }
- if (_rtcTerminalLiveDataBuffer.Length <= e.Data.Data.Length)
- {
- switch (_imageHelper?.OSType)
- {
- case EnumClientOSType.PC:
- ParallelOptions parallelOptions = new ParallelOptions
- {
- MaxDegreeOfParallelism = 10
- };
- Parallel.For(0, usHeight, parallelOptions, row =>
- {
- Array.Copy(e.Data.Data, row * e.Data.Width * 4, _rtcTerminalLiveDataBuffer, row * usWidth * 4, usWidth * 4);
- });
- break;
- case EnumClientOSType.Android:
- for (int row = 0; row < usHeight; row++)
- {
- Array.Copy(e.Data.Data, row * e.Data.Width * 4, _rtcTerminalLiveDataBuffer, row * usWidth * 4, usWidth * 4);
- }
- break;
- }
- }
- else
- {
- if (_imagePreviewErrorLogCount++ < 1)
- {
- Logger.WriteLineError($"rtcTerminalLiveDataBuffer is small than terminal data size, " +
- $"terminal width:{terminalInfo.TerminalWidth}, terminal height:{terminalInfo.TerminalHeight}" +
- $",terminal array length:{terminallength} " +
- $"destination array length: {_rtcTerminalLiveDataBuffer.Length}, data size: {e.Data.Width}*{e.Data.Height}");
- }
- }
- ResizeVideoFrameData(ref _terminalVideoFrameData, usWidth, usHeight, _rtcTerminalLiveDataBuffer);
- OnTerminalVideoFrameArrived(sender, _terminalVideoFrameData);
- return;
- }
- }
- terminalData = _termialLiveDataBytes.TerminalData;
- cameraData = _termialLiveDataBytes.CameraData;
- var needCameraData = terminalInfo.CameraLiveEnabled;
- if (terminalData != null)
- {
- ResizeVideoFrameData(ref _terminalVideoFrameData, terminalCompleteWidth, terminalCompleteHeight, terminalData, remoteTerminalRawData.ImageData);
- OnTerminalVideoFrameArrived(sender, _terminalVideoFrameData);
- }
- if (needCameraData)
- {
- OnTerminalCameraFrameArrived(sender, new CPVideoFrameData(cameraCompleteWidth, cameraCompleteHeight, cameraData));
- }
- }
- else
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == e.UserId);
- if (videoProvider != null)
- {
- OnVideoFrameArrived(videoProvider, e.Data);
- }
- }
- }
- }
- _imagePreviewErrorLogCount = 0;
- }
- catch (Exception ex)
- {
- if (_imagePreviewErrorLogCount++ < 1)
- {
- Logger.WriteLineError($"destination array length: {_rtcTerminalLiveDataBuffer?.Length}, data size: {e?.Data?.Width}*{e?.Data?.Height}");
- Logger.WriteLineError($"OnRtcRemoteVideoFrameArrived ex:{ex}");
- }
- }
- }
- private void OnVideoFrameArrived(VideoProvider videoProvider, CPVideoFrameData e)
- {
- OnRemoteVideoFrameArrived(this, new ConsultationVideoFrameData(e, videoProvider.ConsultationMemberInfo));
- }
- private void OnTRTCRoomEnterErrorHappened(object sender, EnumTRTCRoomError e)
- {
- OnTRTCRoomEnterError?.Invoke(sender, e);
- }
- private void ResizeVideoFrameData(ref CPVideoFrameData videoFrameData, int width, int height, byte[] data, object imageData = null)
- {
- if (videoFrameData == null)
- {
- videoFrameData = new CPVideoFrameData(width, height, data) { ImageData = imageData };
- }
- else
- {
- videoFrameData.Width = width;
- videoFrameData.Height = height;
- videoFrameData.Data = data;
- videoFrameData.ImageData = imageData;
- }
- }
- private void OnTryToReconnect(object sender, EventArgs e)
- {
- TryToReconnect?.Invoke(this, EventArgs.Empty);
- }
- private void OnOfflined(object sender, EventArgs e)
- {
- CloseConsultation?.Invoke(sender, e);
- }
- private void CreateRtmpPlayer(ConsultationMemberInfo consultationMember)
- {
- var rtmpVideoProvider = new RtmpVideoProvider(consultationMember);
- rtmpVideoProvider.VideoFrameArrived += OnRemoteVideoFrameArrived;
- _videoProviders.Add(rtmpVideoProvider);
- }
- private void OnRemoteVideoFrameArrived(object sender, ConsultationVideoFrameData e)
- {
- ConsultationRemoteVideoFrameArrived?.Invoke(this, e);
- }
- private void OnRemoteUserLeaveRoomArrived(object sender, RemoteUserLeaveRoomArgs e)
- {
- RemoteUserLeaveRoomArrived?.Invoke(this, e);
- }
- private void OnRtmpUltrasoundMergeImageFrameReceived(object sender, CPVideoFrameData e)
- {
- try
- {
- var terminal = _consultationInfo.TerminalInfo;
- var needCameraData = terminal.CameraLiveEnabled;
- var liveProtocol = terminal.TerminalLiveProtocol;
- if (terminal != null)
- {
- if (terminal.TerminalLiveEnabled && terminal.CameraLiveEnabled)
- {
- int terminalCompleteWidth = terminal.TerminalWidth;
- int terminalCompleteHeight = terminal.TerminalHeight;
- int cameraCompleteWidth = terminal.CameraWidth;
- int cameraCompleteHeight = terminal.CameraHeight;
- byte[] terminalData;
- byte[] cameraData;
- if (liveProtocol == LiveProtocol.RTC)
- {
- var terminalBytes = terminalCompleteWidth * terminalCompleteHeight * 4;
- var cameraBytes = cameraCompleteWidth * cameraCompleteHeight * 4;
- _termialLiveDataBytes.Update(e.Data, terminalBytes, cameraBytes,
- terminalCompleteWidth, terminalCompleteHeight, e.Width, _imageHelper.OSType);
- terminalData = _termialLiveDataBytes.TerminalData;
- cameraData = _termialLiveDataBytes.CameraData;
- }
- else
- {
- _imageHelper.SplitImageData(ref _liveDataBytes, e, terminalCompleteWidth, terminalCompleteHeight, cameraCompleteWidth, cameraCompleteHeight, needCameraData);
- terminalData = _liveDataBytes.TerminalData;
- cameraData = _liveDataBytes.CameraData;
- }
- if (terminalData != null)
- {
- ResizeVideoFrameData(ref _completeVideoFrameData, terminalCompleteWidth, terminalCompleteHeight, terminalData, e.ImageData);
- OnTerminalVideoFrameArrived(sender, _completeVideoFrameData);
- }
- if (needCameraData)
- {
- if (cameraData != null)
- {
- ResizeVideoFrameData(ref _cameraVideoFrameData, cameraCompleteWidth, cameraCompleteHeight, cameraData);
- OnTerminalCameraFrameArrived(sender, _cameraVideoFrameData);
- }
- }
- }
- else if (terminal.TerminalLiveEnabled && !terminal.CameraLiveEnabled)
- {
- var width = terminal.TerminalWidth;
- var height = terminal.TerminalHeight;
- if (liveProtocol == LiveProtocol.RTC && width > 0 && height > 0)
- {
- var terminallength = width * height * 4;
- if (_rtcTerminalLiveDataBuffer == null)
- {
- _rtcTerminalLiveDataBuffer = new byte[terminallength];
- }
- else if (terminallength != _rtcTerminalLiveDataBuffer.Length)
- {
- Array.Resize(ref _rtcTerminalLiveDataBuffer, terminallength);
- }
- if (_rtcTerminalLiveDataBuffer.Length >= terminallength)
- {
- for (int row = 0; row < height; row++)
- {
- Array.Copy(e.Data, row * e.Width * 4, _rtcTerminalLiveDataBuffer, row * width * 4, width * 4);
- }
- }
- else
- {
- if (_imagePreviewErrorLogCount++ < 1)
- {
- Logger.WriteLineError($"rtcTerminalLiveDataBuffer is small than terminal data size, " +
- $"terminal width:{terminal.TerminalWidth}, " +
- $"terminal height:{terminal.TerminalHeight},terminal array length:{terminallength} " +
- $"destination array length: {_rtcTerminalLiveDataBuffer.Length}, data size {e.Width}*{e.Height}");
- }
- }
- ResizeVideoFrameData(ref _rtcTerminaVideoFrameData, width, height, _rtcTerminalLiveDataBuffer);
- OnTerminalVideoFrameArrived(sender, _rtcTerminaVideoFrameData);
- }
- else
- {
- OnTerminalVideoFrameArrived(sender, e);
- }
- }
- else if (terminal.CameraLiveEnabled && !terminal.TerminalLiveEnabled)
- {
- OnTerminalCameraFrameArrived(sender, e);
- }
- _imagePreviewErrorLogCount = 0;
- }
- }
- catch (Exception ex)
- {
- if (_imagePreviewErrorLogCount++ < 1)
- {
- Logger.WriteLineError($"destination array length: {_rtcTerminalLiveDataBuffer?.Length}, data size: {e?.Width}*{e?.Height}");
- Logger.WriteLineError($"OnPreviewImageReceived ex:{ex}");
- }
- }
- }
- /// <summary>
- /// 会诊人员发生变化
- /// </summary>
- public void ConsultationMemberChange(MeetingMemberNotification meetingChangeMember)
- {
- var members = meetingChangeMember.Members;
- if (_liveProtocol == LiveProtocol.RTC)
- {
- foreach (var member in members)
- {
- var memberInfo = DTOConverter.ConvertMeetingMemberInfoMessageToMeetingMemberInfo(member);
- if (member.OperationType == ClientMessageOperationType.Add)
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider == null)
- {
- _videoProviders.Add(new RtcVideoProvider(memberInfo));
- }
- else
- {
- videoProvider.ConsultationMemberInfo = memberInfo;
- }
- }
- else if (member.OperationType == ClientMessageOperationType.Delete)
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider != null)
- {
- videoProvider.Dispose();
- _videoProviders.Remove(videoProvider);
- }
- }
- }
- }
- else if (_liveProtocol == LiveProtocol.Rtmp)
- {
- foreach (var member in members)
- {
- var memberInfo = DTOConverter.ConvertMeetingMemberInfoMessageToMeetingMemberInfo(member);
- if (member.OperationType == ClientMessageOperationType.Add)
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider == null)
- {
- CreateRtmpPlayer(memberInfo);
- }
- else
- {
- videoProvider.ConsultationMemberInfo = memberInfo;
- }
- }
- else if (member.OperationType == ClientMessageOperationType.Delete)
- {
- var videoProvider = _videoProviders.FirstOrDefault(f => f.ConsultationMemberInfo.Id == member.Id);
- if (videoProvider != null)
- {
- videoProvider.Dispose();
- _videoProviders.Remove(videoProvider);
- }
- }
- }
- }
- }
- public void RemoveVideoProvider(string userId)
- {
- lock (_startConsultationLocker)
- {
- if (_videoProviders.Count > 0)
- {
- var video = _videoProviders.FirstOrDefault(v => v.ConsultationMemberInfo.Id == userId);
- if (video != null)
- {
- video.Dispose();
- _videoProviders.Remove(video);
- }
- if (_liveProtocol == LiveProtocol.RTC)
- {
- if (_videoProviders.Count <= 1)
- {
- _rtcRoom.LocalVideoFrameArrived -= OnRtcLocalVideoFrameArrived;
- _rtcRoom.RemoteVideoFrameArrived -= OnRtcRemoteVideoFrameArrived;
- _rtcRoom.TryToReconnect -= OnTryToReconnect;
- _rtcRoom.RemoteUserLeaveRoomArrived -= OnRemoteUserLeaveRoomArrived;
- _rtcRoom.Exit();
- for (int i = _videoProviders.Count - 1; i >= 0; i--)
- {
- _videoProviders[i].Dispose();
- }
- _videoProviders.Clear();
- }
- }
- else if (_liveProtocol == LiveProtocol.Rtmp)
- {
- if (_videoProviders.Count <= 1)
- {
- for (int i = _videoProviders.Count - 1; i >= 0; i--)
- {
- UnregisterReference(_videoProviders[i]);
- _videoProviders[i].Dispose();
- }
- _videoProviders.Clear();
- }
- }
- if (_videoProviders.Count == 0)
- {
- if (_terminalMergePlayer != null)
- {
- _terminalMergePlayer.VideoFrameReceived -= OnRtmpUltrasoundMergeImageFrameReceived;
- _terminalMergePlayer.StatusChanged -= OnRtmpUltrasoundMergeVideoStatusChanged;
- _terminalMergePlayer.Stop();
- _terminalMergePlayer = null;
- }
- if (_terminalVideoPlayer != null)
- {
- _terminalVideoPlayer.VideoFrameReceived -= OnTerminalVideoFrameArrived;
- _terminalVideoPlayer.StatusChanged -= OnTerminalVideoStatusChanged;
- _terminalVideoPlayer.Stop();
- _terminalVideoPlayer = null;
- }
- if (_terminalCameraPlayer != null)
- {
- _terminalCameraPlayer.VideoFrameReceived -= OnTerminalCameraFrameArrived;
- _terminalCameraPlayer.StatusChanged -= OnTerminalCameraVideoStatusChanged;
- _terminalCameraPlayer.Stop();
- _terminalCameraPlayer = null;
- }
- }
- }
- }
- }
- private void OnRtmpUltrasoundMergeVideoStatusChanged(object sender, CPLiveStatusData e)
- {
- var terminalInfo = _consultationInfo?.TerminalInfo;
- if (terminalInfo.TerminalLiveEnabled)
- {
- OnTerminalVideoStatusChanged(this, e);
- }
- if (terminalInfo.CameraLiveEnabled)
- {
- OnTerminalCameraVideoStatusChanged(this, e);
- }
- }
- private void OnTerminalCameraVideoStatusChanged(object sender, CPLiveStatusData e)
- {
- CameraLiveStatusChanged?.Invoke(this, e);
- }
- private void OnTerminalVideoStatusChanged(object sender, CPLiveStatusData e)
- {
- TerminalLiveStatusChanged?.Invoke(this, e);
- }
- /// <summary>
- /// 挂断
- /// </summary>
- public void Hangup()
- {
- if (!_isConsulting)
- {
- return;
- }
- lock (_startConsultationLocker)
- {
- try
- {
- if (_isConsulting)
- {
- if (_videoProviders.Count > 0)
- {
- if (_liveProtocol == LiveProtocol.RTC)
- {
- _rtcRoom.LocalVideoFrameArrived -= OnRtcLocalVideoFrameArrived;
- _rtcRoom.RemoteVideoFrameArrived -= OnRtcRemoteVideoFrameArrived;
- _rtcRoom.TryToReconnect -= OnTryToReconnect;
- _rtcRoom.RemoteUserLeaveRoomArrived -= OnRemoteUserLeaveRoomArrived;
- _rtcRoom.Exit();
- for (int i = _videoProviders.Count - 1; i >= 0; i--)
- {
- _videoProviders[i].Dispose();
- }
- _videoProviders.Clear();
- }
- else if (_liveProtocol == LiveProtocol.Rtmp)
- {
- for (int i = _videoProviders.Count - 1; i >= 0; i--)
- {
- var videoProvider = _videoProviders[i];
- UnregisterReference(videoProvider);
- videoProvider.Dispose();
- }
- _videoProviders.Clear();
- }
- }
- if (_terminalMergePlayer != null)
- {
- _terminalMergePlayer.VideoFrameReceived -= OnRtmpUltrasoundMergeImageFrameReceived;
- _terminalMergePlayer.Stop();
- _terminalMergePlayer = null;
- }
- if (_terminalVideoPlayer != null)
- {
- _terminalVideoPlayer.VideoFrameReceived -= OnTerminalVideoFrameArrived;
- _terminalVideoPlayer.Stop();
- _terminalVideoPlayer = null;
- }
- if (_terminalCameraPlayer != null)
- {
- _terminalCameraPlayer.VideoFrameReceived -= OnTerminalCameraFrameArrived;
- _terminalCameraPlayer.Stop();
- _terminalCameraPlayer = null;
- }
- }
- }
- catch (Exception ex)
- {
- Logger.WriteLineInfo($"Hangup failed ex: {ex}");
- }
- finally
- {
- _isConsulting = false;
- }
- }
- }
- private void UnregisterReference(VideoProvider videoProvider)
- {
- if (videoProvider.ConsultationMemberInfo.Id == _accountId)
- {
- videoProvider.VideoFrameArrived -= OnLocalVideoFrameArrived;
- videoProvider.Offlined -= OnOfflined;
- }
- else
- {
- videoProvider.VideoFrameArrived -= OnRemoteVideoFrameArrived;
- videoProvider.Offlined -= OnOfflined;
- }
- }
- public void SwitchCamera()
- {
- lock (_lock)
- {
- if (_isConsulting && _consultationInfo != null)
- {
- if (_liveProtocol == LiveProtocol.RTC)
- {
- _rtcRoom?.SwitchCamera();
- }
- else
- {
- var rtmpPusher = (RtmpVideoPusher)_videoProviders.FirstOrDefault(x => x is RtmpVideoPusher);
- if (rtmpPusher != null)
- {
- rtmpPusher.SwitchCamera();
- }
- }
- }
- }
- }
- public void Mute(bool isMute)
- {
- lock (_lock)
- {
- if (_isConsulting && _consultationInfo != null)
- {
- if (_liveProtocol == LiveProtocol.RTC)
- {
- _rtcRoom?.Mute(isMute);
- }
- else
- {
- var rtmpPusher = (RtmpVideoPusher)_videoProviders.FirstOrDefault(x => x is RtmpVideoPusher);
- if (rtmpPusher != null)
- {
- rtmpPusher.SetMute(isMute);
- }
- }
- }
- }
- }
- public void Dispose()
- {
- Hangup();
- }
- }
- }
|