Browse Source

临时保存一下,打个包

DGJ 1 year ago
parent
commit
7b43b5e7fb

+ 64 - 14
Assets/AgoraVideoAudioManager.cs

@@ -1,9 +1,11 @@
 using Agora.Rtc;
 using Agora.Util;
 using SC.XR.Unity;
+using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
+using System.Text;
 using UnityEngine;
 using UnityEngine.Rendering;
 using UnityEngine.Serialization;
@@ -72,8 +74,18 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
         isRoom = false;
         isSwitchCamera = false;
         listCustomPeer = new List<CustomPeer>();
-      
-        
+
+        RTCManager.Instance.OnJoinChannel += JoinChannel;
+        RTCManager.Instance.OnLeaveChannel += LeaveChannel;
+        RTCManager.Instance.OnShowViewRawImage += AddListShowView;
+        RTCManager.Instance.OnMuteLocalAudioStream += EnableLoacalAudio;
+        RTCManager.Instance.OnMuteLocalVideoStream += EnableLocalVideo;
+        RTCManager.Instance.OnMuteRemoteAudioStream += MuteRemoteAudioStream;
+        RTCManager.Instance.OnMuteRemoteVideoStream += MuteRemoteVideoStream;
+        RTCManager.Instance.OnSetUid += SetUid;
+        RTCManager.Instance.OnSetChannelName += SetChinnelName;
+        RTCManager.Instance.OnAddPeeridUid += AddPeeridUid;
+        RTCManager.Instance.OnRemAtPeeridUid += RemAtPeeridUid;
     }
 
     // Update is called once per frame
@@ -126,7 +138,7 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
 
     private void InitEngine()
     {
-
+    
         RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine();
 
         AgoraVideoManagerHandler handler = new AgoraVideoManagerHandler(this);
@@ -147,6 +159,11 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
     {
         _channelName = roomid;
     }
+    public void SetUid(string uid)
+    {
+      
+        this.uid = StringToUint(uid);
+    }
 
     public void JoinChannel()
     {
@@ -325,6 +342,16 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
         dicPeeridAndUid.Add(peerid, uid);
     }
 
+    public void AddPeeridUid(string peerid, string strUid)
+    {
+        uint uid = StringToUint(strUid);
+        Debug.Log(" AddPeeridUid " + peerid + "   " + uid);
+
+        if (dicPeeridAndUid.ContainsKey(peerid))
+            return;
+        dicPeeridAndUid.Add(peerid, uid);
+    }
+
     public void RemAtPeeridUid(string peerid)
     {
         if (!dicPeeridAndUid.ContainsKey(peerid))
@@ -370,6 +397,22 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
         MakeVideoView(dicPeeridAndUid[peerId], rawImage, this._channelName);
     }
 
+    public void AddListShowView(string peerId, RawImage rawImage)
+    {
+
+        if (!dicPeeridAndUid.ContainsKey(peerId))
+            return;
+        Debug.Log(" AddListShowView " + peerId);
+
+        if (rawImage.name == "AgoraRawImage")
+            mainViewPeerId = peerId;
+
+        //  rawImage.gameObject.SetActive(true);
+        rawImage.rectTransform.localEulerAngles = new Vector3(0, 180, 180);
+
+        MakeVideoView(dicPeeridAndUid[peerId], rawImage, this._channelName);
+    }
+
     public void ShowOneView(RawImage rawImage)
     {
         if (dicPeeridAndUid.Count < 2)
@@ -432,11 +475,11 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
                 break;
         }
     }
-    public void MuteRemoteAudioStream(string peerid, bool isAudio)
+    public void MuteRemoteAudioStream(string uid, bool isAudio)
     {
         if (!dicPeeridAndUid.ContainsKey(peerid))
             return;
-        int msg = RtcEngine.MuteRemoteAudioStream(dicPeeridAndUid[peerid], !isAudio);
+        int msg = RtcEngine.MuteRemoteAudioStream(StringToUint(uid) , !isAudio);
 
         switch (msg)
         {
@@ -602,10 +645,14 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
             }
         }
 
+    }
 
+    private uint StringToUint(string value)
+    {
+        //byte[] bytes = Encoding.ASCII.GetBytes(value);
 
-
-
+        return (uint)int.Parse(value);
+       // return BitConverter.ToUInt32(bytes);
     }
     private void StopPublish()
     {
@@ -731,8 +778,8 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
         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);
+        //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);
 
@@ -764,8 +811,10 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
         //}
 
         // make the object draggable
-        if (rawImage.gameObject.GetComponent<UIElementDrag>() == null)
-            rawImage.gameObject.AddComponent<UIElementDrag>();
+        if (rawImage.gameObject.GetComponent<UIElementDrag>() != null)
+            Destroy(rawImage.gameObject.GetComponent<UIElementDrag>());
+
+        rawImage.gameObject.AddComponent<UIElementDrag>();
         //var canvas = GameObject.Find("VideoCanvas");
         //if (canvas != null)
         //{
@@ -781,9 +830,10 @@ public class AgoraVideoAudioManager : SingletonMono<AgoraVideoAudioManager>
 
         // configure videoSurface
 
-        if (rawImage.gameObject.GetComponent<VideoSurface>() == null)
-            rawImage.gameObject.AddComponent<VideoSurface>();
-        var videoSurface = rawImage.gameObject.GetComponent<VideoSurface>();
+        if (rawImage.gameObject.GetComponent<VideoSurface>() != null)
+            Destroy(rawImage.gameObject.GetComponent<VideoSurface>());
+
+        var videoSurface = rawImage.gameObject.AddComponent<VideoSurface>();
         return videoSurface;
     }
 

+ 3 - 2
Assets/AgoraVideoJo.cs

@@ -1,4 +1,4 @@
-using System.Collections;
+using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
@@ -12,6 +12,7 @@ public class AgoraVideoJo : MonoBehaviour
     IEnumerator JoinChannel(float times)
     {
         yield return new WaitForSeconds(times);
-        AgoraVideoAudioManager.Instance.JoinChannel();
+       // AgoraVideoAudioManager.Instance.JoinChannel();
+        RTCManager.Instance.JoinChannel();
     }
 }

+ 12 - 6
Assets/MediaSoup/WebSocket/WSRtcHandler.cs

@@ -296,7 +296,8 @@ public class WSRtcHandler  {
                             RoomMain.Instance.LeaveRoom();
                         }
                     }
-                    AgoraVideoAudioManager.Instance.RemAtPeeridUid(data["data"]["peerId"].ToString());
+                   // AgoraVideoAudioManager.Instance.RemAtPeeridUid(data["data"]["peerId"].ToString());
+                    RTCManager.Instance.RemAtPeeridUid(data["data"]["peerId"].ToString());
                     break;
                 case "chatMessage":
                     sendText(data["method"].ToString(), data["data"]);
