Skip to content

Commit

Permalink
Merge pull request #304 from techanon/global-video-texture
Browse files Browse the repository at this point in the history
Add _Udon_VideoTex global texture support for testing Avatars
  • Loading branch information
pema99 authored May 6, 2024
2 parents 1991f36 + 4d20f9a commit c40869e
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 5 deletions.
10 changes: 10 additions & 0 deletions Packages/com.llealloo.audiolink/Runtime/AudioLinkAvatar.prefab
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,16 @@ MonoBehaviour:
showVideoPreviewInComponent: 0
videoPlayer: {fileID: 5208934818770322006}
resolution: 720
enableGlobalVideoTexture: 0
globalTextureName: _Udon_VideoTex
textureTransformMode: 1
texturePixelOrigin: {x: 0, y: 0}
texturePixelSize: {x: 0, y: 0}
textureTiling: {x: 1, y: 1}
textureOffset: {x: 0, y: 0}
forceStandbyTexture: 0
showStandbyIfPaused: 1
standbyTexture: {fileID: 0}
--- !u!1 &8800328339556915021
GameObject:
m_ObjectHideFlags: 0
Expand Down
154 changes: 149 additions & 5 deletions Packages/com.llealloo.audiolink/Runtime/Scripts/ytdlpPlayer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,38 @@

namespace AudioLink
{

public class ytdlpPlayer : MonoBehaviour
{
public enum TextureTransformMode
{
AsIs,
Normalized,
ByPixels
}

public string ytdlpURL = "https://www.youtube.com/watch?v=SFTcZ1GXOCQ";
ytdlpRequest _currentRequest = null;

[SerializeField] public bool showVideoPreviewInComponent = false;

public bool showVideoPreviewInComponent = false;
public VideoPlayer videoPlayer = null;

[SerializeField] public Resolution resolution = Resolution._720p;
public Resolution resolution = Resolution._720p;

public bool enableGlobalVideoTexture = false;
public string globalTextureName = "_Udon_VideoTex";
public TextureTransformMode textureTransformMode = TextureTransformMode.Normalized;
public Vector2Int texturePixelOrigin = new Vector2Int(0, 0);
public Vector2Int texturePixelSize = new Vector2Int(0, 0);
public Vector2 textureTiling = new Vector2(1f, 1f);
public Vector2 textureOffset = new Vector2(0f, 0f);
public bool forceStandbyTexture = false;
public bool showStandbyIfPaused = true;
public Texture2D standbyTexture;

private int _globalTextureId;
private int _globalTextureTransformId;
private bool _globalTextureActive = false;
internal Vector4 _lastGlobalST = Vector4.zero;

public enum Resolution
{
Expand All @@ -37,6 +59,8 @@ public enum Resolution

void OnEnable()
{
_globalTextureId = Shader.PropertyToID(globalTextureName);
_globalTextureTransformId = Shader.PropertyToID(globalTextureName + "_ST");
RequestPlay();
}

Expand All @@ -45,7 +69,7 @@ public void RequestPlay()
_currentRequest = ytdlpURLResolver.Resolve(ytdlpURL, (int)resolution);
}

void Update()
private void Update()
{
if (_currentRequest != null && _currentRequest.isDone)
{
Expand All @@ -54,6 +78,8 @@ void Update()
}
}

private void LateUpdate() => ExportGlobalVideoTexture();

public void UpdateUrl(string resolved)
{
if (videoPlayer == null)
Expand Down Expand Up @@ -130,6 +156,67 @@ public void SetAudioSourceVolume(float volume)
audioSourceOutput.volume = Mathf.Clamp01(volume);
}
}

private void ExportGlobalVideoTexture()
{
Texture texture = null;
bool showStandby = forceStandbyTexture;
if (!showStandby && videoPlayer != null)
{
// enable pausing or stopping the video to make the standby texture show
showStandby |= (!videoPlayer.isPaused || showStandbyIfPaused) && !videoPlayer.isPlaying;
if (!showStandby) texture = videoPlayer.targetTexture != null ? videoPlayer.targetTexture : videoPlayer.texture;
}

showStandby |= texture == null;
if (showStandby && standbyTexture != null)
texture = standbyTexture;

Vector4 st = new Vector4(1, 1, 0, 0);
if (enableGlobalVideoTexture)
{
if (texture != null && !showStandby)
{
switch (textureTransformMode)
{
case TextureTransformMode.Normalized:
st.x = textureTiling.x;
st.y = textureTiling.y;
st.z = textureOffset.x;
st.w = textureOffset.y;
break;
case TextureTransformMode.ByPixels:
// calculate offset/tiling from source texture pixel size.
float sourceWidth = texture.width;
float sourceHeight = texture.height;
float targetWidth = texturePixelSize.x;
float targetHeight = texturePixelSize.y;
float targetX = texturePixelOrigin.x;
float targetY = texturePixelOrigin.y;
if (targetWidth == 0) targetWidth = sourceWidth;
if (targetHeight == 0) targetHeight = sourceHeight;
st.x = targetWidth / sourceWidth;
st.y = targetHeight / sourceHeight;
st.z = targetX / sourceWidth;
st.w = (sourceHeight - targetHeight - targetY) / sourceHeight;
break;
}
}

Shader.SetGlobalVector(_globalTextureTransformId, st);
Shader.SetGlobalTexture(_globalTextureId, texture);
_lastGlobalST = st;
_globalTextureActive = true;
}
// if globals ever get disabled, unset the custom texture global flag as well
else if (_globalTextureActive)
{
_globalTextureActive = false;
_lastGlobalST = st;
Shader.SetGlobalVector(_globalTextureTransformId, st);
Shader.SetGlobalTexture(_globalTextureId, null);
}
}
}

