134 lines
4.5 KiB
C#
134 lines
4.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.Playables;
|
|
using UnityEngine.Video;
|
|
|
|
[System.Serializable]
|
|
public class VideoPlayerBehaviour : PlayableBehaviour
|
|
{
|
|
public VideoClip videoClip;
|
|
public float playbackSpeed = 1f;
|
|
|
|
private VideoPlayer m_VideoPlayer;
|
|
private PlayableDirector m_Director;
|
|
private bool m_VideoSetup = false;
|
|
private bool m_WasTimelinePlaying = false;
|
|
private double m_LastSyncTime = -1;
|
|
private int m_SyncCooldownFrames = 0;
|
|
private const int SYNC_COOLDOWN_DURATION = 5;
|
|
|
|
public override void OnPlayableCreate(Playable playable)
|
|
{
|
|
if (m_Director == null)
|
|
{
|
|
m_Director = Object.FindObjectOfType<PlayableDirector>();
|
|
}
|
|
m_VideoSetup = false;
|
|
m_WasTimelinePlaying = false;
|
|
m_LastSyncTime = -1;
|
|
m_SyncCooldownFrames = 0;
|
|
}
|
|
|
|
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
|
|
{
|
|
if (playerData == null) return;
|
|
|
|
m_VideoPlayer = playerData as VideoPlayer;
|
|
if (m_VideoPlayer == null) return;
|
|
|
|
if (m_SyncCooldownFrames > 0)
|
|
{
|
|
m_SyncCooldownFrames--;
|
|
}
|
|
|
|
if (!m_VideoSetup && videoClip != null)
|
|
{
|
|
m_VideoPlayer.clip = videoClip;
|
|
m_VideoSetup = true;
|
|
}
|
|
|
|
if (info.weight > 0.5f)
|
|
{
|
|
bool isTimelinePlaying = m_Director != null && m_Director.state == PlayState.Playing;
|
|
|
|
double normalizedTime = playable.GetTime() / playable.GetDuration();
|
|
double targetTime = normalizedTime * videoClip.length;
|
|
|
|
if (isTimelinePlaying != m_WasTimelinePlaying)
|
|
{
|
|
Debug.Log($"Timeline state changed: {m_WasTimelinePlaying} -> {isTimelinePlaying}");
|
|
|
|
if (isTimelinePlaying)
|
|
{
|
|
Debug.Log($"Starting playback at time: {targetTime:F3} (Timeline: {playable.GetTime():F3})");
|
|
|
|
m_VideoPlayer.time = targetTime;
|
|
m_VideoPlayer.playbackSpeed = playbackSpeed;
|
|
m_LastSyncTime = targetTime;
|
|
m_SyncCooldownFrames = SYNC_COOLDOWN_DURATION;
|
|
|
|
if (!m_VideoPlayer.isPlaying)
|
|
{
|
|
m_VideoPlayer.Play();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Debug.Log($"Pausing at time: {m_VideoPlayer.time:F3}");
|
|
if (m_VideoPlayer.isPlaying)
|
|
{
|
|
m_VideoPlayer.Pause();
|
|
}
|
|
}
|
|
m_WasTimelinePlaying = isTimelinePlaying;
|
|
}
|
|
|
|
if (isTimelinePlaying)
|
|
{
|
|
if (m_SyncCooldownFrames <= 0)
|
|
{
|
|
double timeDiff = Mathf.Abs((float)(m_VideoPlayer.time - targetTime));
|
|
|
|
if (timeDiff > 0.3)
|
|
{
|
|
Debug.Log($"Large drift detected - Re-syncing: Video={m_VideoPlayer.time:F3}, Target={targetTime:F3}, Diff={timeDiff:F3}");
|
|
|
|
if (m_VideoPlayer.isPrepared)
|
|
{
|
|
m_VideoPlayer.time = targetTime;
|
|
m_LastSyncTime = targetTime;
|
|
m_SyncCooldownFrames = SYNC_COOLDOWN_DURATION;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_SyncCooldownFrames <= 0)
|
|
{
|
|
double timeDiff = Mathf.Abs((float)(m_VideoPlayer.time - targetTime));
|
|
if (timeDiff > 0.033)
|
|
{
|
|
if (m_VideoPlayer.isPrepared)
|
|
{
|
|
m_VideoPlayer.time = targetTime;
|
|
m_LastSyncTime = targetTime;
|
|
m_SyncCooldownFrames = 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void OnBehaviourPause(Playable playable, FrameData info)
|
|
{
|
|
Debug.Log("Clip ended - stopping video");
|
|
if (m_VideoPlayer != null)
|
|
{
|
|
m_VideoPlayer.Pause();
|
|
}
|
|
m_WasTimelinePlaying = false;
|
|
m_LastSyncTime = -1;
|
|
m_SyncCooldownFrames = 0;
|
|
}
|
|
} |