@@ -304,8 +305,10 @@ public class WSRtcHandler  {
                 case "connect":
                     getRtpCapabilities("");
                     Debug.Log(data["data"][0]+ "  "+ data["data"][1]);
-                    AgoraVideoAudioManager.Instance.AddPeeridUid(data["data"][0].ToString(), (uint)int.Parse(data["data"][1].ToString()));
-                    AgoraVideoAudioManager.Instance.uid = (uint)int.Parse(data["data"][1].ToString());
+                    //AgoraVideoAudioManager.Instance.AddPeeridUid(data["data"][0].ToString(), (uint)int.Parse(data["data"][1].ToString()));
+                    //AgoraVideoAudioManager.Instance.uid = (uint)int.Parse(data["data"][1].ToString());
+                    RTCManager.Instance.AddPeeridUid(data["data"][0].ToString(), data["data"][1].ToString());
+                    RTCManager.Instance.SetUid(data["data"][1].ToString());
                     break;
                 case "newConsumer":
                     newConsumers.Enqueue(data.ToJson());
@@ -316,7 +319,8 @@ public class WSRtcHandler  {
                     SCRtcFactory.Instance.mSCRtcManager.OnRtcListener(data);
                     sendText(data["method"].ToString(), data["data"]);
                     SoundMgr._instance.PlayMusicByName("tishi", false);
-                    AgoraVideoAudioManager.Instance.AddPeeridUid(data["data"]["peerId"].ToString(), (uint)int.Parse(data["data"]["uid"].ToString()));
+                   // AgoraVideoAudioManager.Instance.AddPeeridUid(data["data"]["peerId"].ToString(), (uint)int.Parse(data["data"]["uid"].ToString()));
+                    RTCManager.Instance.AddPeeridUid(data["data"]["peerId"].ToString(), data["data"]["uid"].ToString());
                     break;
                 case "consumerPaused":
                     p = SCRtcFactory.Instance.mSCRtcPeers.getPeer(data["data"]["peerId"].ToString());
@@ -468,9 +472,11 @@ public class WSRtcHandler  {
                 {
                     for (int i = 0; i < data["data"]["room"]["users"].Count; i++)
                     {
-                        AgoraVideoAudioManager.Instance.AddPeeridUid(data["data"]["room"]["users"][i]["peerId"].ToString(), (uint)int.Parse(data["data"]["room"]["users"][i]["uid"].ToString()));
+                       // AgoraVideoAudioManager.Instance.AddPeeridUid(data["data"]["room"]["users"][i]["peerId"].ToString(), (uint)int.Parse(data["data"]["room"]["users"][i]["uid"].ToString()));
+                        RTCManager.Instance.AddPeeridUid(data["data"]["room"]["users"][i]["peerId"].ToString(), data["data"]["room"]["users"][i]["uid"].ToString());
                     }
-                    AgoraVideoAudioManager.Instance.ShowOneView(RoomMain.Instance.agoraRawImage);
+                   // AgoraVideoAudioManager.Instance.ShowOneView(RoomMain.Instance.agoraRawImage);
+                    RTCManager.Instance.ShowOneViewRawImage(RoomMain.Instance.agoraRawImage);
                 }
 
             }

+ 13 - 0
Assets/Remote/Scenes/Remote3.0.unity

@@ -811,6 +811,7 @@ GameObject:
   m_Component:
   - component: {fileID: 855958479}
   - component: {fileID: 855958480}
+  - component: {fileID: 855958481}
   m_Layer: 0
   m_Name: Agora
   m_TagString: Untagged
@@ -856,6 +857,18 @@ MonoBehaviour:
   isSwitchCamera: 0
   ca: {fileID: 284870648}
   img: {fileID: 948814504}
+--- !u!114 &855958481
+MonoBehaviour:
+  m_ObjectHideFlags: 0
+  m_CorrespondingSourceObject: {fileID: 0}
+  m_PrefabInstance: {fileID: 0}
+  m_PrefabAsset: {fileID: 0}
+  m_GameObject: {fileID: 855958478}
+  m_Enabled: 1
+  m_EditorHideFlags: 0
+  m_Script: {fileID: 11500000, guid: 8d18263e64ad01049a2377a0e7ad2281, type: 3}
+  m_Name: 
+  m_EditorClassIdentifier: 
 --- !u!1 &918637851
 GameObject:
   m_ObjectHideFlags: 0

+ 10 - 5
Assets/Remote/ShowRoom/PeerBigView.cs

@@ -34,7 +34,8 @@ public class PeerBigView : MonoBehaviour,IDragHandler,IEndDragHandler
         PopPeerView.CloseView += closeView;
         WSHandler.Rtc.OnActiveSpeaker += ActiveSpeaker;
 
-        AgoraVideoAudioManager.Instance.AddListShowView(cPeer.peerId, agoraRawImage, false);
+      //  AgoraVideoAudioManager.Instance.AddListShowView(cPeer.peerId, agoraRawImage, false);
+        RTCManager.Instance.ShowViewRawImage(cPeer.peerId, agoraRawImage);
     }
 
     private void OnDestroy()
@@ -191,7 +192,8 @@ public class PeerBigView : MonoBehaviour,IDragHandler,IEndDragHandler
         //    cPeer.isCloseVideo = false;
         //    // cPeer.setInfo("audio", cPeer.cIdA,true);
         //}
-        AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, true);
+     //   AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, true);
+        RTCManager.Instance.MuteRemoteVideoStream(cPeer.peerId, true);
         //agoraRawImage.gameObject.SetActive(true);
       //  RoomMain.Instance.agoraRawImage.gameObject.SetActive(true);
     }
@@ -203,7 +205,8 @@ public class PeerBigView : MonoBehaviour,IDragHandler,IEndDragHandler
         //    cPeer.isCloseVideo = true;
         //    // cPeer.setInfo("audio", cPeer.cIdA,true);
         //}
-        AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, false);
+       // AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, false);
+        RTCManager.Instance.MuteRemoteVideoStream(cPeer.peerId, false);
       //  agoraRawImage.gameObject.SetActive(false);
       //  RoomMain.Instance.agoraRawImage.gameObject.SetActive(false);
     }
@@ -218,7 +221,8 @@ public class PeerBigView : MonoBehaviour,IDragHandler,IEndDragHandler
         //    // cPeer.setInfo("audio", cPeer.cIdA,true);
         //}
        // cPeer.isCloseAudio = false;
-        AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, true);
+       // AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, true);
+        RTCManager.Instance.MuteRemoteAudioStream(cPeer.peerId, true);
     }
     public void closeMic()
     {
@@ -229,7 +233,8 @@ public class PeerBigView : MonoBehaviour,IDragHandler,IEndDragHandler
         //    //  cPeer.setInfo("audio", cPeer.cIdA, false);
         //}
        // cPeer.isCloseAudio = true;
-        AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, false);
+     //   AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, false);
+        RTCManager.Instance.MuteRemoteAudioStream(cPeer.peerId, false);
     }
 
     public void OnDrag(PointerEventData eventData)

+ 14 - 8
Assets/Remote/ShowRoom/PeerSamllView.cs

