VideoSurface.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #if UNITY_EDITOR_WIN || UNITY_EDITOR_OSX || UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_ANDROID
  2. using UnityEngine;
  3. using UnityEngine.UI;
  4. namespace Agora.Rtc
  5. {
  6. public enum VideoSurfaceType
  7. {
  8. Renderer = 0,
  9. RawImage = 1,
  10. };
  11. public delegate void OnTextureSizeModifyHandler(int width, int height);
  12. public sealed class VideoSurface : MonoBehaviour
  13. {
  14. [SerializeField] private VideoSurfaceType VideoSurfaceType = VideoSurfaceType.Renderer;
  15. [SerializeField] private bool Enable = true;
  16. [SerializeField] private uint Uid = 0;
  17. [SerializeField] private string ChannelId = "";
  18. [SerializeField] private VIDEO_SOURCE_TYPE SourceType = VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA_PRIMARY;
  19. private Component _renderer;
  20. private bool _needUpdateInfo = true;
  21. private bool _hasAttach = false;
  22. private GameObject _TextureManagerGameObject;
  23. private TextureManager _textureManager;
  24. private int _textureWidth = 0;
  25. private int _textureHeight = 0;
  26. public event OnTextureSizeModifyHandler OnTextureSizeModify;
  27. void Start()
  28. {
  29. CheckVideoSurfaceType();
  30. }
  31. void Update()
  32. {
  33. if (_renderer == null || _needUpdateInfo) return;
  34. if (Enable)
  35. {
  36. if (_textureManager == null)
  37. {
  38. _TextureManagerGameObject = GameObject.Find("TextureManager" + Uid.ToString() + ChannelId + SourceType.ToString());
  39. if (_TextureManagerGameObject == null)
  40. {
  41. _TextureManagerGameObject = new GameObject("TextureManager" + Uid.ToString() + ChannelId + SourceType.ToString());
  42. _TextureManagerGameObject.hideFlags = HideFlags.HideInHierarchy;
  43. _textureManager = _TextureManagerGameObject.AddComponent<TextureManager>();
  44. _textureManager.SetVideoStreamIdentity(Uid, ChannelId, SourceType);
  45. _textureManager.EnableVideoFrameWithIdentity();
  46. }
  47. else
  48. {
  49. _textureManager = _TextureManagerGameObject.GetComponent<TextureManager>();
  50. }
  51. }
  52. else if(_textureManager && !_hasAttach && _textureManager.CanTextureAttach())
  53. {
  54. ApplyTexture(_textureManager.Texture);
  55. _hasAttach = true;
  56. }
  57. if (_textureManager && (this._textureWidth != _textureManager.Width || this._textureHeight != _textureManager.Height))
  58. {
  59. this._textureWidth = _textureManager.Width;
  60. this._textureHeight = _textureManager.Height;
  61. if (this._textureWidth != 0 && this._textureHeight != 0 && this.OnTextureSizeModify!= null)
  62. {
  63. this.OnTextureSizeModify.Invoke(this._textureWidth, this._textureHeight);
  64. }
  65. }
  66. }
  67. else
  68. {
  69. if (_hasAttach && !IsBlankTexture())
  70. {
  71. DestroyTextureManager();
  72. ApplyTexture(null);
  73. }
  74. }
  75. }
  76. void OnDestroy()
  77. {
  78. AgoraLog.Log(string.Format("VideoSurface channel: ${0}, user:{1} destroy", ChannelId, Uid));
  79. DestroyTextureManager();
  80. }
  81. private void CheckVideoSurfaceType()
  82. {
  83. if (VideoSurfaceType == VideoSurfaceType.Renderer)
  84. {
  85. _renderer = GetComponent<Renderer>();
  86. }
  87. if (_renderer == null || VideoSurfaceType == VideoSurfaceType.RawImage)
  88. {
  89. _renderer = GetComponent<RawImage>();
  90. if (_renderer != null)
  91. {
  92. VideoSurfaceType = VideoSurfaceType.RawImage;
  93. }
  94. }
  95. if (_renderer == null)
  96. {
  97. AgoraLog.LogError("Unable to find surface render in VideoSurface component.");
  98. }
  99. else
  100. {
  101. #if UNITY_EDITOR
  102. // this only applies to Editor, in case of material is too dark
  103. UpdateShader();
  104. #endif
  105. }
  106. }
  107. private void DestroyTextureManager()
  108. {
  109. if (_textureManager == null) return;
  110. if (_hasAttach == true)
  111. {
  112. _textureManager.Detach();
  113. _hasAttach = false;
  114. }
  115. if (_textureManager.GetRefCount() <= 0)
  116. {
  117. Destroy(_TextureManagerGameObject);
  118. }
  119. _textureManager = null;
  120. }
  121. private bool IsBlankTexture()
  122. {
  123. if (VideoSurfaceType == VideoSurfaceType.Renderer)
  124. {
  125. var rd = (_renderer as Renderer);
  126. return rd.material.mainTexture == null || !(rd.material.mainTexture is Texture2D);
  127. }
  128. else if (VideoSurfaceType == VideoSurfaceType.RawImage)
  129. {
  130. var rd = (_renderer as RawImage);
  131. return (rd.texture == null);
  132. }
  133. else
  134. {
  135. return true;
  136. }
  137. }
  138. private void ApplyTexture(Texture2D texture)
  139. {
  140. if (VideoSurfaceType == VideoSurfaceType.Renderer)
  141. {
  142. var rd = _renderer as Renderer;
  143. rd.material.mainTexture = texture;
  144. }
  145. else if (VideoSurfaceType == VideoSurfaceType.RawImage)
  146. {
  147. var rd = _renderer as RawImage;
  148. rd.texture = texture;
  149. }
  150. }
  151. private void UpdateShader()
  152. {
  153. var mesh = GetComponent<MeshRenderer>();
  154. if (mesh != null)
  155. {
  156. mesh.material = new Material(Shader.Find("Unlit/Texture"));
  157. }
  158. }
  159. public void SetForUser(uint uid = 0, string channelId = "",
  160. VIDEO_SOURCE_TYPE source_type = VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA_PRIMARY)
  161. {
  162. Uid = uid;
  163. ChannelId = channelId;
  164. SourceType = source_type;
  165. _needUpdateInfo = false;
  166. }
  167. public void SetEnable(bool enable)
  168. {
  169. Enable = enable;
  170. }
  171. }
  172. }
  173. #endif