public class ytdlpRequest
Expand Down Expand Up @@ -325,6 +412,17 @@ public class ytdlpPlayerEditor : UnityEditor.Editor
private SerializedProperty ytdlpURL;
private SerializedProperty resolution;

private SerializedProperty enableGlobalVideoTexture;
private SerializedProperty globalTextureName;
private SerializedProperty transformTextureMode;
private SerializedProperty texturePixelOrigin;
private SerializedProperty texturePixelSize;
private SerializedProperty textureTiling;
private SerializedProperty textureOffset;
private SerializedProperty showStandbyIfPaused;
private SerializedProperty forceStandbyTexture;
private SerializedProperty standbyTexture;

void OnEnable()
{
_ytdlpPlayer = (ytdlpPlayer)target;
Expand All @@ -334,6 +432,16 @@ void OnEnable()

ytdlpURL = serializedObject.FindProperty(nameof(_ytdlpPlayer.ytdlpURL));
resolution = serializedObject.FindProperty(nameof(_ytdlpPlayer.resolution));
enableGlobalVideoTexture = serializedObject.FindProperty(nameof(_ytdlpPlayer.enableGlobalVideoTexture));
globalTextureName = serializedObject.FindProperty(nameof(_ytdlpPlayer.globalTextureName));
transformTextureMode = serializedObject.FindProperty(nameof(_ytdlpPlayer.textureTransformMode));
texturePixelOrigin = serializedObject.FindProperty(nameof(_ytdlpPlayer.texturePixelOrigin));
texturePixelSize = serializedObject.FindProperty(nameof(_ytdlpPlayer.texturePixelSize));
textureTiling = serializedObject.FindProperty(nameof(_ytdlpPlayer.textureTiling));
textureOffset = serializedObject.FindProperty(nameof(_ytdlpPlayer.textureOffset));
showStandbyIfPaused = serializedObject.FindProperty(nameof(_ytdlpPlayer.showStandbyIfPaused));
forceStandbyTexture = serializedObject.FindProperty(nameof(_ytdlpPlayer.forceStandbyTexture));
standbyTexture = serializedObject.FindProperty(nameof(_ytdlpPlayer.standbyTexture));
}

public override bool RequiresConstantRepaint()
Expand Down Expand Up @@ -458,10 +566,46 @@ public override void OnInspectorGUI()
{
// Draw video preview with the same aspect ratio as the video
Texture videoPlayerTexture = _ytdlpPlayer.videoPlayer.texture;
EditorGUILayout.LabelField($"Resolution: {videoPlayerTexture.width}x{videoPlayerTexture.height}");
float aspectRatio = (float)videoPlayerTexture.width / videoPlayerTexture.height;
Rect previewRect = GUILayoutUtility.GetAspectRect(aspectRatio);
EditorGUI.DrawPreviewTexture(previewRect, videoPlayerTexture, null, ScaleMode.ScaleToFit);
}

EditorGUILayout.PropertyField(enableGlobalVideoTexture, new GUIContent("Enable Global Video Texture"));
using (new EditorGUILayout.VerticalScope("box"))
{
if (_ytdlpPlayer.enableGlobalVideoTexture)
{
EditorGUILayout.LabelField("Global Video Texture Settings");

EditorGUILayout.HelpBox("Global Video Texture is NOT part of AudioLink and is only provided as a convenience for testing avatars in editor.", MessageType.Info);

using (new EditorGUI.DisabledScope(EditorApplication.isPlaying))
EditorGUILayout.PropertyField(globalTextureName, new GUIContent("Global Texture Property Target"));
EditorGUILayout.PropertyField(transformTextureMode, new GUIContent("Transform Texture (" + _ytdlpPlayer.globalTextureName + "_ST)"));
EditorGUI.indentLevel++;
switch (_ytdlpPlayer.textureTransformMode)
{
case ytdlpPlayer.TextureTransformMode.Normalized:
EditorGUILayout.PropertyField(textureTiling, new GUIContent("Tiling"));
EditorGUILayout.PropertyField(textureOffset, new GUIContent("Offset"));
break;
case ytdlpPlayer.TextureTransformMode.ByPixels:
EditorGUILayout.PropertyField(texturePixelOrigin, new GUIContent("Pixel Origin (from Top-Left)"));
EditorGUILayout.PropertyField(texturePixelSize, new GUIContent("Pixel Size (0 = Texture Source Size)"));
if (EditorApplication.isPlaying)
using (new EditorGUI.DisabledScope(true))
EditorGUILayout.LabelField($"Normalized: {_ytdlpPlayer._lastGlobalST}");
break;
}

EditorGUI.indentLevel--;
EditorGUILayout.PropertyField(showStandbyIfPaused, new GUIContent("Show Standby Texture when Paused"));
EditorGUILayout.PropertyField(forceStandbyTexture, new GUIContent("Force Show Standby Texture"));
EditorGUILayout.PropertyField(standbyTexture, new GUIContent("Standby Texture"), GUILayout.Height(EditorGUIUtility.singleLineHeight));
}
}
}

if (!available)
Expand Down

0 comments on commit c40869e

Please sign in to comment.