@@ -232,13 +232,15 @@ public class PeerSamllView : BaseView, IPointerEnterHandler, IPointerExitHandler
     }
     public void setBigView()
     {
-        if (cPeer == null)
-        {
-            return;
-        }
+        Debug.Log(" SetBigView ");
+        //if (cPeer == null)
+        //{
+        //    return;
+        //}
         RoomMain.Instance.setBigView(cPeer.tex,cPeer.peerId);
         RoomOtherUser.ShowAction?.Invoke(cPeer.peerId);
         AgoraVideoAudioManager.Instance.AddListShowView(cPeer.peerId, RoomMain.Instance.agoraRawImage, true);
+     //   RTCManager.Instance.ShowViewRawImage(cPeer.peerId, RoomMain.Instance.agoraRawImage);
     }
 
     public void showBigView()
@@ -321,7 +323,8 @@ public class PeerSamllView : BaseView, IPointerEnterHandler, IPointerExitHandler
         //}
 
         // cPeer.setInfo("audio", cPeer.cIdA,true);
-        AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, true);
+      //  AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, true);
+        RTCManager.Instance.MuteRemoteVideoStream(cPeer.peerId, true);
     //    RoomMain.Instance.agoraRawImage.gameObject.SetActive(true);
 
     }
@@ -336,7 +339,8 @@ public class PeerSamllView : BaseView, IPointerEnterHandler, IPointerExitHandler
         //}
 
         // cPeer.setInfo("audio", cPeer.cIdA,true);
-        AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, false);
+      //  AgoraVideoAudioManager.Instance.MuteRemoteVideoStream(cPeer.peerId, false);
+        RTCManager.Instance.MuteRemoteVideoStream(cPeer.peerId, false);
         RoomMain.Instance.agoraRawImage.gameObject.SetActive(false);
     }
 
@@ -353,7 +357,8 @@ public class PeerSamllView : BaseView, IPointerEnterHandler, IPointerExitHandler
         //}
        
         // cPeer.setInfo("audio", cPeer.cIdA,true);
-        AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, true);
+       // AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, true);
+        RTCManager.Instance.MuteRemoteAudioStream(cPeer.peerId,true);
     }
     public void closeMic()
     {
@@ -366,7 +371,8 @@ public class PeerSamllView : BaseView, IPointerEnterHandler, IPointerExitHandler
         //}
        
         //  cPeer.setInfo("audio", cPeer.cIdA, false);
-        AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, false);
+      //  AgoraVideoAudioManager.Instance.MuteRemoteAudioStream(cPeer.peerId, false);
+        RTCManager.Instance.MuteRemoteAudioStream(cPeer.peerId, false);
     }
 
     public void OnPointerEnter(PointerEventData eventData)

+ 10 - 5
Assets/Remote/ShowRoom/RoomMain.cs

@@ -136,8 +136,10 @@ public class RoomMain : RemoteSingleton<RoomMain>
         TitleRoomPeopleCount.text ="房间人数:"+ RoomMainInfo.roomPeopleNum + "/"+ RoomMainInfo.roomMaxPeopleNum;
         TitleRoomNum.text ="房间号:"+ RoomMainInfo.roomNum;
 
-        AgoraVideoAudioManager.Instance.SetChinnelName(RoomMainInfo.roomNum);
-        AgoraVideoAudioManager.Instance.JoinChannel();
+        //AgoraVideoAudioManager.Instance.SetChinnelName(RoomMainInfo.roomNum);
+        //AgoraVideoAudioManager.Instance.JoinChannel();
+        RTCManager.Instance.SetChannelName(RoomMainInfo.roomNum);
+        RTCManager.Instance.JoinChannel();
 
         isSendAudio = CustomInfo.isSendAudio;
         isSendVideo = CustomInfo.isSendVideo;
@@ -317,7 +319,8 @@ public class RoomMain : RemoteSingleton<RoomMain>
         }
         API_GSXR_Slam.GSXR_Reset_Slam();
 
-        AgoraVideoAudioManager.Instance.LeaveChannel();
+      //  AgoraVideoAudioManager.Instance.LeaveChannel();
+        RTCManager.Instance.LeaveChannel();
         RemoteRtc.Instance.FiltrationCamera(true);
     }
 
@@ -375,7 +378,8 @@ public class RoomMain : RemoteSingleton<RoomMain>
             dcetype = "video";
             closeVideoEffect();
         }
-        AgoraVideoAudioManager.Instance.EnableLocalVideo(isSend);
+      //  AgoraVideoAudioManager.Instance.EnableLocalVideo(isSend);
+        RTCManager.Instance.MuteLocalVideoStream(isSend);
     }
 
     public void sendAudio(bool isSend)
@@ -410,7 +414,8 @@ public class RoomMain : RemoteSingleton<RoomMain>
             openAudioEffect();
 
         }
-        AgoraVideoAudioManager.Instance.EnableLoacalAudio(isSend);
+       // AgoraVideoAudioManager.Instance.EnableLoacalAudio(isSend);
+        RTCManager.Instance.MuteLocalAudioStream(isSend);
     }
 
     private void closeVideoEffect()

+ 1 - 1
Assets/Remote/ShowRoom/RoomMain.prefab

@@ -12,7 +12,7 @@ GameObject:
   - component: {fileID: 6608887979044451290}
   - component: {fileID: 83380101878762281}
   m_Layer: 5
-  m_Name: RawImage
+  m_Name: AgoraRawImage
   m_TagString: Untagged
   m_Icon: {fileID: 0}
   m_NavMeshLayer: 0

+ 538 - 0
Assets/Scripts/RTCManager.cs

