using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Vinno.FIS.TRTCClient.Common.Enum; using Vinno.vCloud.FIS.CrossPlatform.Common; using Vinno.vCloud.FIS.CrossPlatform.Common.Enum; using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo; using Vinno.vCloud.FIS.CrossPlatform.Common.LiveVideo.Interface; namespace Vinno.vCloud.FIS.CrossPlatform.Android.LiveVideo.RTMP { public class RtmpMultiPusherV2 : PusherBase, ILiveVideoPusherV2 { private readonly ConcurrentDictionary _pushers; public event EventHandler ChannelStateChanged; public RtmpMultiPusherV2() { _pushers = new ConcurrentDictionary(); } public bool StartPusher(IExtendedData pushParams, IEnumerable deviceInfos) { var rtmpParams = pushParams as RtmpExtendedData; if (rtmpParams == null || rtmpParams.UserInfos.Count == 0) { CrossPlatformHelper.Instance.LogWriter?.WriteLineError("RtmpMultiPusherV2 Extended Data Is Null!"); return false; } var userInfos = rtmpParams.UserInfos; for (int i = 0; i < userInfos.Count(); i++) { var deviceInfo = deviceInfos.FirstOrDefault(x => x.Category == userInfos[i].Category); if (deviceInfo != null) { var device = (CPVideoDeviceOutputInfo)deviceInfo.Clone(); bool isMute = true; string micId = ""; if (i == 0) { isMute = rtmpParams.IsMute; micId = rtmpParams.MicDeviceId; } var pusher = new DsRtmpPusher(device, userInfos[i].PushUrl, micId, isMute, userInfos[i].Width, userInfos[i].Height); if (_pushers.TryAdd(userInfos[i].Category, pusher)) { pusher.LiveStatusChanged += OnLiveStatusChanged; pusher.ImageFrameReceived += OnImageFrameReceived; pusher.Start(); } else { pusher.Dispose(); } } else { CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"RtmpMultiPusherV2 Can not find {userInfos[i].Category} User Info!"); } } return true; } public void SetMute(bool isMute) { if (_pushers.Count > 0) { _pushers[0].SetMute(isMute); } } private void OnLiveStatusChanged(object sender, EnumLiveStatus e) { if (e == EnumLiveStatus.Connected) { var category = (EnumLiveChannelCategory)sender; ChannelStateChanged?.Invoke(this, new ChannelStateEventArgsV2(category, EnumDeviceLiveState.Pushing)); } } private void OnImageFrameReceived(object sender, ImageFrameData e) { var category = (EnumLiveChannelCategory)sender; CopyPreviewData(category, e); } public bool StopPusher() { foreach (var pusher in _pushers.Values) { pusher.LiveStatusChanged -= OnLiveStatusChanged; pusher.ImageFrameReceived -= OnImageFrameReceived; pusher.Stop(); } return true; } public override void DoDispose() { foreach (var pusher in _pushers.Values) { pusher.Dispose(); } _pushers.Clear(); base.DoDispose(); } public void SwitchMic(string micId) { } public bool StartSpeedTest(uint appId, string userId, string userSign) { CrossPlatformHelper.Instance.LogWriter?.WriteLineError($"RtmpMultiPusherV2 Doesn't support StartSpeedTest"); return false; } } }