139 lines
3.2 KiB
C#
139 lines
3.2 KiB
C#
using UnityEngine;
|
|
using RenderHeads.Media.AVProVideo;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Copyright 2015-2018 RenderHeads Ltd. All rights reserverd.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
namespace RenderHeads.Media.AVProVideo.Demos
|
|
{
|
|
/// <summary>
|
|
/// Small demonstration of how you might synchronise multiple video playback
|
|
/// Ideally the videos should be encoded with as many key-frames (I-frames) as possible
|
|
/// </summary>
|
|
public class PlaybackSync : MonoBehaviour
|
|
{
|
|
private enum State
|
|
{
|
|
Loading,
|
|
Playing,
|
|
Finished,
|
|
}
|
|
|
|
public MediaPlayer _masterPlayer;
|
|
public MediaPlayer[] _slavePlayers;
|
|
public float _toleranceMs = 30f;
|
|
public bool _matchVideo = true;
|
|
public bool _muteSlaves = true;
|
|
private State _state = State.Loading;
|
|
|
|
void Start()
|
|
{
|
|
// Setup the slaves
|
|
for (int i = 0; i < _slavePlayers.Length; i++)
|
|
{
|
|
_slavePlayers[i].m_Muted = true;
|
|
if (_matchVideo)
|
|
{
|
|
_slavePlayers[i].OpenVideoFromFile(_masterPlayer.m_VideoLocation, _masterPlayer.m_VideoPath, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
if (_state == State.Loading)
|
|
{
|
|
// Finished loading?
|
|
if (IsAllVideosLoaded())
|
|
{
|
|
// Play the videos
|
|
_masterPlayer.Play();
|
|
for (int i = 0; i < _slavePlayers.Length; i++)
|
|
{
|
|
_slavePlayers[i].Play();
|
|
}
|
|
_state = State.Playing;
|
|
}
|
|
}
|
|
|
|
if (_state == State.Finished)
|
|
{
|
|
Debug.Log("Do Something");
|
|
}
|
|
else if (_state == State.Playing)
|
|
{
|
|
if (_masterPlayer.Control.IsPlaying())
|
|
{
|
|
// Keep the slaves synced
|
|
float masterTime = _masterPlayer.Control.GetCurrentTimeMs();
|
|
for (int i = 0; i < _slavePlayers.Length; i++)
|
|
{
|
|
MediaPlayer slave = _slavePlayers[i];
|
|
float slaveTime = slave.Control.GetCurrentTimeMs();
|
|
float deltaTime = Mathf.Abs(masterTime - slaveTime);
|
|
if (deltaTime > _toleranceMs)
|
|
{
|
|
slave.Control.SeekFast(masterTime + (_toleranceMs * 0.5f)); // Add a bit to allow for the delay in playback start
|
|
if (slave.Control.IsPaused())
|
|
{
|
|
slave.Play();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Pause slaves
|
|
for (int i = 0; i < _slavePlayers.Length; i++)
|
|
{
|
|
MediaPlayer slave = _slavePlayers[i];
|
|
slave.Pause();
|
|
}
|
|
}
|
|
|
|
// Finished?
|
|
if (IsPlaybackFinished(_masterPlayer))
|
|
{
|
|
_state = State.Finished;
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool IsAllVideosLoaded()
|
|
{
|
|
bool result = false;
|
|
if (IsVideoLoaded(_masterPlayer))
|
|
{
|
|
result = true;
|
|
for (int i = 0; i < _slavePlayers.Length; i++)
|
|
{
|
|
if (!IsVideoLoaded(_slavePlayers[i]))
|
|
{
|
|
result = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static bool IsVideoLoaded(MediaPlayer player)
|
|
{
|
|
return (player != null && player.Control != null && player.Control.HasMetaData() && player.Control.CanPlay() && player.TextureProducer.GetTextureFrameCount() > 0);
|
|
}
|
|
|
|
private static bool IsPlaybackFinished(MediaPlayer player)
|
|
{
|
|
bool result = false;
|
|
if (player != null && player.Control != null)
|
|
{
|
|
if (player.Control.IsFinished())
|
|
{
|
|
result = true;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
}
|
|
} |