@@ -0,0 +1,538 @@
+using Agora.Rtc;
+using Agora.Util;
+using SC.XR.Unity;
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+using UnityEngine.Rendering;
+using UnityEngine.UI;
+
+public class RTCManager : SingletonMono<RTCManager>
+{
+   
+    public Camera ca;
+    public RawImage img;
+    Texture2D screenShot;
+    byte[] bts;
+    /// <summary>
+    /// 自身UID
+    /// </summary>
+    private uint uid;
+    /// <summary>
+    /// 当前频道号
+    /// </summary>
+    private string channelName;
+  
+    [SerializeField]
+    private string _appID = "";
+
+    [SerializeField]
+    private string _token = "";
+
+    internal IRtcEngine RtcEngine = null;
+
+    private Dictionary<string, uint> dicPeeridAndUid;
+    public List<CustomPeer> listCustomPeer;
+    private string mainViewPeerId;
+
+    private bool isSwitchCamera;
+
+    public delegate void OnInitDelegate();
+    public delegate void OnJoinChannelDelegate();
+    public delegate void OnLeaveChannelDelegate();
+    public delegate void OnShowViewRawImageDelegate(string uid, RawImage rawImage);
+    public delegate void OnShowViewMeshRendererDelegate(string uid, MeshRenderer mesh);
+    public delegate void OnShowOneViewRawImageDelegate(RawImage rawImage);
+    public delegate void OnMuteLocalAudioStreamDelegate(bool isAudio);
+    public delegate void OnMuteLocalVideoStreamDelegate(bool isVideo);
+    public delegate void OnMuteRemoteAudioStreamDelegate(string uid, bool isAudio);
+    public delegate void OnMuteRemoteVideoStreamDelegate(string uid, bool isVideo);
+    public delegate void OnRemoteAudioStateChangedDelegate(string uid,REMOTE_AUDIO_STATE_RTC state, REMOTE_AUIDO_STATE_REASON_RTC reason);
+    public delegate void OnRemoteVideoStateChangedDelegate(string uid,REMOTE_VIDEO_STATE_RTC state, REMOTE_VIDEO_STATE_REASON_RTC reason);
+    public delegate void OnUserJoinedDelegate(string uid);
+    public delegate void OnUserOfflineDelegate(string uid);
+    public delegate void OnSetUidDelegate(string uid);
+    public delegate void OnSetChannelNameDelegate(string channelName);
+    public delegate void OnAddPeeridUidDelegate(string peerid, string uid);
+    public delegate void OnRemAtPeeridUidDelegate(string peerid);
+
+    public OnInitDelegate OnInit;
+    public OnJoinChannelDelegate OnJoinChannel;
+    public OnLeaveChannelDelegate OnLeaveChannel;
+    public OnShowViewRawImageDelegate OnShowViewRawImage;
+    public OnShowViewMeshRendererDelegate OnShowViewMeshRenderer;
+    public OnShowOneViewRawImageDelegate OnShowOneViewRawImage;
+    public OnMuteLocalAudioStreamDelegate OnMuteLocalAudioStream;
+    public OnMuteLocalVideoStreamDelegate OnMuteLocalVideoStream;
+    public OnMuteRemoteAudioStreamDelegate OnMuteRemoteAudioStream;
+    public OnMuteRemoteVideoStreamDelegate OnMuteRemoteVideoStream;
+    public OnRemoteAudioStateChangedDelegate OnRemoteAudioStateChanged;
+    public OnRemoteVideoStateChangedDelegate OnRemoteVideoStateChanged;
+    public OnUserJoinedDelegate OnUserJoined;
+    public OnUserOfflineDelegate OnUserOffline;
+    public OnSetUidDelegate OnSetUid;
+    public OnSetChannelNameDelegate OnSetChannelName;
+    public OnAddPeeridUidDelegate OnAddPeeridUid;
+    public OnRemAtPeeridUidDelegate OnRemAtPeeridUid;
+
+    private void Update()
+    {
+        PermissionHelper.RequestMicrophontPermission();
+        PermissionHelper.RequestCameraPermission();
+    }
+
+    /// <summary>
+    /// 初始化
+    /// </summary>
+    public void Init()
+    {
+        // OnInit();
+        isSwitchCamera = false;
+        dicPeeridAndUid = new Dictionary<string, uint>();
+        listCustomPeer = new List<CustomPeer>();
+        InitEngine();
+    }
+
+    private void InitEngine()
+    {
+
+        RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine();
+
+        RTCManagerHandler handler = new RTCManagerHandler(this);
+        RtcEngineContext context = new RtcEngineContext(_appID, 0,
+                                    CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_COMMUNICATION,
+                                    AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT);
+        //    RtcEngine.SetCameraDeviceOrientation(VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA, VIDEO_ORIENTATION.VIDEO_ORIENTATION_90);
+        RtcEngine.Initialize(context);
+        RtcEngine.InitEventHandler(handler);
+    }
+
+    public void SetUid(string uid)
+    {
+        // OnSetUid(uid);
+        // UID = uid;
+        this.uid = StringToUint(uid);
+    }
+
+    public void SetChannelName(string channelName)
+    {
+       // OnSetChannelName(channelName);
+        this.channelName = channelName;
+    }
+
+    /// <summary>
+    ///  进入房间
+    /// </summary>
+    public void JoinChannel()
+    {
+       // OnJoinChannel();
+
+        RtcEngine.EnableAudio();
+        RtcEngine.EnableVideo();
+
+        // RtcEngine.DisableAudio();
+        //  RtcEngine.DisableVideo();
+        VideoEncoderConfiguration config = new VideoEncoderConfiguration();
+        config.dimensions = new VideoDimensions(1280, 720);
+        config.frameRate = 15;
+        config.bitrate = 0;
+        //    config.orientationMode = ORIENTATION_MODE.ORIENTATION_MODE_ADAPTIVE;
+        RtcEngine.SetVideoEncoderConfiguration(config);
+        RtcEngine.SetChannelProfile(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_COMMUNICATION);
+        RtcEngine.SetClientRole(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
+        // _channelName = roomid;
+        RtcEngine.SetExternalVideoSource(true, true, EXTERNAL_VIDEO_SOURCE_TYPE.VIDEO_FRAME, new SenderOptions());
+
+        if (DeviceType.type == "DreamGlass")
+            RtcEngine.SetAudioProfile(0, AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_GAME_STREAMING);
+        //  RtcEngine.SetLocalVideoMirrorMode(VIDEO_MIRROR_MODE_TYPE.VIDEO_MIRROR_MODE_ENABLED);
+        RtcEngine.JoinChannel(_token, channelName, "", uid);
+        Debug.Log("uid  " + uid);
+        //RtcEngine.MuteLocalVideoStream(false);
+        //RtcEngine.MuteLocalAudioStream(false);
+        //RtcEngine.MuteAllRemoteAudioStreams(true);
+        //RtcEngine.MuteAllRemoteVideoStreams(true);
+        //isRoom = true;
+        //MuteLocalAudioStream(CustomInfo.isSendAudio);
+        //MuteLocalVideoStream(CustomInfo.isSendVideo);
+       // isSendVideo = CustomInfo.isSendVideo;
+        StartCoroutine(RenderTexturesScreenCapture());
+    }
+
+    
+    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);
+            }
+        }
+    }
+    
+    IEnumerator GetRenederFPS()
+    {
+        while (true)
+        {
+            var req = AsyncGPUReadback.Request(RemoteRtc.Instance.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");
+            }
+        }
+    }
+
+    /// <summary>
+    ///  退出房间
+    /// </summary>
+    public void LeaveChannel()
+    {
+        //OnLeaveChannel();
+        int msg = RtcEngine.LeaveChannel();
+        switch (msg)
+        {
+            case 0:
+                Debug.Log( "成功退出频道: " + channelName);
+                break;
+            default:
+                Debug.Log("退出频道失败: " + msg);
+                break;
+        }
+
+      
+    }
+
+    
+    /// <summary>
+    ///  显示用户画面
+    /// </summary>
+    /// <param name="uid"> 用户的UID</param>
+    /// <param name="rawImage"> 需要显示的RawImage</param>
+    public void ShowViewRawImage( string peerId, RawImage rawImage)
+    {
+        //OnShowViewRawImage(uid, rawImage);
+
+        MakeVideoView(dicPeeridAndUid[peerId], rawImage, this.channelName);
+    }
+    /// <summary>
+    ///  显示用户画面
+    /// </summary>
+    /// <param name="uid"> 用户的UID</param>
+    /// <param name="mesh"> 需要显示的Mesh</param>
+    public void ShowViewMeshRenderer(string uid, MeshRenderer mesh)
+    {
+        OnShowViewMeshRenderer(uid, mesh);
+    }
+   
+    /// <summary>
+    ///  开关自身音频
+    /// </summary>
+    /// <param name="isAudio"></param>
+    public void MuteLocalAudioStream(bool isAudio)
+    {
+        //OnMuteLocalAudioStream(isAudio);
+
+        int msg = RtcEngine.MuteLocalAudioStream(!isAudio);
+
+        //  int msg = RtcEngine.EnableLocalAudio(isAudio);
+        switch (msg)
+        {
+            case 0:
+                Debug.Log(isAudio ? "打开本地音频成功" : "关闭本地音频成功 ");
+                break;
+            default:
+                Debug.LogError("开关本地音频失败: " + msg);
+                break;
+        }
+    }
+    /// <summary>
+    ///  开关自身视频
+    /// </summary>
+    /// <param name="isVideo"></param>
+    public void MuteLocalVideoStream(bool isVideo)
+    {
+       // OnMuteLocalVideoStream(isVideo);
+        int msg = RtcEngine.MuteLocalVideoStream(!isVideo);
+        switch (msg)
+        {
+            case 0:
+                Debug.Log(isVideo ? "打开本地视频成功 " : "关闭本地视频成功 ");
+                break;
+            default:
+                Debug.LogError("开关本地视频失败: " + msg);
+                break;
+        }
+    }
+    /// <summary>
+    ///  订阅/取订 用户音频
+    /// </summary>
+    /// <param name="uid"></param>
+    /// <param name="isAudio"></param>
+    public void MuteRemoteAudioStream(string peerid, bool isAudio)
+    {
+     //   OnMuteRemoteAudioStream(uid, isAudio);
+     //   
+        int msg = RtcEngine.MuteRemoteAudioStream(StringToUint(peerid), !isAudio);
+
+        switch (msg)
+        {
+            case 0:
+                Debug.Log(isAudio ? "订阅远端音频成功" : "取订远端音频成功 ");
+                break;
+            default:
+                Debug.LogError("远端音频失败: " + msg);
+                break;
+        }
+    }
+
+    /// <summary>
+    ///  订阅/取订 用户视频
+    /// </summary>
+    /// <param name="uid"></param>
+    /// <param name="isVideo"></param>
+    public void MuteRemoteVideoStream(string peerid, bool isVideo)
+    {
+     //   OnMuteRemoteVideoStream(uid, isVideo);
+
+        int msg = RtcEngine.MuteRemoteVideoStream(StringToUint(peerid), !isVideo);
+        switch (msg)
+        {
+            case 0:
+                Debug.Log(isVideo ? "订阅远端视频成功" : "取订远端视频成功 ");
+                break;
+            default:
+                Debug.LogError("远端视频失败: " + msg);
+                break;
+        }
+    }
+    /// <summary>
+    /// 用户音频状态发生变化的回调
+    /// </summary>
+    /// <param name="uid"></param>
+    /// <param name="state"> 音频状态 </param>
+    public void RemoteAudioStateChanged(string uid ,REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason)
+    {
+        OnRemoteAudioStateChanged(uid, (REMOTE_AUDIO_STATE_RTC)state, (REMOTE_AUIDO_STATE_REASON_RTC)reason);
+    }
+    /// <summary>
+    /// 用户视频状态发生变化的回调
+    /// </summary>
+    /// <param name="uid"></param>
+    /// <param name="state"> 视频状态 </param>
+    public void RemoteVideoStateChanged(string uid ,REMOTE_AUDIO_STATE state ,REMOTE_AUDIO_STATE_REASON reason)
+    {
+        OnRemoteVideoStateChanged(uid, (REMOTE_VIDEO_STATE_RTC)state, (REMOTE_VIDEO_STATE_REASON_RTC)reason);
+    }
+
+    /// <summary>
+    ///  有用户进入频道的回调
+    /// </summary>
+    /// <param name="uid"></param>
+    public void UserJoined(string uid)
+    {
+        OnUserJoined(uid);
+    }
+
+    /// <summary>
+    ///  有用户退出频道的回调
+    /// </summary>
+    /// <param name="uid"></param>
+    public void UserOffline(string uid)
+    {
+        OnUserOffline(uid);
+    }
+
+    private uint StringToUint(string value)
+    {
+        //byte[] bytes = Encoding.ASCII.GetBytes(value);
+
+        return (uint)int.Parse(value);
+        // return BitConverter.ToUInt32(bytes);
+    }
+
+
+    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 = MakeImageSurface(rawImage);
+        // var videoSurface = MakePlaneSurface(uid.ToString());
+        if (ReferenceEquals(videoSurface, null)) return;
+        // configure videoSurface
+        if (uid == 0)
+        {
+            //  videoSurface.SetForUser(uid, channelId);
+        }
+        else
+        {
+            videoSurface.SetForUser(uid, channelId, VIDEO_SOURCE_TYPE.VIDEO_SOURCE_REMOTE);
+        }
+
+        //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);
+        //};
+
+        videoSurface.SetEnable(true);
+        //  AgoraVideoAudioManager.Instance.EnableLocalVideo(false);
+
+    }
+
+
+    private static VideoSurface MakeImageSurface(RawImage rawImage)
+    {
+        // make the object draggable
+        if (rawImage.gameObject.GetComponent<UIElementDrag>() != null)
+            Destroy(rawImage.gameObject.GetComponent<UIElementDrag>());
+        rawImage.gameObject.AddComponent<UIElementDrag>();
+
+        // configure videoSurface
+
+        if (rawImage.gameObject.GetComponent<VideoSurface>() != null)
+            Destroy(rawImage.gameObject.GetComponent<VideoSurface>());
+        var videoSurface = rawImage.gameObject.AddComponent<VideoSurface>();
+
+        return videoSurface;
+    }
+}
+public class RTCManagerHandler : IRtcEngineEventHandler
+{
+    private readonly RTCManager _videoSample;
+
+    internal RTCManagerHandler(RTCManager videoSample)
+    {
+        _videoSample = videoSample;
+    }
+
+    public override void OnError(int err, string msg)
+    {
+        
+    }
+
+    public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
+    {
+        int build = 0;
+        Debug.Log("Agora: OnJoinChannelSuccess ");
+      ////  _videoSample.Log.UpdateLog(string.Format("sdk version: ${0}",
+      //   //   _videoSample.RtcEngine.GetVersion(ref build)));
+      //  //_videoSample.Log.UpdateLog(string.Format("sdk build: ${0}",
+      // //   build));
+      //  //_videoSample.Log.UpdateLog(
+      //      string.Format("OnJoinChannelSuccess channelName: {0}, uid: {1}, elapsed: {2}",
+      //                      connection.channelId, connection.localUid, elapsed));
+
+      //  //  _videoSample.ClickSelf();
+      //  // AgoraVideoAudioManager.MakeVideoView(0);
+
+    }
+
+    public override void OnLeaveChannel(RtcConnection connection, RtcStats stats)
+    {
+       // _videoSample.Log.UpdateLog("OnLeaveChannel");
+        AgoraVideoAudioManager.DestroyVideoView(0);
+    }
+
+    public override void OnClientRoleChanged(RtcConnection connection, CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole)
+    {
+        //_videoSample.Log.UpdateLog("OnClientRoleChanged");
+    }
+
+    public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed)
+    {
+        Debug.Log(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed));
+       // _videoSample.Log.UpdateLog(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed));
+        AgoraVideoAudioManager.OnUserJoined(uid);
+        //   AgoraVideoAudioManager.MakeVideoView(uid, _videoSample.GetChannelName());
+    }
+
+    public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason)
+    {
+       // _videoSample.Log.UpdateLog(string.Format("OnUserOffLine uid: ${0}, reason: ${1}", uid,
+       //     (int)reason));
+        //  AgoraVideoAudioManager.DestroyVideoView(uid);
+    }
+
+    public override void OnUserInfoUpdated(uint uid, Agora.Rtc.UserInfo info)
+    {
+     //   _videoSample.Log.UpdateLog(string.Format(" 用户 :${0}  加入房间", uid));
+
+        AgoraVideoAudioManager.OnUserInfoUpdated(uid, info);
+    }
+
+
+    public override void OnUplinkNetworkInfoUpdated(UplinkNetworkInfo info)
+    {
+       // _videoSample.Log.UpdateLog("OnUplinkNetworkInfoUpdated");
+    }
+
+    public override void OnDownlinkNetworkInfoUpdated(DownlinkNetworkInfo info)
+    {
+       // _videoSample.Log.UpdateLog("OnDownlinkNetworkInfoUpdated");
+    }
+
+
+
+    public override void OnRemoteVideoStateChanged(RtcConnection connection, uint remoteUid, REMOTE_VIDEO_STATE state, REMOTE_VIDEO_STATE_REASON reason, int elapsed)
+    {
+        AgoraVideoAudioManager.OnRemoteVideoStateChanged(remoteUid, state, reason);
+    }
+
+    public override void OnRemoteAudioStateChanged(RtcConnection connection, uint remoteUid, REMOTE_AUDIO_STATE state, REMOTE_AUDIO_STATE_REASON reason, int elapsed)
+    {
+        AgoraVideoAudioManager.OnRemoteAudioStateChanged(remoteUid, state, reason);
+    }
+}

