using Agora.Rtc; using Agora.Util; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Serialization; using UnityEngine.UI; using Logger = Agora.Util.Logger; public class AgoraTestVideo : MonoBehaviour { [FormerlySerializedAs("appIdInput")] [SerializeField] private AppIdInput _appIdInput; [Header("_____________Basic Configuration_____________")] [FormerlySerializedAs("APP_ID")] [SerializeField] private string _appID = ""; [FormerlySerializedAs("TOKEN")] [SerializeField] private string _token = ""; [FormerlySerializedAs("CHANNEL_NAME")] [SerializeField] private string _channelName = ""; internal static string _channelToken = ""; internal static string _tokenBase = "http://localhost:8080"; internal CONNECTION_STATE_TYPE _state = CONNECTION_STATE_TYPE.CONNECTION_STATE_DISCONNECTED; public uint uid; internal Logger Log; public Text Logtext; internal IRtcEngine rtcEngine; private RtcEngineEventHandler rtcEngineEventHandler; private RtcConnection rtcConnection; public InputField inputChannelName; public Button joinChannel; public Button leaveChannel; // Start is called before the first frame update void Start() { LoadAssetData(); if (CheckAppId()) { InitEngine(); } joinChannel.onClick.AddListener(JoinChannel); leaveChannel.onClick.AddListener(LeavelChannel); } // Update is called once per frame void Update() { PermissionHelper.RequestMicrophontPermission(); PermissionHelper.RequestCameraPermission(); } [ContextMenu("ShowAgoraBasicProfileData")] private void LoadAssetData() { if (_appIdInput == null) return; _appID = _appIdInput.appID; _token = _appIdInput.token; _channelToken = _appIdInput.token; _channelName = _appIdInput.channelName; } private bool CheckAppId() { Log = new Logger(Logtext); return Log.DebugAssert(_appID.Length > 10, "Please fill in your appId in API-Example/profile/appIdInput.asset"); } private void InitEngine() { rtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine(); RtcEngineContext context = new RtcEngineContext(_appID, 0, CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING, AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT); rtcEngine.Initialize(context); UserEventHandler handler = new UserEventHandler(this); rtcEngine.InitEventHandler(handler); } private void JoinChannel() { _channelName = inputChannelName.text; rtcEngine.SetClientRole(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER); rtcEngine.EnableAudio(); rtcEngine.EnableVideo(); //if (_channelToken.Length == 0) //{ // Logtext.text = " Token NULL"; // return; //} rtcEngine.JoinChannel(_channelToken, _channelName, ""); } private void LeavelChannel() { int msg = rtcEngine.LeaveChannel(); switch (msg) { case 0: Logtext.text = " 成功离开频道 "+ _channelName; break; default: Logtext.text = " 离开频道失败 " + msg; break; } } internal void RenewOrJoinToken(string newToken) { AgoraTestVideo._channelToken = newToken; if (_state == CONNECTION_STATE_TYPE.CONNECTION_STATE_DISCONNECTED || _state == CONNECTION_STATE_TYPE.CONNECTION_STATE_DISCONNECTED || _state == CONNECTION_STATE_TYPE.CONNECTION_STATE_FAILED ) { // If we are not connected yet, connect to the channel as normal JoinChannel(); } else { // If we are already connected, we should just update the token UpdateToken(); } } private void UpdateToken() { rtcEngine.RenewToken(AgoraTestVideo._channelToken); } internal static void DestroyVideoView(uint uid) { GameObject go = GameObject.Find(uid.ToString()); if (!ReferenceEquals(go, null)) { Object.Destroy(go); } } internal static void MakeVideoView(uint uid, string channelId = "") { GameObject go = GameObject.Find(uid.ToString()); if (!ReferenceEquals(go, null)) { return; // reuse } // create a GameObject and assign to this new user VideoSurface videoSurface = MakeImageSurface(uid.ToString()); if (!ReferenceEquals(videoSurface, null)) { // 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); } } internal string GetChannelName() { return _channelName; } private static VideoSurface MakeImageSurface(string goName) { GameObject go = new GameObject(); if (go == null) { return null; } go.name = goName; // to be renderered onto go.AddComponent(); // make the object draggable go.AddComponent(); GameObject canvas = GameObject.Find("VideoCanvas"); if (canvas != null) { go.transform.parent = canvas.transform; Debug.Log("add video view"); } else { Debug.Log("Canvas is null video view"); } // set up transform go.transform.Rotate(0f, 0.0f, 180.0f); go.transform.localPosition = Vector3.zero; go.transform.localScale = new Vector3(3f, 4f, 1f); // configure videoSurface var videoSurface = go.AddComponent(); return videoSurface; } private void OnDestroy() { Debug.Log("OnDestroy"); if (rtcEngine == null) return; rtcEngine.InitEventHandler(null); rtcEngine.LeaveChannel(); rtcEngine.Dispose(); } } internal class UserEventHandler : IRtcEngineEventHandler { private readonly AgoraTestVideo _helloVideoTokenAgora; internal UserEventHandler(AgoraTestVideo helloVideoTokenAgora) { _helloVideoTokenAgora = helloVideoTokenAgora; } public override void OnError(int err, string msg) { _helloVideoTokenAgora.Log.UpdateLog(string.Format("OnError err: {0}, msg: {1}", err, msg)); } public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed) { int build = 0; _helloVideoTokenAgora.Log.UpdateLog(string.Format("sdk version: ${0}", _helloVideoTokenAgora.rtcEngine.GetVersion(ref build))); _helloVideoTokenAgora.Log.UpdateLog( string.Format("OnJoinChannelSuccess channelName: {0}, uid: {1}, elapsed: {2}", connection.channelId, connection.localUid, elapsed)); _helloVideoTokenAgora.Log.UpdateLog(string.Format("New Token: {0}", AgoraTestVideo._channelToken)); // HelperClass.FetchToken(tokenBase, channelName, 0, this.RenewOrJoinToken); AgoraTestVideo.MakeVideoView(0); } public override void OnRejoinChannelSuccess(RtcConnection connection, int elapsed) { _helloVideoTokenAgora.Log.UpdateLog("OnRejoinChannelSuccess"); } public override void OnLeaveChannel(RtcConnection connection, RtcStats stats) { _helloVideoTokenAgora.Log.UpdateLog("OnLeaveChannel"); AgoraTestVideo.DestroyVideoView(0); } public override void OnClientRoleChanged(RtcConnection connection, CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole) { _helloVideoTokenAgora.Log.UpdateLog("OnClientRoleChanged"); } public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed) { _helloVideoTokenAgora.Log.UpdateLog(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed)); AgoraTestVideo.MakeVideoView(uid, _helloVideoTokenAgora.GetChannelName()); } public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason) { _helloVideoTokenAgora.Log.UpdateLog(string.Format("OnUserOffLine uid: ${0}, reason: ${1}", uid, (int)reason)); AgoraTestVideo.DestroyVideoView(uid); } public override void OnTokenPrivilegeWillExpire(RtcConnection connection, string token) { _helloVideoTokenAgora.StartCoroutine(HelperClass.FetchToken(AgoraTestVideo._tokenBase, _helloVideoTokenAgora.GetChannelName(), 0, _helloVideoTokenAgora.RenewOrJoinToken)); } public override void OnConnectionStateChanged(RtcConnection connection, CONNECTION_STATE_TYPE state, CONNECTION_CHANGED_REASON_TYPE reason) { _helloVideoTokenAgora._state = state; } public override void OnConnectionLost(RtcConnection connection) { _helloVideoTokenAgora.Log.UpdateLog(string.Format("OnConnectionLost ")); } }