JoinChannelVideo.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. using UnityEngine;
  2. using UnityEngine.UI;
  3. using UnityEngine.Serialization;
  4. using Agora.Rtc;
  5. using Agora.Util;
  6. using Logger = Agora.Util.Logger;
  7. namespace Agora_RTC_Plugin.API_Example.Examples.Basic.JoinChannelVideo
  8. {
  9. public class JoinChannelVideo : MonoBehaviour
  10. {
  11. [FormerlySerializedAs("appIdInput")]
  12. [SerializeField]
  13. private AppIdInput _appIdInput;
  14. [Header("_____________Basic Configuration_____________")]
  15. [FormerlySerializedAs("APP_ID")]
  16. [SerializeField]
  17. private string _appID = "";
  18. [FormerlySerializedAs("TOKEN")]
  19. [SerializeField]
  20. private string _token = "";
  21. [FormerlySerializedAs("CHANNEL_NAME")]
  22. [SerializeField]
  23. private string _channelName = "";
  24. public Text LogText;
  25. internal Logger Log;
  26. internal IRtcEngine RtcEngine = null;
  27. private Button _stopPublishButton;
  28. public Button _startPublishButton;
  29. // Use this for initialization
  30. private void Start()
  31. {
  32. LoadAssetData();
  33. if (CheckAppId())
  34. {
  35. InitEngine();
  36. JoinChannel();
  37. SetupUI();
  38. }
  39. }
  40. // Update is called once per frame
  41. private void Update()
  42. {
  43. PermissionHelper.RequestMicrophontPermission();
  44. PermissionHelper.RequestCameraPermission();
  45. }
  46. //Show data in AgoraBasicProfile
  47. [ContextMenu("ShowAgoraBasicProfileData")]
  48. private void LoadAssetData()
  49. {
  50. if (_appIdInput == null) return;
  51. _appID = _appIdInput.appID;
  52. _token = _appIdInput.token;
  53. _channelName = _appIdInput.channelName;
  54. }
  55. private bool CheckAppId()
  56. {
  57. Log = new Logger(LogText);
  58. return Log.DebugAssert(_appID.Length > 10, "Please fill in your appId in API-Example/profile/appIdInput.asset");
  59. }
  60. private void InitEngine()
  61. {
  62. RtcEngine = Agora.Rtc.RtcEngine.CreateAgoraRtcEngine();
  63. UserEventHandler handler = new UserEventHandler(this);
  64. RtcEngineContext context = new RtcEngineContext(_appID, 0,
  65. CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_LIVE_BROADCASTING,
  66. AUDIO_SCENARIO_TYPE.AUDIO_SCENARIO_DEFAULT);
  67. RtcEngine.Initialize(context);
  68. RtcEngine.InitEventHandler(handler);
  69. }
  70. private void JoinChannel()
  71. {
  72. RtcEngine.EnableAudio();
  73. RtcEngine.EnableVideo();
  74. VideoEncoderConfiguration config = new VideoEncoderConfiguration();
  75. config.dimensions = new VideoDimensions(640, 360);
  76. config.frameRate = 15;
  77. config.bitrate = 0;
  78. RtcEngine.SetVideoEncoderConfiguration(config);
  79. RtcEngine.SetChannelProfile(CHANNEL_PROFILE_TYPE.CHANNEL_PROFILE_COMMUNICATION);
  80. RtcEngine.SetClientRole(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
  81. RtcEngine.JoinChannel(_token, _channelName);
  82. }
  83. private void SetupUI()
  84. {
  85. _stopPublishButton = GameObject.Find("StopButton").GetComponent<Button>();
  86. _stopPublishButton.onClick.AddListener(StopPublish);
  87. _startPublishButton = GameObject.Find("StartButton").GetComponent<Button>();
  88. _startPublishButton.onClick.AddListener(StartPublish);
  89. _startPublishButton.gameObject.SetActive(false);
  90. }
  91. private void StopPublish()
  92. {
  93. var options = new ChannelMediaOptions();
  94. options.publishMicrophoneTrack.SetValue(false);
  95. options.publishCameraTrack.SetValue(false);
  96. var nRet = RtcEngine.UpdateChannelMediaOptions(options);
  97. this.Log.UpdateLog("UpdateChannelMediaOptions: " + nRet);
  98. _stopPublishButton.gameObject.SetActive(false);
  99. _startPublishButton.gameObject.SetActive(true);
  100. }
  101. private void StartPublish()
  102. {
  103. var options = new ChannelMediaOptions();
  104. options.publishMicrophoneTrack.SetValue(true);
  105. options.publishCameraTrack.SetValue(true);
  106. var nRet = RtcEngine.UpdateChannelMediaOptions(options);
  107. this.Log.UpdateLog("UpdateChannelMediaOptions: " + nRet);
  108. _stopPublishButton.gameObject.SetActive(true);
  109. _startPublishButton.gameObject.SetActive(false);
  110. }
  111. private void OnDestroy()
  112. {
  113. Debug.Log("OnDestroy");
  114. if (RtcEngine == null) return;
  115. RtcEngine.InitEventHandler(null);
  116. RtcEngine.LeaveChannel();
  117. RtcEngine.Dispose();
  118. }
  119. internal string GetChannelName()
  120. {
  121. return _channelName;
  122. }
  123. internal static void MakeVideoView(uint uid, string channelId = "")
  124. {
  125. var go = GameObject.Find(uid.ToString());
  126. if (!ReferenceEquals(go, null))
  127. {
  128. return; // reuse
  129. }
  130. // create a GameObject and assign to this new user
  131. var videoSurface = MakeImageSurface(uid.ToString());
  132. if (ReferenceEquals(videoSurface, null)) return;
  133. // configure videoSurface
  134. if (uid == 0)
  135. {
  136. videoSurface.SetForUser(uid, channelId);
  137. }
  138. else
  139. {
  140. videoSurface.SetForUser(uid, channelId, VIDEO_SOURCE_TYPE.VIDEO_SOURCE_REMOTE);
  141. }
  142. videoSurface.OnTextureSizeModify += (int width, int height) =>
  143. {
  144. float scale = (float)height / (float)width;
  145. videoSurface.transform.localScale = new Vector3(-5, 5 * scale, 1);
  146. Debug.Log("OnTextureSizeModify: " + width + " " + height);
  147. };
  148. videoSurface.SetEnable(true);
  149. }
  150. #region -- Video Render UI Logic ---
  151. // VIDEO TYPE 1: 3D Object
  152. private static VideoSurface MakePlaneSurface(string goName)
  153. {
  154. var go = GameObject.CreatePrimitive(PrimitiveType.Plane);
  155. if (go == null)
  156. {
  157. return null;
  158. }
  159. go.name = goName;
  160. // set up transform
  161. go.transform.Rotate(-90.0f, 0.0f, 0.0f);
  162. var yPos = Random.Range(3.0f, 5.0f);
  163. var xPos = Random.Range(-2.0f, 2.0f);
  164. go.transform.position = Vector3.zero;
  165. go.transform.localScale = new Vector3(0.25f, 0.5f, 0.5f);
  166. // configure videoSurface
  167. var videoSurface = go.AddComponent<VideoSurface>();
  168. return videoSurface;
  169. }
  170. // Video TYPE 2: RawImage
  171. private static VideoSurface MakeImageSurface(string goName)
  172. {
  173. GameObject go = new GameObject();
  174. if (go == null)
  175. {
  176. return null;
  177. }
  178. go.name = goName;
  179. // to be renderered onto
  180. go.AddComponent<RawImage>();
  181. // make the object draggable
  182. go.AddComponent<UIElementDrag>();
  183. var canvas = GameObject.Find("VideoCanvas");
  184. if (canvas != null)
  185. {
  186. go.transform.parent = canvas.transform;
  187. Debug.Log("add video view");
  188. }
  189. else
  190. {
  191. Debug.Log("Canvas is null video view");
  192. }
  193. // set up transform
  194. go.transform.Rotate(0f, 0.0f, 180.0f);
  195. go.transform.localPosition = Vector3.zero;
  196. go.transform.localScale = new Vector3(2f, 3f, 1f);
  197. // configure videoSurface
  198. var videoSurface = go.AddComponent<VideoSurface>();
  199. return videoSurface;
  200. }
  201. internal static void DestroyVideoView(uint uid)
  202. {
  203. var go = GameObject.Find(uid.ToString());
  204. if (!ReferenceEquals(go, null))
  205. {
  206. Destroy(go);
  207. }
  208. }
  209. # endregion
  210. }
  211. #region -- Agora Event ---
  212. internal class UserEventHandler : IRtcEngineEventHandler
  213. {
  214. private readonly JoinChannelVideo _videoSample;
  215. internal UserEventHandler(JoinChannelVideo videoSample)
  216. {
  217. _videoSample = videoSample;
  218. }
  219. public override void OnError(int err, string msg)
  220. {
  221. _videoSample.Log.UpdateLog(string.Format("OnError err: {0}, msg: {1}", err, msg));
  222. }
  223. public override void OnJoinChannelSuccess(RtcConnection connection, int elapsed)
  224. {
  225. int build = 0;
  226. Debug.Log("Agora: OnJoinChannelSuccess ");
  227. _videoSample.Log.UpdateLog(string.Format("sdk version: ${0}",
  228. _videoSample.RtcEngine.GetVersion(ref build)));
  229. _videoSample.Log.UpdateLog(string.Format("sdk build: ${0}",
  230. build));
  231. _videoSample.Log.UpdateLog(
  232. string.Format("OnJoinChannelSuccess channelName: {0}, uid: {1}, elapsed: {2}",
  233. connection.channelId, connection.localUid, elapsed));
  234. JoinChannelVideo.MakeVideoView(0);
  235. }
  236. public override void OnRejoinChannelSuccess(RtcConnection connection, int elapsed)
  237. {
  238. _videoSample.Log.UpdateLog("OnRejoinChannelSuccess");
  239. }
  240. public override void OnLeaveChannel(RtcConnection connection, RtcStats stats)
  241. {
  242. _videoSample.Log.UpdateLog("OnLeaveChannel");
  243. JoinChannelVideo.DestroyVideoView(0);
  244. }
  245. public override void OnClientRoleChanged(RtcConnection connection, CLIENT_ROLE_TYPE oldRole, CLIENT_ROLE_TYPE newRole)
  246. {
  247. _videoSample.Log.UpdateLog("OnClientRoleChanged");
  248. }
  249. public override void OnUserJoined(RtcConnection connection, uint uid, int elapsed)
  250. {
  251. _videoSample.Log.UpdateLog(string.Format("OnUserJoined uid: ${0} elapsed: ${1}", uid, elapsed));
  252. JoinChannelVideo.MakeVideoView(uid, _videoSample.GetChannelName());
  253. }
  254. public override void OnUserOffline(RtcConnection connection, uint uid, USER_OFFLINE_REASON_TYPE reason)
  255. {
  256. _videoSample.Log.UpdateLog(string.Format("OnUserOffLine uid: ${0}, reason: ${1}", uid,
  257. (int)reason));
  258. JoinChannelVideo.DestroyVideoView(uid);
  259. }
  260. public override void OnUplinkNetworkInfoUpdated(UplinkNetworkInfo info)
  261. {
  262. _videoSample.Log.UpdateLog("OnUplinkNetworkInfoUpdated");
  263. }
  264. public override void OnDownlinkNetworkInfoUpdated(DownlinkNetworkInfo info)
  265. {
  266. _videoSample.Log.UpdateLog("OnDownlinkNetworkInfoUpdated");
  267. }
  268. }
  269. # endregion
  270. }