+ 11 - 0
Assets/Scripts/RTCManager.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 8d18263e64ad01049a2377a0e7ad2281
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 210 - 0
Assets/Scripts/RTCStateReason.cs

@@ -0,0 +1,210 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public class RTCStateReason 
+{
+   
+}
+public enum REMOTE_VIDEO_STATE_RTC
+{
+    ///
+    /// <summary>
+    /// 0: The remote video is in the initial state. The SDK reports this state in the case of REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED, REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED, or REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE.
+    /// 远端视频默认初始状态。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_STOPPED = 0,
+
+    ///
+    /// <summary>
+    /// 1: The first remote video packet is received.
+    /// 本地用户已接收远端视频首包。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_STARTING = 1,
+
+    ///
+    /// <summary>
+    /// 2: The remote video stream is decoded and plays normally. The SDK reports this state in the case of REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY, REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED, REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED or REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK_RECOVERY.
+    /// 远端视频流正在解码,正常播放。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_DECODING = 2,
+
+    ///
+    /// <summary>
+    /// 3: The remote video is frozen. The SDK reports this state in the case of REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION or REMOTE_VIDEO_STATE_REASON_AUDIO_FALLBACK.
+    ///  远端视频流卡顿。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_FROZEN = 3,
+
+    ///
+    /// <summary>
+    /// 4: The remote video fails to start. The SDK reports this state in the case of REMOTE_VIDEO_STATE_REASON_INTERNAL.
+    /// 远端视频流播放失败。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_FAILED = 4,
+}
+
+public enum REMOTE_AUDIO_STATE_RTC
+{
+    /// <summary>
+    /// 0: The local audio is in the initial state. The SDK reports this state in the case of REMOTE_AUDIO_REASON_LOCAL_MUTED, REMOTE_AUDIO_REASON_REMOTE_MUTED or REMOTE_AUDIO_REASON_REMOTE_OFFLINE.
+    /// 远端音频默认初始状态。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_STATE_STOPPED = 0,
+
+    ///
+    /// <summary>
+    /// 1: The first remote audio packet is received.
+    /// 本地用户已接收远端音频首包。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_STATE_STARTING = 1,
+
+    ///
+    /// <summary>
+    /// 2: The remote audio stream is decoded and plays normally. The SDK reports this state in the case of REMOTE_AUDIO_REASON_NETWORK_RECOVERY, REMOTE_AUDIO_REASON_LOCAL_UNMUTED or REMOTE_AUDIO_REASON_REMOTE_UNMUTED.
+    /// 远端音频流正在解码,正常播放。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_STATE_DECODING = 2,
+
+    ///
+    /// <summary>
+    /// 3: The remote audio is frozen. The SDK reports this state in the case of REMOTE_AUDIO_REASON_NETWORK_CONGESTION.
+    /// 远端音频流卡顿。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_STATE_FROZEN = 3,
+
+    ///
+    /// <summary>
+    /// 4: The remote audio fails to start. The SDK reports this state in the case of REMOTE_AUDIO_REASON_INTERNAL.
+    /// 远端音频流播放失败。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_STATE_FAILED = 4,
+}
+
+public enum REMOTE_AUIDO_STATE_REASON_RTC
+{
+    ///
+    /// <summary>
+    /// 1: Network congestion. 
+    /// 网络阻塞
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_NETWORK_CONGESTION = 1,
+
+    ///
+    /// <summary>
+    /// 2: Network recovery.  
+    /// 网络恢复正常
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_NETWORK_RECOVERY = 2,
+
+    ///
+    /// <summary>
+    /// 3: The local user stops receiving the remote audio stream or disables the audio module.
+    /// 本地用户停止接收远端音频流或本地用户禁用音频模块
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_LOCAL_MUTED = 3,
+
+    ///
+    /// <summary>
+    /// 4: The local user resumes receiving the remote audio stream or enables the audio module.
+    /// 本地用户恢复接收远端音频流或本地用户启动音频模块。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_LOCAL_UNMUTED = 4,
+
+    ///
+    /// <summary>
+    /// 5: The remote user stops sending the audio stream or disables the audio module.
+    /// 远端用户停止发送音频流或远端用户禁用音频模块。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_REMOTE_MUTED = 5,
+
+    ///
+    /// <summary>
+    /// 6: The remote user resumes sending the audio stream or enables the audio module.
+    ///  远端用户恢复发送音频流或远端用户启用音频模块。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_REMOTE_UNMUTED = 6,
+
+    ///
+    /// <summary>
+    /// 7: The remote user leaves the channel.
+    /// 远端用户离开频道。
+    /// </summary>
+    ///
+    REMOTE_AUDIO_REASON_REMOTE_OFFLINE = 7
+}
+
+public enum REMOTE_VIDEO_STATE_REASON_RTC
+{
+    ///
+    /// <summary>
+    /// 1: Network congestion.
+    ///  网络阻塞。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION = 1,
+
+    ///
+    /// <summary>
+    /// 2: Network recovery.
+    ///  网络恢复正常。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY = 2,
+
+    ///
+    /// <summary>
+    /// 3: The local user stops receiving the remote video stream or disables the video module.
+    /// 本地用户停止接收远端视频流或本地用户禁用视频模块。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED = 3,
+
+    ///
+    /// <summary>
+    /// 4: The local user resumes receiving the remote video stream or enables the video module.
+    /// 本地用户恢复接收远端视频流或本地用户启动视频模块。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED = 4,
+
+    ///
+    /// <summary>
+    /// 5: The remote user stops sending the video stream or disables the video module.
+    ///  远端用户停止发送视频流或远端用户禁用视频模块。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED = 5,
+
+    ///
+    /// <summary>
+    /// 6: The remote user resumes sending the video stream or enables the video module.
+    /// 远端用户恢复发送视频流或远端用户启用视频模块。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED = 6,
+
+    ///
+    /// <summary>
+    /// 7: The remote user leaves the channel.
+    /// 远端用户离开频道。
+    /// </summary>
+    ///
+    REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE = 7,
+}

