Created
December 10, 2019 04:51
-
-
Save icywind/41fcbbac76ed119c641820802be8531e to your computer and use it in GitHub Desktop.
Updated version of VideoSurface to use RawImage for rendering.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Runtime.InteropServices; | |
using UnityEngine.UI; | |
/**!! This version of the script is non-official. use it on your own risk! */ | |
/* | |
* This example script demonstrates how to attachThis example | |
* video content to a 3D object (chenzhenyong@agora.io) | |
* | |
* Agora engine outputs one local preview video and some | |
* remote user video. User ID (int) is used to identify | |
* these video streams. 0 is used for local preview video | |
* stream, and other value stands for remote user video | |
* stream. | |
*/ | |
public enum AgoraVideoSurfaceType | |
{ | |
Renderer, | |
RawImage | |
}; | |
public class VideoSurface : MonoBehaviour | |
{ | |
private System.IntPtr data = Marshal.AllocHGlobal(1920 * 1080 * 4); | |
private int defWidth = 0; | |
private int defHeight = 0; | |
private Texture2D nativeTexture; | |
[SerializeField] | |
AgoraVideoSurfaceType VideoSurfaceType = AgoraVideoSurfaceType.Renderer; | |
/* only one of the following should be set, depends on VideoSurfaceType */ | |
private Renderer mRenderer = null; | |
private RawImage mRawImage = null; | |
private bool _initialized = false; | |
void Start() | |
{ | |
// render video | |
if (VideoSurfaceType == AgoraVideoSurfaceType.Renderer) | |
{ | |
mRenderer = GetComponent<Renderer>(); | |
} | |
if (mRenderer == null || VideoSurfaceType == AgoraVideoSurfaceType.RawImage) | |
{ | |
mRawImage = GetComponent<RawImage>(); | |
if (mRawImage != null) | |
{ | |
// the variable may have been set to default enum but actually it is a RawImage | |
VideoSurfaceType = AgoraVideoSurfaceType.RawImage; | |
} | |
} | |
if (mRawImage == null && mRenderer == null) | |
{ | |
Debug.LogError("Unable to find surface render in VideoSurface component."); | |
} | |
else | |
{ | |
_initialized = true; | |
} | |
} | |
bool IsBlankTexture() | |
{ | |
if (VideoSurfaceType == AgoraVideoSurfaceType.Renderer) | |
{ | |
// if never assigned or assigned texture is not Texture2D, we will consider it blank and create a new one | |
return (mRenderer.material.mainTexture == null || !(mRenderer.material.mainTexture is Texture2D)); | |
} | |
else | |
{ | |
return (mRawImage.texture == null); | |
} | |
} | |
/// <summary> | |
/// nativeTexture at the calling point should have created with image data. This method | |
/// apply this reference to the surface renderer. | |
/// </summary> | |
void ApplyTexture() | |
{ | |
if (VideoSurfaceType == AgoraVideoSurfaceType.Renderer) | |
{ | |
mRenderer.material.mainTexture = nativeTexture; | |
} | |
else | |
{ | |
mRawImage.texture = nativeTexture; | |
} | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
agora_gaming_rtc.IRtcEngine engine = agora_gaming_rtc.IRtcEngine.QueryEngine(); | |
if (engine == null || !_initialized) | |
{ | |
return; | |
} | |
uint uid = mUid; | |
#if UNITY_STANDALONE_WIN || UNITY_EDITOR || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_ANDROID || UNITY_IOS || UNITY_IPHONE | |
if (mEnable) | |
{ | |
// create texture if not existent | |
if ( IsBlankTexture() ) | |
{ | |
int tmpi = engine.UpdateTexture(0, uid, data, ref defWidth, ref defHeight); | |
if (tmpi == -1) { | |
return; | |
} | |
if (defWidth > 0 && defHeight > 0) | |
{ | |
try | |
{ | |
// create Texture in the first time update data | |
nativeTexture = new Texture2D((int)defWidth, (int)defHeight, TextureFormat.RGBA32, false); | |
nativeTexture.LoadRawTextureData(data, (int)defWidth * (int)defHeight * 4); | |
nativeTexture.Apply(); | |
ApplyTexture(); | |
} | |
catch (System.Exception e) | |
{ | |
Debug.Log("Exception e = " + e); | |
} | |
} | |
} | |
else | |
{ | |
int width = 0; | |
int height = 0; | |
int tmpi = engine.UpdateTexture(0, uid, data, ref width, ref height); | |
if (tmpi == -1) { | |
return; | |
} | |
if (width == defWidth && height == defHeight) | |
{ | |
// Note that nativeTexture is being referenced in the renderer/raw image's texture. | |
// updating nativeTexture is updating renderer or raw image. | |
try | |
{ | |
/* | |
* if width and height don't change, we only need to update data for texture, do not need to create Texture. | |
*/ | |
nativeTexture.LoadRawTextureData(data, (int)width * (int)height * 4); | |
nativeTexture.Apply(); | |
} | |
catch (System.Exception e) | |
{ | |
Debug.Log("Exception e = " + e); | |
} | |
} else if (width > 0 && height > 0) { | |
try | |
{ | |
/* | |
* if width or height changed, we need to create new texture. | |
*/ | |
defWidth = width; | |
defHeight = height; | |
ApplyTexture(); | |
} | |
catch (System.Exception e) | |
{ | |
Debug.Log("Exception e = " + e); | |
Debug.LogWarning("Exception, got width = " + width + " height = " + height); | |
} | |
} | |
} | |
} | |
else // not mEnabled | |
{ | |
nativeTexture = null; | |
ApplyTexture(); | |
} | |
#endif | |
} | |
void OnDestroy() | |
{ | |
Marshal.FreeHGlobal(data); | |
Debug.Log("VideoSurface Destroyed."); | |
} | |
// call this to render video stream from uid on this game object | |
public void SetForUser(uint uid) | |
{ | |
mUid = uid; | |
Debug.Log("Set uid " + uid + " for gameObject" + gameObject.name); | |
} | |
/* | |
* if enable = true, the video will render. if enable = false, the video will stop render. | |
*/ | |
public void SetEnable(bool enable) | |
{ | |
mEnable = enable; | |
} | |
public void ResetTexture() | |
{ | |
nativeTexture = new Texture2D ((int)defWidth, (int)defHeight, TextureFormat.RGBA32, false); | |
} | |
/* | |
* uid = 0, it means yourself but not others, you can get others uid by Agora Engine CallBack onUserJoined. | |
*/ | |
private uint mUid = 0; | |
/* | |
*if disabled, then no rendering happens | |
*/ | |
private bool mEnable = true; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment