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; } } }