+ 11 - 0
Assets/Scripts/RTCStateReason.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 7a9a599b3dfaf5b42a298c5396f478e3
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 261 - 0
Assets/Scripts/VideoAudioData.cs

@@ -0,0 +1,261 @@
+using SC.XR.Unity;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+using UnityEngine.UI;
+
+public class VideoAudioData : SingletonMono<VideoAudioData>
+{
+    public Dictionary<string, uint> dicPeeridAndUid;
+    public List<CustomPeer> listCustomPeer;
+    public string mainViewPeerId;
+
+    private void Start()
+    {
+        dicPeeridAndUid = new Dictionary<string, uint>();
+        listCustomPeer = new List<CustomPeer>();
+        mainViewPeerId = "";
+
+        RTCManager.Instance.OnRemoteAudioStateChanged += RemoteAudioStateChanged;
+        RTCManager.Instance.OnRemoteVideoStateChanged += RemoteVideoStateChanged;
+    }
+
+    public void  InitData()
+    {
+        dicPeeridAndUid.Clear();
+        listCustomPeer.Clear();
+        dicPeeridAndUid = new Dictionary<string, uint>();
+        listCustomPeer = new List<CustomPeer>();
+        mainViewPeerId = "";
+    }
+
+    public void AddPeeridUid(string peerid, uint uid)
+    {
+        if (dicPeeridAndUid.ContainsKey(peerid))
+            return;
+        dicPeeridAndUid.Add(peerid, uid);
+    }
+
+    public void RemAtPeeridUid(string peerid)
+    {
+        if (!dicPeeridAndUid.ContainsKey(peerid))
+            return;
+        dicPeeridAndUid.Remove(peerid);
+
+        for (int i = 0; i < listCustomPeer.Count; i++)
+        {
+            if(listCustomPeer[i].peerId == peerid)
+            {
+                listCustomPeer.RemoveAt(i);
+                break;
+            }
+        }
+    }
+
+    public void JoinChannel()
+    {
+        RTCManager.Instance.JoinChannel();
+        RTCManager.Instance.MuteLocalAudioStream(CustomInfo.isSendAudio);
+        RTCManager.Instance.MuteLocalVideoStream(CustomInfo.isSendVideo);
+    }
+
+    public void LeaveChannel()
+    {
+        RTCManager.Instance.LeaveChannel();
+        InitData();
+        RoomMain.Instance.agoraRawImage.gameObject.SetActive(false);
+        RoomMain.Instance.agoraRawImage.texture = null;
+    }
+
+    public void AddListShowView(string peerId, RawImage rawImage)
+    {
+        if (!dicPeeridAndUid.ContainsKey(peerId))
+            return;
+        Debug.Log(" AddListShowView " + peerId);
+
+        if (rawImage.name == "AgoraRawImage")
+            mainViewPeerId = peerId;
+
+        rawImage.gameObject.SetActive(true);
+        rawImage.rectTransform.localEulerAngles = new Vector3(0, 180, 180);
+
+        RTCManager.Instance.ShowViewRawImage(dicPeeridAndUid[peerId].ToString(), rawImage);
+    }
+
+    public void ShowOneView(RawImage rawImage)
+    {
+        if (dicPeeridAndUid.Count < 2)
+            return;
+        //  rawImage.gameObject.SetActive(true);
+        rawImage.rectTransform.localEulerAngles = new Vector3(0, 180, 180);
+        RTCManager.Instance.ShowViewRawImage(dicPeeridAndUid.Values.Skip(1).First().ToString(), rawImage);
+    }
+
+    public void UserJoined(uint uid)
+    {
+        if (uid == dicPeeridAndUid.Values.Skip(1).First())
+        {
+
+            //  RoomMain.Instance.agoraRawImage.gameObject.SetActive(true);
+            RoomMain.Instance.agoraRawImage.rectTransform.localEulerAngles = new Vector3(0, 180, 180);
+            RTCManager.Instance.ShowViewRawImage(dicPeeridAndUid.Values.Skip(1).First().ToString(), RoomMain.Instance.agoraRawImage);
+
+            foreach (var item in dicPeeridAndUid)
+            {
+                if (item.Value == uid)
+                    mainViewPeerId = item.Key;
+            }
+        }
+
+    }
+
+    public void MuteLocalAudioStream(bool isAudio)
+    {
+        RTCManager.Instance.MuteLocalAudioStream(isAudio);
+    }
+
+    public void MuteLocalVideoStream(bool isVideo)
+    {
+        RTCManager.Instance.MuteLocalVideoStream(isVideo);
+    }
+
+    public void MuteRemoteAudioStream(string peerid,bool isAudio)
+    {
+        if (!dicPeeridAndUid.ContainsKey(peerid))
+            return;
+        RTCManager.Instance.MuteRemoteAudioStream(dicPeeridAndUid[peerid].ToString(), isAudio);
+
+    }
+
+    public void MuteRemoteVideoStream(string peerid,bool isVideo)
+    {
+        if (!dicPeeridAndUid.ContainsKey(peerid))
+            return;
+        RTCManager.Instance.MuteRemoteVideoStream(dicPeeridAndUid[peerid].ToString(), isVideo);
+    }
+
+    public void RemoteAudioStateChanged(string uid, REMOTE_AUDIO_STATE_RTC state, REMOTE_AUIDO_STATE_REASON_RTC reason)
+    {
+        if (!dicPeeridAndUid.ContainsValue(StringToUint(uid)))
+            return;
+
+        for (int i = 0; i < listCustomPeer.Count; i++)
+        {
+            if (dicPeeridAndUid[listCustomPeer[i].peerId] == StringToUint(uid))
+            {
+                 switch (reason)
+                {
+                 
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_NETWORK_CONGESTION:
+                        //  listCustomPeer[i].isAudio = false;
+                        break;
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_NETWORK_RECOVERY:
+                        //  listCustomPeer[i].isAudio = true;
+                        break;
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_LOCAL_MUTED:
+                        listCustomPeer[i].isCloseAudio = true;
+                        break;
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_LOCAL_UNMUTED:
+                        listCustomPeer[i].isCloseAudio = false;
+                        break;
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_REMOTE_MUTED:
+                        listCustomPeer[i].isAudio = false;
+                        break;
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_REMOTE_UNMUTED:
+                        listCustomPeer[i].isAudio = true;
+                        break;
+                    case REMOTE_AUIDO_STATE_REASON_RTC.REMOTE_AUDIO_REASON_REMOTE_OFFLINE:
+                        listCustomPeer[i].isAudio = false;
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            }
+        }
+    }
+
+    public void RemoteVideoStateChanged(string uid, REMOTE_VIDEO_STATE_RTC state , REMOTE_VIDEO_STATE_REASON_RTC reason)
+    {
+        if (!dicPeeridAndUid.ContainsValue(StringToUint(uid)))
+            return;
+        for (int i = 0; i < listCustomPeer.Count; i++)
+        {
+            if (dicPeeridAndUid[listCustomPeer[i].peerId] == StringToUint(uid))
+            {
+                switch (state)
+                {
+                    case REMOTE_VIDEO_STATE_RTC.REMOTE_VIDEO_STATE_STOPPED:
+                        break;
+                    case REMOTE_VIDEO_STATE_RTC.REMOTE_VIDEO_STATE_STARTING:
+                        listCustomPeer[i].isVideo = true;
+                        CloseAgoraMainImage(listCustomPeer[i].peerId, true);
+                        break;
+                    case REMOTE_VIDEO_STATE_RTC.REMOTE_VIDEO_STATE_DECODING:
+                        listCustomPeer[i].isCloseVideo = false;
+                        CloseAgoraMainImage(listCustomPeer[i].peerId, true);
+                        break;
+                    case REMOTE_VIDEO_STATE_RTC.REMOTE_VIDEO_STATE_FROZEN:
+                        break;
+                    case REMOTE_VIDEO_STATE_RTC.REMOTE_VIDEO_STATE_FAILED:
+                        break;
+                    default:
+                        break;
+                }
+
+                switch (reason)
+                {                  
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_NETWORK_CONGESTION://网络阻塞。
+
+                        //  listCustomPeer[i].isVideo = false;
+                        break;
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_NETWORK_RECOVERY:// 网络恢复正常。
+
+                        //  listCustomPeer[i].isVideo = true;
+                        break;
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_LOCAL_MUTED://本地用户停止接收远端视频流或本地用户禁用视频模块
+
+                        listCustomPeer[i].isCloseVideo = true;
+                        CloseAgoraMainImage(listCustomPeer[i].peerId, false);
+                        break;
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_LOCAL_UNMUTED://本地用户恢复接收远端视频流或本地用户启动视频模块
+
+                        listCustomPeer[i].isCloseVideo = false;
+                        CloseAgoraMainImage(listCustomPeer[i].peerId, true);
+                        break;
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_REMOTE_MUTED://远端用户停止发送视频流或远端用户禁用视频模块。
+
+                        listCustomPeer[i].isVideo = false;
+                        CloseAgoraMainImage(listCustomPeer[i].peerId, false);
+                        break;
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_REMOTE_UNMUTED://远端用户恢复发送视频流或远端用户启用视频模块。
+
+                        listCustomPeer[i].isVideo = true;
+                        CloseAgoraMainImage(listCustomPeer[i].peerId, true);
+                        break;
+                    case REMOTE_VIDEO_STATE_REASON_RTC.REMOTE_VIDEO_STATE_REASON_REMOTE_OFFLINE: //远端用户离开频道。
+
+                        listCustomPeer[i].isVideo = false;
+                        break;
+                }
+                break;
+            }
+        }
+    }
+
+    private void CloseAgoraMainImage(string peerid, bool isOpen)
+    {
+        if (peerid == mainViewPeerId)
+            RoomMain.Instance.agoraRawImage.gameObject.SetActive(isOpen);
+    }
+
+
+    private uint StringToUint(string value)
+    {
+        //byte[] bytes = Encoding.ASCII.GetBytes(value);
+
+        return (uint)int.Parse(value);
+        // return BitConverter.ToUInt32(bytes);
+    }
+}

+ 11 - 0
Assets/Scripts/VideoAudioData.cs.meta

@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: db4fa27bcac54ef45b57470f3de02003
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 1 - 1
Packages/manifest.json

@@ -11,7 +11,7 @@
     "com.unity.ugui": "1.0.0",
     "com.unity.visualscripting": "1.7.8",
     "com.unity.xr.openxr": "1.5.3",
-    "com.ximmerse.xr": "file:G:/GUnityProject/XRSDK/package",
+    "jh.xr.engine": "file:G:/GUnityProject/XRSDK/package",
     "com.unity.modules.ai": "1.0.0",
     "com.unity.modules.androidjni": "1.0.0",
     "com.unity.modules.animation": "1.0.0",

+ 4 - 41
Packages/packages-lock.json

@@ -134,40 +134,6 @@
       },
       "url": "https://packages.unity.cn"
     },
