using agora_gaming_rtc; using SC.XR.Unity; using ShadowStudio.Model; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Serialization; using UnityEngine.UI; using XRTool.Util; using static agora_gaming_rtc.ExternalVideoFrame; public class AgoraRTCManager : SingletonMono<AgoraRTCManager> { [Header("_____________Basic Configuration_____________")] [FormerlySerializedAs("APP_ID")] [SerializeField] private string _appID = ""; [FormerlySerializedAs("TOKEN")] [SerializeField] private string _token = ""; [FormerlySerializedAs("CHANNEL_NAME")] [SerializeField] private string _channelName = ""; private uint uid; private string peerid; internal IRtcEngine RtcEngine = null; private AgoraCustomPeer myPeer; private Dictionary<string, uint> dicPeeridAndUid; private List<AgoraCustomPeer> listCustomPeer; public bool isSwitchCamera; public uint Uid { get { return uid; } set { uid = value; } } public AgoraCustomPeer MyPeer { get { return myPeer; } set { if(value!=null) myPeer = value; } } public string ChannelName { get { return _channelName; } set { if (value != null) _channelName = value; } } public string PeerId { get { return peerid; } set { if (value != null) peerid = value; } } private void Start() { LoadAssetData(); //if (_appID.Length > 10) //{ //} InitEngine(); dicPeeridAndUid = new Dictionary<string, uint>(); isSwitchCamera = false; listCustomPeer = new List<AgoraCustomPeer>(); } private void Update() { } //Show data in AgoraBasicProfile [ContextMenu("ShowAgoraBasicProfileData")] private void LoadAssetData() { } private void InitEngine() { RtcEngine = IRtcEngine.GetEngine(_token); RtcEngine.DisableVideo(); } public void JoinChannel() { Debug.Log(" JoinChannel " + _channelName); RtcEngine.EnableAudio(); if(DeviceType.type!="LeiNiao") { RtcEngine.DisableVideo(); } RtcEngine.SetChannelProfile(CHANNEL_PROFILE.CHANNEL_PROFILE_COMMUNICATION); RtcEngine.SetClientRole(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER); RtcEngine.JoinChannel(_channelName, "", uid); RtcEngine.DisableVideo(); RtcEngine.DisableVideoObserver(); StartCoroutine(InitVideoAndAduio(1f)); if (!RTCINIT) { RTCINIT = true; if (DeviceType.type != "LeiNiao") { //StartCoroutine(RenderTexturesScreenCapture()); } } } static bool RTCINIT; Texture2D screenShot; IEnumerator RenderTexturesScreenCapture() { Debug.Log("RenderTexturesScreenCapture����ͼƬ1"); yield return new WaitForEndOfFrame(); if (screenShot == null) { screenShot = new Texture2D(1280, 720, TextureFormat.RGBA32, false); StartCoroutine(GetRenederFPS()); } while (true) { // if (isSendVideo) // continue; // img.texture = RemoteRtc.Instance.cam.activeTexture; // RenderTexture.active = ca.activeTexture; // screenShot.ReadPixels(new Rect(0, 0, ca.activeTexture.width, ca.activeTexture.height), 0, 0); // screenShot.Apply(); //Camera.main.targetTexture = null; // RenderTexture.active = null; yield return new WaitForSeconds(0.05f); if (bts != null) { // screenShot = HorizontalFlipTexture(screenShot2); var timetick = System.DateTime.Now.Ticks / 10000; ExternalVideoFrame externalVideoFrame = new ExternalVideoFrame(); externalVideoFrame.type = VIDEO_BUFFER_TYPE.VIDEO_BUFFER_RAW_DATA; externalVideoFrame.format = VIDEO_PIXEL_FORMAT.VIDEO_PIXEL_RGBA; externalVideoFrame.buffer = bts;// screenShot.GetRawTextureData(); externalVideoFrame.stride = (int)screenShot.width; externalVideoFrame.height = (int)screenShot.height; externalVideoFrame.rotation = 180; externalVideoFrame.cropLeft = 1; externalVideoFrame.cropRight = 1; externalVideoFrame.timestamp = timetick; RtcEngine.PushVideoFrame(externalVideoFrame); // Debug.Log("�����С���������"); } } } public Camera cam2; byte[] bts; IEnumerator GetRenederFPS() { while (true) { var req = AsyncGPUReadback.Request(cam2.activeTexture); yield return new WaitUntil(() => req.done); if (!req.hasError) { if (bts == null) { bts = new byte[req.layerDataSize]; } req.GetData<byte>().CopyTo(bts); // screenShot.LoadRawTextureData(bts); // screenShot.Apply(); // tex.SetPixels32(req.GetData<Color32>().ToArray()); // img.texture = screenShot; } else { Debug.LogError("Error AsyncGPUReadbackRequest.hasError"); } } } public void LeaveChannel() { Debug.Log("LeaveChannel "); int msg = RtcEngine.LeaveChannel(); switch (msg) { case 0: Debug.Log( "成功退出频道: " + _channelName); break; default: Debug.Log("退出频道失败: " + msg); break; } } public void ClearDatas() { myPeer = null; dicPeeridAndUid.Clear(); dicPeeridAndUid = new Dictionary<string, uint>(); listCustomPeer.Clear(); listCustomPeer = new List<AgoraCustomPeer>(); } private IEnumerator InitVideoAndAduio(float times) { yield return new WaitForSeconds(times); // MuteLocalVideoStream(CustomInfo.isSendVideo); MuteLocalAudioStream(CustomInfo.isSendAudio); MyPeer.isAudio = true; // MyPeer.isVideo = true; } public void AddDicPeerData(string peerid, uint uid) { if (dicPeeridAndUid.ContainsKey(peerid)) return; dicPeeridAndUid.Add(peerid, uid); AgoraCustomPeer peer = new AgoraCustomPeer(); peer.AgoraInit(peerid); listCustomPeer.Add(peer); if (peerid == PeerId) MyPeer = peer; } public void RemDicPeerData(string peerid) { Debug.Log(" RemAtPeeridUid " + peerid + " " + uid); dicPeeridAndUid.Remove(peerid); for (int i = 0; i < listCustomPeer.Count; i++) { if (listCustomPeer[i].peerId == peerid) listCustomPeer.Remove(listCustomPeer[i]); } } public void SetCustomPeerName(string peerid, string name) { Debug.Log("SetListCustomPeer " + peerid + " " + name); for (int i = 0; i < listCustomPeer.Count; i++) { if (peerid == listCustomPeer[i].peerId) { listCustomPeer[i].SetName(name); break; } } } public AgoraCustomPeer GetCustomPeer(string peerid) { Debug.Log("GetListCustomPeer " + peerid); for (int i = 0; i < listCustomPeer.Count; i++) { if (listCustomPeer[i].peerId == peerid) return listCustomPeer[i]; } return null; } public void AgoarRawImageVideoView(string peerId, RawImage rawImage) { Debug.Log(" AgoarRawImageVideoView " + peerId); try { if (peerId == CommonMethod.MyPeer.PeerId) { rawImage.gameObject.SetActive(true); rawImage.rectTransform.localEulerAngles = new Vector3(0, 180, 180); MakeVideoView(0, rawImage); } else if (dicPeeridAndUid.ContainsKey(peerId)) { // list_ShowView.Add(peerId, rawImage); rawImage.gameObject.SetActive(true); rawImage.rectTransform.localEulerAngles = new Vector3(0, 0, 180); MakeVideoView(dicPeeridAndUid[peerId], rawImage, this._channelName); } } catch (System.Exception e) { HttpsSendLog.Instance.SendLog("Agora", e.ToString()); } } public void MuteLocalAudioStream(bool isAudio) { int msg = RtcEngine.MuteLocalAudioStream(!isAudio); // int msg = RtcEngine.EnableLocalAudio(isAudio); switch (msg) { case 0: Debug.Log(isAudio ? "打开本地音频成功" : "关闭本地音频成功 "); MyPeer.isOpenAduio = !isAudio; break; default: Debug.LogError("开关本地音频失败: " + msg); break; } } public void MuteRemoteAudioStream(string peerid, bool isAudio) { Debug.Log(peerid); if (!dicPeeridAndUid.ContainsKey(peerid)) return; int msg = RtcEngine.MuteRemoteAudioStream(dicPeeridAndUid[peerid], !isAudio); switch (msg) { case 0: Debug.Log(isAudio ? "订阅远端音频成功" : "取订远端音频成功 "); break; default: Debug.LogError("开关本地音频失败: " + msg); break; } } public void MuteLocalVideoStream(bool isVideo) { return; if(isVideo) { XRRGBCamera.Instance.playCamera(CustomInfo.mWidth, CustomInfo.mHight); } else { XRRGBCamera.Instance.stopCamera(); } int msg = RtcEngine.MuteLocalVideoStream(!isVideo); //RtcEngine.EnableVideo(); //int msg = RtcEngine.EnableLocalVideo(isVideo); switch (msg) { case 0: Debug.Log(isVideo ? "打开本地视频成功 " : "关闭本地视频成功 "); // myPeer.isCloseVideo = !isVideo; MyPeer.isOpenVideo = !isVideo; break; default: Debug.LogError("开关本地视频失败: " + msg); break; } } public void MuteRemoteVideoStream(string peerid, bool isVideo) { // Debug.Log(peerid); if (!dicPeeridAndUid.ContainsKey(peerid)) return; int msg = RtcEngine.MuteRemoteVideoStream(dicPeeridAndUid[peerid], !isVideo); switch (msg) { case 0: Debug.Log(isVideo ? "订阅远端视频成功" : "取订远端视频成功 "); break; default: Debug.LogError("开关本地音频失败: " + msg); break; } } public void RemoteVideoStateChanged(uint uid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason) { Debug.Log(uid + " " + state + " " + reason); Debug.Log("RemoteVideoStateChanged " + uid); if (!dicPeeridAndUid.ContainsValue(uid)) return; for (int i = 0; i < listCustomPeer.Count; i++) { if (dicPeeridAndUid[listCustomPeer[i].peerId] == uid) { switch (state) { case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_STOPPED: // listCustomPeer[i].isVideo = false; break; case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_STARTING: listCustomPeer[i].isVideo = true; break; case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_DECODING: listCustomPeer[i].isOpenVideo = false; break; case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_FROZEN: break; case REMOTE_VIDEO_STATE.REMOTE_VIDEO_STATE_FAILED: // listCustomPeer[i].isVideo = false; break; default: break; } switch (reason) { case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_INTERNAL: break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION://网络阻塞�? // listCustomPeer[i].isVideo = false; break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY:// 网络恢复正常�? // listCustomPeer[i].isVideo = true; break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED://本地用户停止接收远端视频流或本地用户禁用视频模块 listCustomPeer[i].isOpenVideo = true; break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED://本地用户恢复接收远端视频流或本地用户启动视频模块 listCustomPeer[i].isOpenVideo = false; break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED://远端用户停止发送视频流或远端用户禁用视频模块�? listCustomPeer[i].isVideo = false; // CloseAgoraMainImage(listCustomPeer[i].peerId, false); break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED://远端用户恢复发送视频流或远端用户启用视频模块�? listCustomPeer[i].isVideo = true; // CloseAgoraMainImage(listCustomPeer[i].peerId, true); break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE: //远端用户离开频道�? listCustomPeer[i].isVideo = false; break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK: break; case REMOTE_VIDEO_STATE_REASON.REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK_RECOVERY: break; default: break; } break; } } } public void RemoteAudioStateChanged(uint uid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason) { Debug.Log(uid + " " + state + " " + reason); // Debug.Log("RemoteAudioStateChanged " + uid); if (!dicPeeridAndUid.ContainsValue(uid)) return; // Debug.Log("RemoteAudioStateChanged " + 1); for (int i = 0; i < listCustomPeer.Count; i++) { Debug.Log(listCustomPeer[i].peerId); if (dicPeeridAndUid[listCustomPeer[i].peerId] == uid) { // Debug.Log("RemoteAudioStateChanged " + 2); switch (state) { case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_STOPPED: // listCustomPeer[i].isAudio = false; break; case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_STARTING: listCustomPeer[i].isAudio = true; break; case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_DECODING: listCustomPeer[i].isOpenAduio = false; break; case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_FROZEN: break; case REMOTE_AUDIO_STATE.REMOTE_AUDIO_STATE_FAILED: // listCustomPeer[i].isAudio = false; break; default: break; } switch (reason) { case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_INTERNAL: break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_NETWORK_CONGESTION: // listCustomPeer[i].isAudio = false; break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_NETWORK_RECOVERY: // listCustomPeer[i].isAudio = true; break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_LOCAL_MUTED: listCustomPeer[i].isOpenAduio = true; break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_LOCAL_UNMUTED: listCustomPeer[i].isOpenAduio = false; break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_REMOTE_MUTED: listCustomPeer[i].isAudio = false; break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_REMOTE_UNMUTED: listCustomPeer[i].isAudio = true; break; case REMOTE_AUDIO_STATE_REASON.REMOTE_AUDIO_REASON_REMOTE_OFFLINE: listCustomPeer[i].isAudio = false; break; default: break; } break; } } } private void OnDestroy() { Debug.Log("OnDestroy"); if (RtcEngine == null) return; RtcEngine.LeaveChannel(); } internal static void MakeVideoView(uint uid, RawImage rawImage, string channelId = "") { Debug.Log("MakeVideoView " + uid); //var go = GameObject.Find(uid.ToString()); //if (!ReferenceEquals(go, null)) //{ // return; // reuse //} // create a GameObject and assign to this new user // var videoSurface = MakePlaneSurface(uid.ToString()); // configure videoSurface if (uid == 0) { rawImage.transform.localEulerAngles = Vector3.zero; //videoSurface.SetForUser(uid, channelId); rawImage.texture = AgoraRTCManager.Instance.cam2.activeTexture; } else { rawImage.transform.localEulerAngles = new Vector3(-180,180,0); var videoSurface = MakeImageSurface(rawImage); if (ReferenceEquals(videoSurface, null)) return; videoSurface.SetForUser(uid); videoSurface.SetEnable(true); } //videoSurface.OnTextureSizeModify += (int width, int height) => //{ // float scale = (float)height / (float)width; // videoSurface.transform.localScale = new Vector3(-5, 5 * scale, 1); // Debug.Log("OnTextureSizeModify: " + width + " " + height); //}; } internal static void OnUserJoined(uint uid) { // _videoSample.Log.UpdateLog(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed)); // Debug.Log(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed)) AgoraRTCManager.Instance.RtcEngine.GetUserInfoByUid(uid); } internal static void OnRemoteVideoStateChanged(uint uid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason) { AgoraRTCManager.Instance.RemoteVideoStateChanged(uid, state, reason); } internal static void OnRemoteAudioStateChanged(uint uid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason) { AgoraRTCManager.Instance.RemoteAudioStateChanged(uid, state, reason); } #region -- Video Render UI Logic --- // VIDEO TYPE 1: 3D Object private static VideoSurface MakePlaneSurface(string goName) { var go = GameObject.CreatePrimitive(PrimitiveType.Quad); //for (int i = 0; i < list_UserInfo.Count; i++) //{ // if (list_UserInfo[i].uid.ToString() == goName) // { // string userAccount = list_UserInfo[i].userAccount; // if (AgoraVideoAudioManager.Instance.list_ShowView.ContainsKey(list_UserInfo[i].userAccount)) // { // go = AgoraVideoAudioManager.Instance.list_ShowView[list_UserInfo[i].userAccount].gameObject; // } // else // Debug.LogError(" Agora ShowView is NULL "); // } //} if (go == null) { go = GameObject.CreatePrimitive(PrimitiveType.Plane); return null; } go.name = goName; // set up transform go.transform.Rotate(-90.0f, 0.0f, 0.0f); var yPos = Random.Range(3.0f, 5.0f); var xPos = Random.Range(-2.0f, 2.0f); go.transform.position = Vector3.zero; go.transform.localScale = new Vector3(0.25f, 0.5f, 0.5f); // configure videoSurface var videoSurface = go.AddComponent<VideoSurface>(); return videoSurface; } // Video TYPE 2: RawImage private static VideoSurface MakeImageSurface(RawImage rawImage) { var videoSurface = rawImage.gameObject.AddComponent<VideoSurface>(); return videoSurface; } #endregion }