|
@@ -0,0 +1,231 @@
|
|
|
+using fis.media.Library.Media.Members;
|
|
|
+using fis.media.Library.Media.Players;
|
|
|
+using fis.media.Library.Media.Publisher;
|
|
|
+using fis.media.Library.Media.Rooms;
|
|
|
+using fis.media.Library.OutPut.FisVideoFrameOutput;
|
|
|
+using fis.media.Library.Players;
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+
|
|
|
+namespace fis.media.Managers
|
|
|
+{
|
|
|
+ public class ChatRoomManager
|
|
|
+ {
|
|
|
+ private ChatRoomManager()
|
|
|
+ {
|
|
|
+ Pusher =PusherManager.Instance;
|
|
|
+ Player = PlayerManager.Instance;
|
|
|
+ //默认为TRTC房间
|
|
|
+ RoomType = RoomTypeEnum.TRTCRoom;
|
|
|
+ _videoStreamStructre = new VideoStreamStructre();
|
|
|
+ }
|
|
|
+ private static ChatRoomManager _instance;
|
|
|
+ private RoomTypeEnum _roomType;
|
|
|
+ private VideoStreamStructre _videoStreamStructre;
|
|
|
+
|
|
|
+ public static ChatRoomManager Instance => _instance ?? (_instance = new ChatRoomManager());
|
|
|
+ public IRoom Room { get; private set; }
|
|
|
+ public PusherManager Pusher { get; set; }
|
|
|
+ public PlayerManager Player { get; set; }
|
|
|
+
|
|
|
+ public event EventHandler<VideoStreamStructre> VideoStreamOutputInvoked;
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 进入房间
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="roomType"></param>
|
|
|
+ /// <param name="members"></param>
|
|
|
+ /// <param name="args"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool Enter(RoomTypeEnum roomType, List<AbstractMember> members,string[] args)
|
|
|
+ {
|
|
|
+ RoomType = roomType;
|
|
|
+ foreach (var c in members)
|
|
|
+ {
|
|
|
+ Room.EnterRoom(c);
|
|
|
+ }
|
|
|
+ var memebers = Room.Members;
|
|
|
+ foreach (var m in memebers)
|
|
|
+ {
|
|
|
+ var channels = m.Player.PlayerChannels;
|
|
|
+ foreach (var channel in channels)
|
|
|
+ {
|
|
|
+ channel.FrameRecieved += OnChannelFrameRevieved;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var commonStartupArgs= new List<string> { $"{RoomType}" };
|
|
|
+
|
|
|
+ foreach (var arg in args)
|
|
|
+ {
|
|
|
+ commonStartupArgs.Add(arg);
|
|
|
+ }
|
|
|
+ Pusher.Start(commonStartupArgs.ToArray());
|
|
|
+
|
|
|
+ Pusher.PreviewImageReceived += OnPreviewImageReceived;
|
|
|
+
|
|
|
+ Player.Start(commonStartupArgs.ToArray());
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnPreviewImageReceived(object? sender, LocalPreviewVideoFrameData e)
|
|
|
+ {
|
|
|
+ var selfMember = Room.Members.FirstOrDefault(x => x.Id == e.UserId);
|
|
|
+ var activeMember= selfMember as ActiveMember;
|
|
|
+ var channelVideoFrame = new ChannelVideoFrame(e.Data,activeMember.Id, ChannelNameEnum.Main,activeMember.RoleType);
|
|
|
+ OnChannelFrameRevieved(this, channelVideoFrame);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void OnChannelFrameRevieved(object? sender, ChannelVideoFrame e)
|
|
|
+ {
|
|
|
+ var existOuput = _videoStreamStructre.VideoChannels.FirstOrDefault(x => x.Id == e.ChannelOwnerId
|
|
|
+ && x.ChannelDisplayName == e.ChannelNameEnum.ToString());
|
|
|
+ if (existOuput == null)
|
|
|
+ {
|
|
|
+ var outPut = GenerateOutput(e);
|
|
|
+ outPut.UpdataFrameData(e.VideoFrameData.ToBase64());
|
|
|
+ _videoStreamStructre.VideoChannels.Add(outPut);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ existOuput.UpdataFrameData(e.VideoFrameData.ToBase64());
|
|
|
+ }
|
|
|
+ VideoStreamOutputInvoked?.Invoke(this,_videoStreamStructre);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 更新成员状态
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="abstractMember"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool UpdateMember(AbstractMember abstractMember)
|
|
|
+ {
|
|
|
+ var memeber = Room.Members.FirstOrDefault(x => x.Id == abstractMember.Id);
|
|
|
+ if (memeber == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ var activeExistMemeber= memeber as ActiveMember;
|
|
|
+ var activeMemeber = abstractMember as ActiveMember;
|
|
|
+ if (activeMemeber != null && activeExistMemeber != null)
|
|
|
+ {
|
|
|
+ activeExistMemeber.IsOnline = activeMemeber.IsOnline;
|
|
|
+ activeExistMemeber.IsMute = activeMemeber.IsMute;
|
|
|
+ activeExistMemeber.IsCameraOn = activeExistMemeber.IsCameraOn;
|
|
|
+ activeExistMemeber.IsMergeChannel = activeExistMemeber.IsMergeChannel;
|
|
|
+ return activeExistMemeber.AdaptMemberUpdate();
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 删除成员
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="abstractMember"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool RemoveMember(AbstractMember abstractMember)
|
|
|
+ {
|
|
|
+ var memeber = Room.Members.FirstOrDefault(x => x.Id == abstractMember.Id);
|
|
|
+ if (memeber == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ memeber.Dispose();
|
|
|
+ Room.Members.Remove(memeber);
|
|
|
+ return true;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool Exit()
|
|
|
+ {
|
|
|
+ Pusher.Dispose();
|
|
|
+ Player.Dispose();
|
|
|
+
|
|
|
+ var memebers = Room.Members;
|
|
|
+
|
|
|
+ foreach (var m in memebers)
|
|
|
+ {
|
|
|
+ var channels = m.Player.PlayerChannels;
|
|
|
+ foreach (var channel in channels)
|
|
|
+ {
|
|
|
+ channel.FrameRecieved -= OnChannelFrameRevieved;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Room.Dispose();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private RoomTypeEnum RoomType
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return _roomType;
|
|
|
+ }
|
|
|
+ set
|
|
|
+ {
|
|
|
+ if (_roomType != value)
|
|
|
+ {
|
|
|
+ _roomType = value;
|
|
|
+ SwithRoom();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void SwithRoom()
|
|
|
+ {
|
|
|
+ Room?.Dispose();
|
|
|
+ Room = null;
|
|
|
+ if (RoomType == RoomTypeEnum.TRTCRoom)
|
|
|
+ {
|
|
|
+ Room = TRTCRoom.Instance;
|
|
|
+ }
|
|
|
+ if (RoomType == RoomTypeEnum.RTMPVirtualRoom)
|
|
|
+ {
|
|
|
+ Room = RTMPRoom.Instance;
|
|
|
+ }
|
|
|
+ if (RoomType == RoomTypeEnum.VRTCRoom)
|
|
|
+ {
|
|
|
+ Room = VRTCRoom.Instance;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Channelbase GenerateOutput(ChannelVideoFrame e)
|
|
|
+ {
|
|
|
+ if (e.OwnerRoleType == MemeberTypeEnum.LocalVideo)
|
|
|
+ {
|
|
|
+ return new LocalCameraChannel(e.ChannelOwnerId, e.ChannelNameEnum.ToString());
|
|
|
+
|
|
|
+ }
|
|
|
+ if (e.OwnerRoleType == MemeberTypeEnum.RemoteVideo)
|
|
|
+ {
|
|
|
+ return new RemoteCameraChannel(e.ChannelOwnerId, e.ChannelNameEnum.ToString());
|
|
|
+ }
|
|
|
+ if (e.OwnerRoleType == MemeberTypeEnum.MainDeviceVideo)
|
|
|
+ {
|
|
|
+ if (e.ChannelNameEnum == ChannelNameEnum.Main)
|
|
|
+ {
|
|
|
+ return new MainChannel(e.ChannelOwnerId, e.ChannelNameEnum.ToString());
|
|
|
+ }
|
|
|
+ if (e.ChannelNameEnum == ChannelNameEnum.SideOne)
|
|
|
+ {
|
|
|
+ return new SideChannelOne(e.ChannelOwnerId, e.ChannelNameEnum.ToString());
|
|
|
+ }
|
|
|
+ if (e.ChannelNameEnum == ChannelNameEnum.SideTwo)
|
|
|
+ {
|
|
|
+ return new SideChannelTwo(e.ChannelOwnerId, e.ChannelNameEnum.ToString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+}
|