-    "com.unity.xr.arsubsystems": {
-      "version": "4.2.7",
-      "depth": 1,
-      "source": "registry",
-      "dependencies": {
-        "com.unity.subsystemregistration": "1.1.0",
-        "com.unity.xr.management": "4.0.1"
-      },
-      "url": "https://packages.unity.cn"
-    },
-    "com.unity.xr.core-utils": {
-      "version": "2.0.0",
-      "depth": 2,
-      "source": "registry",
-      "dependencies": {
-        "com.unity.modules.xr": "1.0.0"
-      },
-      "url": "https://packages.unity.cn"
-    },
-    "com.unity.xr.interaction.toolkit": {
-      "version": "2.0.4",
-      "depth": 1,
-      "source": "registry",
-      "dependencies": {
-        "com.unity.inputsystem": "1.3.0",
-        "com.unity.ugui": "1.0.0",
-        "com.unity.xr.core-utils": "2.0.0",
-        "com.unity.xr.legacyinputhelpers": "2.1.8",
-        "com.unity.modules.audio": "1.0.0",
-        "com.unity.modules.imgui": "1.0.0",
-        "com.unity.modules.physics": "1.0.0"
-      },
-      "url": "https://packages.unity.cn"
-    },
     "com.unity.xr.legacyinputhelpers": {
       "version": "2.1.10",
       "depth": 1,
@@ -202,17 +168,14 @@
       },
       "url": "https://packages.unity.cn"
     },
-    "com.ximmerse.xr": {
+    "jh.xr.engine": {
       "version": "file:G:/GUnityProject/XRSDK/package",
       "depth": 0,
       "source": "local",
       "dependencies": {
-        "com.unity.xr.management": "3.2.9",
-        "com.unity.xr.legacyinputhelpers": "2.1.4",
-        "com.unity.xr.arsubsystems": "4.1.9",
-        "com.unity.xr.interaction.toolkit": "2.0.0",
-        "com.unity.inputsystem": "1.3.0",
-        "com.unity.xr.openxr": "1.5.3"
+        "com.unity.xr.management": "4.0.1",
+        "com.unity.xr.legacyinputhelpers": "2.1.2",
+        "com.unity.inputsystem": "1.4.2"
       }
     },
     "com.unity.modules.ai": {