NewN_UAVPlane/Assets/3rdParty/AVProVideo/Demos/Scripts/SimpleController.cs

364 lines
11 KiB
C#

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using RenderHeads.Media.AVProVideo;
//-----------------------------------------------------------------------------
// Copyright 2015-2018 RenderHeads Ltd. All rights reserverd.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Demos
{
/// <summary>
/// Simple video player GUI built using IMGUI
/// Shows how a simpel video play can be created with scripting
/// Includes support for fading to black when a new video is loaded
/// </summary>
public class SimpleController : MonoBehaviour
{
public string _folder = "AVProVideoSamples/";
public string[] _filenames = new string[] { "SampleSphere.mp4", "BigBuckBunny_360p30.mp3", "BigBuckBunny_720p30.mp4" };
public string[] _streams;
public MediaPlayer _mediaPlayer;
public DisplayIMGUI _display;
public GUISkin _guiSkin;
private int _width;
private int _height;
private float _durationSeconds;
public bool _useFading = true;
private Queue<string> _eventLog = new Queue<string>(8);
private float _eventTimer = 1f;
private MediaPlayer.FileLocation _nextVideoLocation;
private string _nextVideoPath;
//private bool _seekDragStarted;
//private bool _seekDragWasPlaying;
private void Start()
{
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
}
// Callback function to handle events
public void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
{
switch (et)
{
case MediaPlayerEvent.EventType.ReadyToPlay:
break;
case MediaPlayerEvent.EventType.Started:
break;
case MediaPlayerEvent.EventType.FirstFrameReady:
break;
case MediaPlayerEvent.EventType.MetaDataReady:
GatherProperties();
break;
case MediaPlayerEvent.EventType.FinishedPlaying:
break;
}
AddEvent(et);
}
private void AddEvent(MediaPlayerEvent.EventType et)
{
Debug.Log("[SimpleController] Event: " + et.ToString());
_eventLog.Enqueue(et.ToString());
if (_eventLog.Count > 5)
{
_eventLog.Dequeue();
_eventTimer = 1f;
}
}
private void GatherProperties()
{
if (_mediaPlayer != null && _mediaPlayer.Info != null)
{
_width = _mediaPlayer.Info.GetVideoWidth();
_height = _mediaPlayer.Info.GetVideoHeight();
_durationSeconds = _mediaPlayer.Info.GetDurationMs() / 1000f;
}
}
private void Update()
{
if (!_useFading)
{
if (_display != null && _display._mediaPlayer != null && _display._mediaPlayer.Control != null)
{
_display._color = Color.white;
_display._mediaPlayer.Control.SetVolume(1f);
}
}
if (_eventLog != null && _eventLog.Count > 0)
{
_eventTimer -= Time.deltaTime;
if (_eventTimer < 0f)
{
_eventLog.Dequeue();
_eventTimer = 1f;
}
}
}
private void LoadVideo(string filePath, bool url = false)
{
// Set the video file name and to load.
if (!url)
_nextVideoLocation = MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder;
else
_nextVideoLocation = MediaPlayer.FileLocation.AbsolutePathOrURL;
_nextVideoPath = filePath;
// IF we're not using fading then load the video immediately
if (!_useFading)
{
// Load the video
if (!_mediaPlayer.OpenVideoFromFile(_nextVideoLocation, _nextVideoPath, _mediaPlayer.m_AutoStart))
{
Debug.LogError("Failed to open video!");
}
}
else
{
StartCoroutine("LoadVideoWithFading");
}
}
private static bool VideoIsReady(MediaPlayer mp)
{
return (mp != null && mp.TextureProducer != null && mp.TextureProducer.GetTextureFrameCount() <= 0);
}
private static bool AudioIsReady(MediaPlayer mp)
{
return (mp != null && mp.Control != null && mp.Control.CanPlay() && mp.Info.HasAudio() && !mp.Info.HasVideo());
}
private IEnumerator LoadVideoWithFading()
{
const float FadeDuration = 0.25f;
float fade = FadeDuration;
// Fade down
while (fade > 0f && Application.isPlaying)
{
fade -= Time.deltaTime;
fade = Mathf.Clamp(fade, 0f, FadeDuration);
_display._color = new Color(1f, 1f, 1f, fade / FadeDuration);
_display._mediaPlayer.Control.SetVolume(fade / FadeDuration);
yield return null;
}
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
// Load the video
if (Application.isPlaying)
{
if (!_mediaPlayer.OpenVideoFromFile(_nextVideoLocation, _nextVideoPath, _mediaPlayer.m_AutoStart))
{
Debug.LogError("Failed to open video!");
}
else
{
// Wait for the first frame to come through (could also use events for this)
while (Application.isPlaying && (VideoIsReady(_mediaPlayer) || AudioIsReady(_mediaPlayer)))
{
yield return null;
}
// Wait 3 frames for display object to update
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
yield return new WaitForEndOfFrame();
}
}
// Fade up
while (fade < FadeDuration && Application.isPlaying)
{
fade += Time.deltaTime;
fade = Mathf.Clamp(fade, 0f, FadeDuration);
_display._color = new Color(1f, 1f, 1f, fade / FadeDuration);
_display._mediaPlayer.Control.SetVolume(fade / FadeDuration);
yield return null;
}
}
void OnGUI()
{
if (_mediaPlayer == null)
{
return;
}
// Make sure we're set to render after the background IMGUI
GUI.depth = -10;
// Apply skin
if (_guiSkin != null)
{
GUI.skin = _guiSkin;
}
// Make sure the UI scales with screen resolution
const float UIWidth = 1920f / 2.0f;
const float UIHeight = 1080f / 2.0f;
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(Screen.width / UIWidth, Screen.height / UIHeight, 1f));
GUILayout.BeginVertical("box");
if (_mediaPlayer.Control != null)
{
// Display properties
GUILayout.Label("Loaded: " + _mediaPlayer.m_VideoPath);
GUILayout.Label(string.Format("Size: {0}x{1} FPS: {3} Duration: {2}ms", _width, _height, _mediaPlayer.Info.GetDurationMs(), _mediaPlayer.Info.GetVideoFrameRate().ToString("F2")));
GUILayout.Label("Updates: " + _mediaPlayer.TextureProducer.GetTextureFrameCount() + " Rate: " + _mediaPlayer.Info.GetVideoDisplayRate().ToString("F1"));
GUILayout.BeginHorizontal();
// Fade option
_useFading = GUILayout.Toggle(_useFading, "Fade to Black During Loading");
// Auto play
_mediaPlayer.m_AutoStart = GUILayout.Toggle(_mediaPlayer.m_AutoStart, "Auto Play After Load");
// Looping
bool loopStatus = _mediaPlayer.m_Loop;
bool newLoopStatus = GUILayout.Toggle(loopStatus, "Loop");
if (newLoopStatus != loopStatus)
{
_mediaPlayer.m_Loop = newLoopStatus;
_mediaPlayer.Control.SetLooping(newLoopStatus);
}
GUILayout.EndHorizontal();
// Timeline scrubbing (note as use int as WebGL has float == precision issues)
int currentTime = (int)_mediaPlayer.Control.GetCurrentTimeMs();
int newTime = (int)GUILayout.HorizontalSlider(currentTime, 0f, _durationSeconds * 1000f);
Rect timeSliderRect = GUILayoutUtility.GetLastRect();
float thumbWidth = GUI.skin.horizontalSliderThumb.CalcSize(GUIContent.none).x;
// Draw buffering indication
Rect bufferingRect = timeSliderRect;
GUI.color = Color.green;
bufferingRect.xMin += thumbWidth;
bufferingRect.y = bufferingRect.yMax - 4;
bufferingRect.width -= thumbWidth * 1f;
bufferingRect.width *= _mediaPlayer.Control.GetBufferingProgress();
bufferingRect.height = 4;
GUI.DrawTexture(bufferingRect, Texture2D.whiteTexture, ScaleMode.StretchToFill);
GUI.color = Color.green;
int timeRangeCount = _mediaPlayer.Control.GetBufferedTimeRangeCount();
for (int i = 0; i < timeRangeCount; i++)
{
float startTimeMs = 0f;
float endTimeMs = 0f;
if (_mediaPlayer.Control.GetBufferedTimeRange(i, ref startTimeMs, ref endTimeMs))
{
bufferingRect.xMin = thumbWidth + timeSliderRect.x + (timeSliderRect.width - thumbWidth * 1f) * (startTimeMs / (_durationSeconds * 1000f));
bufferingRect.xMax = thumbWidth + timeSliderRect.x + (timeSliderRect.width - thumbWidth * 1f) * (endTimeMs / (_durationSeconds * 1000f));
GUI.DrawTexture(bufferingRect, Texture2D.whiteTexture, ScaleMode.StretchToFill);
}
}
GUI.color = Color.white;
// Handle possible slider move
if (newTime != currentTime)
{
_mediaPlayer.Control.Seek((float)newTime);
}
if (!_mediaPlayer.Control.IsPlaying())
{
if (GUILayout.Button("Play"))
{
_mediaPlayer.Control.Play();
}
}
else
{
if (GUILayout.Button("Pause"))
{
_mediaPlayer.Control.Pause();
}
}
// Audio tracks
GUILayout.BeginHorizontal();
int numAudioTracks = _mediaPlayer.Info.GetAudioTrackCount();
int selectedTrackIndex = _mediaPlayer.Control.GetCurrentAudioTrack();
for (int i = 0; i < numAudioTracks; i++)
{
if (i == selectedTrackIndex)
{
GUI.color = Color.green;
}
if (GUILayout.Button("Audio Track #" + (i + 1)))
{
_mediaPlayer.Control.SetAudioTrack(i);
}
GUI.color = Color.white;
}
GUILayout.EndHorizontal();
}
GUILayout.Label("Select a new file to play:");
// Display a grid of buttons containing the file names of videos to play
int newSelection = GUILayout.SelectionGrid(-1, _filenames, 3);
if (newSelection >= 0)
{
LoadVideo(System.IO.Path.Combine(_folder, _filenames[newSelection]));
}
GUILayout.Space(8f);
GUILayout.Label("Select a new stream to play:");
// Display a grid of buttons containing the file names of videos to play
int newSteam = GUILayout.SelectionGrid(-1, _streams, 1);
if (newSteam >= 0)
{
LoadVideo(_streams[newSteam], true);
}
GUILayout.Space(8f);
GUILayout.Label("Recent Events: ");
GUILayout.BeginVertical("box");
int eventIndex = 0;
foreach (string eventString in _eventLog)
{
GUI.color = Color.white;
if (eventIndex == 0)
{
GUI.color = new Color(1f, 1f, 1f, _eventTimer);
}
GUILayout.Label(eventString);
eventIndex++;
}
GUILayout.EndVertical();
GUI.color = Color.white;
GUILayout.EndVertical();
}
}
}