123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146 |
- // UnityEngine.UI was moved to a package in 2019.2.0
- // Unfortunately no way to test for this across all Unity versions yet
- // You can set up the asmdef to reference the new package, but the package doesn't
- // existing in Unity 2017 etc, and it throws an error due to missing reference
- #define AVPRO_PACKAGE_UNITYUI
- #if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.UI;
- using UnityEngine.EventSystems;
- using RenderHeads.Media.AVProVideo;
- using RenderHeads.Media.AVProVideo.Demos.UI;
- //-----------------------------------------------------------------------------
- // Copyright 2018-2021 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProVideo.Demos
- {
- public class MediaPlayerUI : MonoBehaviour
- {
- [SerializeField] MediaPlayer _mediaPlayer = null;
- [Header("Options")]
- [SerializeField] float _keyVolumeDelta = 0.05f;
- [SerializeField] float _jumpDeltaTime = 5f;
- [SerializeField] bool _showOptions = true;
- [SerializeField] bool _autoHide = true;
- [SerializeField] float _userInactiveDuration = 1.5f;
- [SerializeField] bool _useAudioFading = true;
- [Header("Keyboard Controls")]
- [SerializeField] bool _enableKeyboardControls = true;
- [SerializeField] KeyCode KeyVolumeUp = KeyCode.UpArrow;
- [SerializeField] KeyCode KeyVolumeDown = KeyCode.DownArrow;
- [SerializeField] KeyCode KeyTogglePlayPause = KeyCode.Space;
- [SerializeField] KeyCode KeyToggleMute = KeyCode.M;
- [SerializeField] KeyCode KeyJumpForward = KeyCode.RightArrow;
- [SerializeField] KeyCode KeyJumpBack = KeyCode.LeftArrow;
- [Header("Optional Components")]
- [SerializeField] OverlayManager _overlayManager = null;
- [SerializeField] MediaPlayer _thumbnailMediaPlayer = null;
- [SerializeField] RectTransform _timelineTip = null;
- [Header("UI Components")]
- [SerializeField] RectTransform _canvasTransform = null;
- //[SerializeField] Image image = null;
- [SerializeField] Slider _sliderTime = null;
- [SerializeField] EventTrigger _videoTouch = null;
- [SerializeField] CanvasGroup _controlsGroup = null;
- [Header("UI Components (Optional)")]
- [SerializeField] GameObject _liveItem = null;
- [SerializeField] Text _textMediaName = null;
- [SerializeField] Text _textTimeDuration = null;
- [SerializeField] Slider _sliderVolume = null;
- [SerializeField] Button _buttonPlayPause = null;
- [SerializeField] Button _buttonVolume = null;
- [SerializeField] Button _buttonSubtitles = null;
- [SerializeField] Button _buttonOptions = null;
- [SerializeField] Button _buttonTimeBack = null;
- [SerializeField] Button _buttonTimeForward = null;
- [SerializeField] RawImage _imageAudioSpectrum = null;
- [SerializeField] GameObject _optionsMenuRoot = null;
- [SerializeField] HorizontalSegmentsPrimitive _segmentsSeek = null;
- [SerializeField] HorizontalSegmentsPrimitive _segmentsBuffered = null;
- [SerializeField] HorizontalSegmentsPrimitive _segmentsProgress = null;
- private bool _wasPlayingBeforeTimelineDrag;
- private float _controlsFade = 1f;
- private Material _playPauseMaterial;
- private Material _volumeMaterial;
- private Material _subtitlesMaterial;
- private Material _optionsMaterial;
- private Material _audioSpectrumMaterial;
- private float[] _spectrumSamples = new float[128];
- private float[] _spectrumSamplesSmooth = new float[128];
- private float _maxValue = 1f;
- private float _audioVolume = 1f;
- private float _audioFade = 0f;
- private bool _isAudioFadingUpToPlay = true;
- private const float AudioFadeDuration = 0.25f;
- private float _audioFadeTime = 0f;
- private readonly LazyShaderProperty _propMorph = new LazyShaderProperty("_Morph");
- private readonly LazyShaderProperty _propMute = new LazyShaderProperty("_Mute");
- private readonly LazyShaderProperty _propVolume = new LazyShaderProperty("_Volume");
- private readonly LazyShaderProperty _propSpectrum = new LazyShaderProperty("_Spectrum");
- private readonly LazyShaderProperty _propSpectrumRange = new LazyShaderProperty("_SpectrumRange");
- void Awake()
- {
- #if UNITY_IOS
- Application.targetFrameRate = 60;
- #endif
- }
- void Start()
- {
- if (_mediaPlayer)
- {
- _audioVolume = _mediaPlayer.AudioVolume;
- }
- SetupPlayPauseButton();
- SetupTimeBackForwardButtons();
- SetupVolumeButton();
- SetupSubtitlesButton();
- SetupOptionsButton();
- SetupAudioSpectrum();
- CreateTimelineDragEvents();
- CreateVideoTouchEvents();
- CreateVolumeSliderEvents();
- UpdateVolumeSlider();
- BuildOptionsMenu();
- }
- private struct UserInteraction
- {
- public static float InactiveTime;
- private static Vector3 _previousMousePos;
- private static int _lastInputFrame;
- public static bool IsUserInputThisFrame()
- {
- if (Time.frameCount == _lastInputFrame)
- {
- return true;
- }
- #if (!ENABLE_INPUT_SYSTEM || ENABLE_LEGACY_INPUT_MANAGER)
- bool touchInput = (Input.touchSupported && Input.touchCount > 0);
- bool mouseInput = (Input.mousePresent && (Input.mousePosition != _previousMousePos || Input.mouseScrollDelta != Vector2.zero || Input.GetMouseButton(0)));
- if (touchInput || mouseInput)
- {
- _previousMousePos = Input.mousePosition;
- _lastInputFrame = Time.frameCount;
- return true;
- }
- return false;
- #else
- return true;
- #endif
- }
- }
- private Material DuplicateMaterialOnImage(Graphic image)
- {
- // Assign a copy of the material so we aren't modifying the material asset file
- image.material = new Material(image.material);
- return image.material;
- }
- private void SetupPlayPauseButton()
- {
- if (_buttonPlayPause)
- {
- _buttonPlayPause.onClick.AddListener(OnPlayPauseButtonPressed);
- _playPauseMaterial = DuplicateMaterialOnImage(_buttonPlayPause.GetComponent<Image>());
- }
- }
- private void SetupTimeBackForwardButtons()
- {
- if (_buttonTimeBack)
- {
- _buttonTimeBack.onClick.AddListener(OnPlayTimeBackButtonPressed);
- }
- if (_buttonTimeForward)
- {
- _buttonTimeForward.onClick.AddListener(OnPlayTimeForwardButtonPressed);
- }
- }
- private void SetupVolumeButton()
- {
- if (_buttonVolume)
- {
- _buttonVolume.onClick.AddListener(OnVolumeButtonPressed);
- _volumeMaterial = DuplicateMaterialOnImage(_buttonVolume.GetComponent<Image>());
- }
- }
- private void SetupSubtitlesButton()
- {
- if (_buttonSubtitles)
- {
- _buttonSubtitles.onClick.AddListener(OnSubtitlesButtonPressed);
- _subtitlesMaterial = DuplicateMaterialOnImage(_buttonSubtitles.GetComponent<Image>());
- }
- }
- private void SetupOptionsButton()
- {
- if (_buttonOptions)
- {
- _buttonOptions.onClick.AddListener(OnOptionsButtonPressed);
- _optionsMaterial = DuplicateMaterialOnImage(_buttonOptions.GetComponent<Image>());
- }
- }
- private void SetupAudioSpectrum()
- {
- if (_imageAudioSpectrum)
- {
- _audioSpectrumMaterial = DuplicateMaterialOnImage(_imageAudioSpectrum);
- }
- }
- private void OnPlayPauseButtonPressed()
- {
- TogglePlayPause();
- }
- private void OnPlayTimeBackButtonPressed()
- {
- SeekRelative(-_jumpDeltaTime);
- }
- private void OnPlayTimeForwardButtonPressed()
- {
- SeekRelative(_jumpDeltaTime);
- }
- private void OnVolumeButtonPressed()
- {
- ToggleMute();
- }
- private void OnSubtitlesButtonPressed()
- {
- ToggleSubtitles();
- }
- private void OnOptionsButtonPressed()
- {
- ToggleOptionsMenu();
- }
- private bool _isHoveringOverTimeline;
- private void OnTimelineBeginHover(PointerEventData eventData)
- {
- if (eventData.pointerCurrentRaycast.gameObject != null)
- {
- _isHoveringOverTimeline = true;
- _sliderTime.transform.localScale = new Vector3(1f, 2.5f, 1f);
- }
- }
- private void OnTimelineEndHover(PointerEventData eventData)
- {
- _isHoveringOverTimeline = false;
- _sliderTime.transform.localScale = new Vector3(1f, 1f, 1f);
- }
- private void CreateVideoTouchEvents()
- {
- EventTrigger.Entry entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.PointerUp;
- entry.callback.AddListener((data) => { OnVideoPointerUp(); });
- _videoTouch.triggers.Add(entry);
- }
- private void OnVideoPointerUp()
- {
- bool controlsMostlyVisible = (_controlsGroup.alpha >= 0.5f && _controlsGroup.gameObject.activeSelf);
- if (controlsMostlyVisible)
- {
- TogglePlayPause();
- }
- }
- void UpdateAudioFading()
- {
- // Increment fade timer
- if (_audioFadeTime < AudioFadeDuration)
- {
- _audioFadeTime = Mathf.Clamp(_audioFadeTime + Time.deltaTime, 0f, AudioFadeDuration);
- }
- // Trigger pause when audio faded down
- if (_audioFadeTime >= AudioFadeDuration)
- {
- if (!_isAudioFadingUpToPlay)
- {
- Pause(skipFeedback:true);
- }
- }
- // Apply audio fade value
- if (_mediaPlayer.Control != null && _mediaPlayer.Control.IsPlaying())
- {
- _audioFade = Mathf.Clamp01(_audioFadeTime / AudioFadeDuration);
- if (!_isAudioFadingUpToPlay)
- {
- _audioFade = (1f - _audioFade);
- }
- ApplyAudioVolume();
- }
- }
- public void TogglePlayPause()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- if (_useAudioFading && _mediaPlayer.Info.HasAudio())
- {
- if (_mediaPlayer.Control.IsPlaying())
- {
- if (_overlayManager)
- {
- _overlayManager.TriggerFeedback(OverlayManager.Feedback.Pause);
- }
- _isAudioFadingUpToPlay = false;
- }
- else
- {
- _isAudioFadingUpToPlay = true;
- Play();
- }
- _audioFadeTime = 0f;
- }
- else
- {
- if (_mediaPlayer.Control.IsPlaying())
- {
- Pause();
- }
- else
- {
- Play();
- }
- }
- }
- }
- private void Play()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- if (_overlayManager)
- {
- _overlayManager.TriggerFeedback(OverlayManager.Feedback.Play);
- }
- _mediaPlayer.Play();
- }
- }
- private void Pause(bool skipFeedback = false)
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- if (!skipFeedback)
- {
- if (_overlayManager)
- {
- _overlayManager.TriggerFeedback(OverlayManager.Feedback.Pause);
- }
- }
- _mediaPlayer.Pause();
- }
- }
- public void SeekRelative(float deltaTime)
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- TimeRange timelineRange = GetTimelineRange();
- double time = _mediaPlayer.Control.GetCurrentTime() + deltaTime;
- time = System.Math.Max(time, timelineRange.startTime);
- time = System.Math.Min(time, timelineRange.startTime + timelineRange.duration);
- _mediaPlayer.Control.Seek(time);
- if (_overlayManager)
- {
- _overlayManager.TriggerFeedback(deltaTime > 0f ? OverlayManager.Feedback.SeekForward : OverlayManager.Feedback.SeekBack);
- }
- }
- }
- public void ChangeAudioVolume(float delta)
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- // Change volume
- _audioVolume = Mathf.Clamp01(_audioVolume + delta);
- // Update the UI
- UpdateVolumeSlider();
- // Trigger the overlays
- if (_overlayManager)
- {
- _overlayManager.TriggerFeedback(delta > 0f ? OverlayManager.Feedback.VolumeUp : OverlayManager.Feedback.VolumeDown);
- }
- }
- }
- public void ToggleMute()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- if (_mediaPlayer.AudioMuted)
- {
- MuteAudio(false);
- }
- else
- {
- MuteAudio(true);
- }
- }
- }
- private void MuteAudio(bool mute)
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- // Change mute
- _mediaPlayer.AudioMuted = mute;
- // Update the UI
- // The UI element is constantly updated by the Update() method
- // Trigger the overlays
- if (_overlayManager)
- {
- _overlayManager.TriggerFeedback(mute ? OverlayManager.Feedback.VolumeMute : OverlayManager.Feedback.VolumeUp);
- }
- }
- }
- public void ToggleSubtitles()
- {
- if (_mediaPlayer && _mediaPlayer.TextTracks != null)
- {
- if (_mediaPlayer.TextTracks.GetTextTracks().Count > 0)
- {
- if (_mediaPlayer.TextTracks.GetActiveTextTrack() != null)
- {
- _mediaPlayer.TextTracks.SetActiveTextTrack(null);
- }
- else
- {
- // TODO: instead of activating the first one, base it on the language/track
- // selection stored in the MediaPlayerUI
- _mediaPlayer.TextTracks.SetActiveTextTrack(_mediaPlayer.TextTracks.GetTextTracks()[0]);
- }
- }
- }
- }
- private void ToggleOptionsMenu()
- {
- _showOptions = !_showOptions;
- BuildOptionsMenu();
- }
- private void BuildOptionsMenu()
- {
- if (_optionsMenuRoot)
- {
- _optionsMenuRoot.SetActive(_showOptions);
- }
- // Temporary code for now disables to touch controls while the debug menu
- // is shown, to stop it consuming mouse input for IMGUI
- _videoTouch.enabled = !_showOptions;
- }
- private void CreateTimelineDragEvents()
- {
- EventTrigger trigger = _sliderTime.gameObject.GetComponent<EventTrigger>();
- if (trigger != null)
- {
- EventTrigger.Entry entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.PointerDown;
- entry.callback.AddListener((data) => { OnTimeSliderBeginDrag(); });
- trigger.triggers.Add(entry);
- entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.Drag;
- entry.callback.AddListener((data) => { OnTimeSliderDrag(); });
- trigger.triggers.Add(entry);
- entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.PointerUp;
- entry.callback.AddListener((data) => { OnTimeSliderEndDrag(); });
- trigger.triggers.Add(entry);
- entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.PointerEnter;
- entry.callback.AddListener((data) => { OnTimelineBeginHover((PointerEventData)data); });
- trigger.triggers.Add(entry);
- entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.PointerExit;
- entry.callback.AddListener((data) => { OnTimelineEndHover((PointerEventData)data); });
- trigger.triggers.Add(entry);
- }
- }
- private void CreateVolumeSliderEvents()
- {
- if (_sliderVolume != null)
- {
- EventTrigger trigger = _sliderVolume.gameObject.GetComponent<EventTrigger>();
- if (trigger != null)
- {
- EventTrigger.Entry entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.PointerDown;
- entry.callback.AddListener((data) => { OnVolumeSliderDrag(); });
- trigger.triggers.Add(entry);
- entry = new EventTrigger.Entry();
- entry.eventID = EventTriggerType.Drag;
- entry.callback.AddListener((data) => { OnVolumeSliderDrag(); });
- trigger.triggers.Add(entry);
- }
- }
- }
- private void OnVolumeSliderDrag()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- _audioVolume = _sliderVolume.value;
- ApplyAudioVolume();
- }
- }
- private void ApplyAudioVolume()
- {
- if (_mediaPlayer)
- {
- _mediaPlayer.AudioVolume = (_audioVolume * _audioFade);
- }
- }
- private void UpdateVolumeSlider()
- {
- if (_sliderVolume)
- {
- if (_mediaPlayer)
- {
- // TODO: remove this
- /*if (mp.Control != null)
- {
- _sliderVolume.value = mp.Control.GetVolume();
- }
- else*/
- {
- _sliderVolume.value = _audioVolume;
- }
- }
- }
- }
- private void UpdateAudioSpectrum()
- {
- bool showAudioSpectrum = false;
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- AudioSource audioSource = _mediaPlayer.AudioSource;
- if (audioSource && _audioSpectrumMaterial)
- {
- showAudioSpectrum = true;
- float maxFreq = (Helper.GetUnityAudioSampleRate() / 2);
- // Frequencies over 18Khz generally aren't very interesting to visualise, so clamp the range
- const float clampFreq = 18000f;
- int sampleRange = Mathf.FloorToInt(Mathf.Clamp01(clampFreq / maxFreq) * _spectrumSamples.Length);
- // Add new samples and smooth the samples over time
- audioSource.GetSpectrumData(_spectrumSamples, 0, FFTWindow.BlackmanHarris);
- // Find the maxValue sample for normalising with
- float maxValue = -1.0f;
- for (int i = 0; i < sampleRange; i++)
- {
- if (_spectrumSamples[i] > maxValue)
- {
- maxValue = _spectrumSamples[i];
- }
- }
- // Chase maxValue to zero
- _maxValue = Mathf.Lerp(_maxValue, 0.0f, Mathf.Clamp01(2.0f * Time.deltaTime));
- // Update maxValue
- _maxValue = Mathf.Max(_maxValue, maxValue);
- if (_maxValue <= 0.01f)
- {
- _maxValue = 1f;
- }
- // Copy and smooth the spectrum values
- for (int i = 0; i < sampleRange; i++)
- {
- float newSample = _spectrumSamples[i] / _maxValue;
- _spectrumSamplesSmooth[i] = Mathf.Lerp(_spectrumSamplesSmooth[i], newSample, Mathf.Clamp01(15.0f * Time.deltaTime));
- }
- // Update shader
- _audioSpectrumMaterial.SetFloatArray(_propSpectrum.Id, _spectrumSamplesSmooth);
- _audioSpectrumMaterial.SetFloat(_propSpectrumRange.Id, (float)sampleRange);
- }
- }
- if (_imageAudioSpectrum)
- {
- _imageAudioSpectrum.gameObject.SetActive(showAudioSpectrum);
- }
- }
- private void OnTimeSliderBeginDrag()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- _wasPlayingBeforeTimelineDrag = _mediaPlayer.Control.IsPlaying();
- if (_wasPlayingBeforeTimelineDrag)
- {
- _mediaPlayer.Pause();
- }
- OnTimeSliderDrag();
- }
- }
- private void OnTimeSliderDrag()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- TimeRange timelineRange = GetTimelineRange();
- double time = timelineRange.startTime + (_sliderTime.value * timelineRange.duration);
- _mediaPlayer.Control.Seek(time);
- _isHoveringOverTimeline = true;
- }
- }
- private void OnTimeSliderEndDrag()
- {
- if (_mediaPlayer && _mediaPlayer.Control != null)
- {
- if (_wasPlayingBeforeTimelineDrag)
- {
- _mediaPlayer.Play();
- _wasPlayingBeforeTimelineDrag = false;
- }
- }
- }
- private TimeRange GetTimelineRange()
- {
- if (_mediaPlayer.Info != null)
- {
- return Helper.GetTimelineRange(_mediaPlayer.Info.GetDuration(), _mediaPlayer.Control.GetSeekableTimes());
- }
- return new TimeRange();
- }
- private bool CanHideControls()
- {
- bool result = true;
- if (!_autoHide)
- {
- result = false;
- }
- #if (!ENABLE_INPUT_SYSTEM || ENABLE_LEGACY_INPUT_MANAGER)
- else if (Input.mousePresent)
- {
- // Check whether the mouse cursor is over the controls, in which case we can't hide the UI
- RectTransform rect = _controlsGroup.GetComponent<RectTransform>();
- Vector2 canvasPos;
- RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, Input.mousePosition, null, out canvasPos);
- Rect rr = RectTransformUtility.PixelAdjustRect(rect, null);
- result = !rr.Contains(canvasPos);
- }
- #endif
- return result;
- }
- private void UpdateControlsVisibility()
- {
- if (UserInteraction.IsUserInputThisFrame() || !CanHideControls())
- {
- UserInteraction.InactiveTime = 0f;
- FadeUpControls();
- }
- else
- {
- UserInteraction.InactiveTime += Time.unscaledDeltaTime;
- if (UserInteraction.InactiveTime >= _userInactiveDuration)
- {
- FadeDownControls();
- }
- else
- {
- FadeUpControls();
- }
- }
- }
- private void FadeUpControls()
- {
- if (!_controlsGroup.gameObject.activeSelf)
- {
- _controlsGroup.gameObject.SetActive(true);
- }
- _controlsFade = Mathf.Min(1f, _controlsFade + Time.deltaTime * 8f);
- _controlsGroup.alpha = Mathf.Pow(_controlsFade, 5f);
- }
- private void FadeDownControls()
- {
- if (_controlsGroup.gameObject.activeSelf)
- {
- _controlsFade = Mathf.Max(0f, _controlsFade - Time.deltaTime * 3f);
- _controlsGroup.alpha = Mathf.Pow(_controlsFade, 5f);
- if (_controlsGroup.alpha <= 0f)
- {
- _controlsGroup.gameObject.SetActive(false);
- }
- }
- }
- void Update()
- {
- if (!_mediaPlayer) return;
- UpdateControlsVisibility();
- UpdateAudioFading();
- UpdateAudioSpectrum();
- if (_mediaPlayer.Info != null)
- {
- TimeRange timelineRange = GetTimelineRange();
- // Update timeline hover popup
- #if (!ENABLE_INPUT_SYSTEM || ENABLE_LEGACY_INPUT_MANAGER)
- if (_timelineTip != null)
- {
- if (_isHoveringOverTimeline)
- {
- Vector2 canvasPos;
- RectTransformUtility.ScreenPointToLocalPointInRectangle(_canvasTransform, Input.mousePosition, null, out canvasPos);
- _segmentsSeek.gameObject.SetActive(true);
- _timelineTip.gameObject.SetActive(true);
- Vector3 mousePos = _canvasTransform.TransformPoint(canvasPos);
- _timelineTip.position = new Vector2(mousePos.x, _timelineTip.position.y);
- if (UserInteraction.IsUserInputThisFrame())
- {
- // Work out position on the timeline
- Bounds bounds = RectTransformUtility.CalculateRelativeRectTransformBounds(this._sliderTime.GetComponent<RectTransform>());
- float x = Mathf.Clamp01((canvasPos.x - bounds.min.x) / bounds.size.x);
-
- double time = (double)x * timelineRange.Duration;
- // Seek to the new position
- if (_thumbnailMediaPlayer != null && _thumbnailMediaPlayer.Control != null)
- {
- _thumbnailMediaPlayer.Control.SeekFast(time);
- }
- // Update time text
- Text hoverText = _timelineTip.GetComponentInChildren<Text>();
- if (hoverText != null)
- {
- time -= timelineRange.startTime;
- time = System.Math.Max(time, 0.0);
- time = System.Math.Min(time, timelineRange.Duration);
- hoverText.text = Helper.GetTimeString(time, false);
- }
- {
- // Update seek segment when hovering over timeline
- if (_segmentsSeek != null)
- {
- float[] ranges = new float[2];
- if (timelineRange.Duration > 0.0)
- {
- double t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
- ranges[1] = x;
- ranges[0] = (float)t;
- }
- _segmentsSeek.Segments = ranges;
- }
- }
- }
- }
- else
- {
- _timelineTip.gameObject.SetActive(false);
- _segmentsSeek.gameObject.SetActive(false);
- }
- }
- #endif
- // Updated stalled display
- if (_overlayManager)
- {
- _overlayManager.Reset();
- if (_mediaPlayer.Info.IsPlaybackStalled())
- {
- _overlayManager.TriggerStalled();
- }
- }
- // Update keyboard input
- if (_enableKeyboardControls)
- {
- #if (!ENABLE_INPUT_SYSTEM || ENABLE_LEGACY_INPUT_MANAGER)
- // Keyboard toggle play/pause
- if (Input.GetKeyDown(KeyTogglePlayPause))
- {
- TogglePlayPause();
- }
- // Keyboard seek 5 seconds
- if (Input.GetKeyDown(KeyJumpBack))
- {
- SeekRelative(-_jumpDeltaTime);
- }
- else if (Input.GetKeyDown(KeyJumpForward))
- {
- SeekRelative(_jumpDeltaTime);
- }
- // Keyboard control volume
- if (Input.GetKeyDown(KeyVolumeUp))
- {
- ChangeAudioVolume(_keyVolumeDelta);
- }
- else if (Input.GetKeyDown(KeyVolumeDown))
- {
- ChangeAudioVolume(-_keyVolumeDelta);
- }
- // Keyboard toggle mute
- if (Input.GetKeyDown(KeyToggleMute))
- {
- ToggleMute();
- }
- #endif
- }
- // Animation play/pause button
- if (_playPauseMaterial != null)
- {
- float t = _playPauseMaterial.GetFloat(_propMorph.Id);
- float d = 1f;
- if (_mediaPlayer.Control.IsPlaying())
- {
- d = -1f;
- }
- t += d * Time.deltaTime * 6f;
- t = Mathf.Clamp01(t);
- _playPauseMaterial.SetFloat(_propMorph.Id, t);
- }
- // Animation volume/mute button
- if (_volumeMaterial != null)
- {
- float t = _volumeMaterial.GetFloat(_propMute.Id);
- float d = 1f;
- if (!_mediaPlayer.AudioMuted)
- {
- d = -1f;
- }
- t += d * Time.deltaTime * 6f;
- t = Mathf.Clamp01(t);
- _volumeMaterial.SetFloat(_propMute.Id, t);
- _volumeMaterial.SetFloat(_propVolume.Id, _audioVolume);
- }
- // Animation subtitles button
- if (_subtitlesMaterial)
- {
- float t = _subtitlesMaterial.GetFloat(_propMorph.Id);
- float d = 1f;
- if (_mediaPlayer.TextTracks.GetActiveTextTrack() == null)
- {
- d = -1f;
- }
- t += d * Time.deltaTime * 6f;
- t = Mathf.Clamp01(t);
- _subtitlesMaterial.SetFloat(_propMorph.Id, t);
- }
- // Animation options button
- if (_optionsMaterial)
- {
- float t = _optionsMaterial.GetFloat(_propMorph.Id);
- float d = 1f;
- if (!_showOptions)
- {
- d = -1f;
- }
- t += d * Time.deltaTime * 6f;
- t = Mathf.Clamp01(t);
- _optionsMaterial.SetFloat(_propMorph.Id, t);
- }
- // Update time/duration text display
- if (_textTimeDuration)
- {
- string t1 = Helper.GetTimeString((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime), false);
- string d1 = Helper.GetTimeString(timelineRange.duration, false);
- _textTimeDuration.text = string.Format("{0} / {1}", t1, d1);
- }
- // Update volume slider
- if (!_useAudioFading)
- {
- UpdateVolumeSlider();
- }
- // Update time slider position
- if (_sliderTime && !_isHoveringOverTimeline)
- {
- double t = 0.0;
- if (timelineRange.duration > 0.0)
- {
- t = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
- }
- _sliderTime.value = Mathf.Clamp01((float)t);
- }
- // Update LIVE text visible
- if (_liveItem)
- {
- _liveItem.SetActive(double.IsInfinity(_mediaPlayer.Info.GetDuration()));
- }
- // Update subtitle button visible
- if (_buttonSubtitles)
- {
- _buttonSubtitles.gameObject.SetActive(_mediaPlayer.TextTracks.GetTextTracks().Count > 0);
- }
- // Update media name
- if (_textMediaName)
- {
- #if MEDIA_NAME
- string mediaName = string.Empty;
- if (!string.IsNullOrEmpty(_mediaPlayer.VideoPath))
- {
- mediaName = System.IO.Path.GetFileName(_mediaPlayer.VideoPath);
- if (mediaName.Length > 26)
- {
- mediaName = mediaName.Substring(0, 26);
- }
- }
- #endif
- string resolutionName = string.Empty;
- if (_mediaPlayer.Info.GetVideoWidth() > 0)
- {
- resolutionName = Helper.GetFriendlyResolutionName(_mediaPlayer.Info.GetVideoWidth(), _mediaPlayer.Info.GetVideoHeight(), _mediaPlayer.Info.GetVideoFrameRate());
- }
- #if MEDIA_NAME
- _textMediaName.text = string.Format("{0} {1}", mediaName, resolutionName);
- #else
- _textMediaName.text = resolutionName;
- #endif
- }
- // Update buffered segments
- if (_segmentsBuffered)
- {
- TimeRanges times = _mediaPlayer.Control.GetBufferedTimes();
- float[] ranges = null;
- if (times.Count > 0 && timelineRange.duration > 0.0)
- {
- ranges = new float[times.Count * 2];
- for (int i = 0; i < times.Count; i++)
- {
- ranges[i * 2 + 0] = Mathf.Max(0f, (float)((times[i].StartTime - timelineRange.startTime) / timelineRange.duration));
- ranges[i * 2 + 1] = Mathf.Min(1f,(float)((times[i].EndTime - timelineRange.startTime) / timelineRange.duration));
- }
- }
- _segmentsBuffered.Segments = ranges;
- }
- // Update progress segment
- if (_segmentsProgress)
- {
- TimeRanges times = _mediaPlayer.Control.GetBufferedTimes();
- float[] ranges = null;
- if (times.Count > 0 && timelineRange.Duration > 0.0)
- {
- ranges = new float[2];
- double x1 = (times.MinTime - timelineRange.startTime) / timelineRange.duration;
- double x2 = ((_mediaPlayer.Control.GetCurrentTime() - timelineRange.startTime) / timelineRange.duration);
- ranges[0] = Mathf.Max(0f, (float)x1);
- ranges[1] = Mathf.Min(1f, (float)x2);
- }
- _segmentsProgress.Segments = ranges;
- }
- }
- }
- void OnGUI()
- {
- // NOTE: These this IMGUI is just temporary until we implement the UI using uGUI
- if (!_showOptions) return;
- if (!_mediaPlayer || _mediaPlayer.Control == null) return;
- GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(2f, 2f, 1f));
- GUI.backgroundColor = Color.red;
- GUILayout.BeginVertical(GUI.skin.box);
- GUI.backgroundColor = Color.white;
- GUILayout.Label("Duration " + _mediaPlayer.Info.GetDuration() + "s");
- GUILayout.BeginHorizontal();
- GUILayout.Label("States: ");
- GUILayout.Toggle(_mediaPlayer.Control.HasMetaData(), "HasMetaData", GUI.skin.button);
- GUILayout.Toggle(_mediaPlayer.Control.IsPaused(), "Paused", GUI.skin.button);
- GUILayout.Toggle(_mediaPlayer.Control.IsPlaying(), "Playing", GUI.skin.button);
- GUILayout.Toggle(_mediaPlayer.Control.IsBuffering(), "Buffering", GUI.skin.button);
- GUILayout.Toggle(_mediaPlayer.Control.IsSeeking(), "Seeking", GUI.skin.button);
- GUILayout.Toggle(_mediaPlayer.Control.IsFinished(), "Finished", GUI.skin.button);
- GUILayout.EndHorizontal();
- {
- TimeRanges times = _mediaPlayer.Control.GetBufferedTimes();
- if (times != null)
- {
- GUILayout.Label("Buffered Range " + times.MinTime + " - " + times.MaxTime);
- }
- }
- {
- TimeRanges times = _mediaPlayer.Control.GetSeekableTimes();
- if (times != null)
- {
- GUILayout.Label("Seek Range " + times.MinTime + " - " + times.MaxTime);
- }
- }
- {
- GUILayout.Label("Video Tracks: " + _mediaPlayer.VideoTracks.GetVideoTracks().Count);
- GUILayout.BeginVertical();
- VideoTrack selectedTrack = null;
- foreach (VideoTrack track in _mediaPlayer.VideoTracks.GetVideoTracks())
- {
- bool isSelected = (track == _mediaPlayer.VideoTracks.GetActiveVideoTrack());
- if (isSelected) GUI.color= Color.green;
- if (GUILayout.Button(track.DisplayName, GUILayout.ExpandWidth(false)))
- {
- selectedTrack = track;
- }
- if (isSelected) GUI.color= Color.white;
- }
- GUILayout.EndHorizontal();
- if (selectedTrack != null)
- {
- _mediaPlayer.VideoTracks.SetActiveVideoTrack(selectedTrack);
- }
- }
- {
- GUILayout.Label("Audio Tracks: " + _mediaPlayer.AudioTracks.GetAudioTracks().Count);
- GUILayout.BeginVertical();
- AudioTrack selectedTrack = null;
- foreach (AudioTrack track in _mediaPlayer.AudioTracks.GetAudioTracks())
- {
- bool isSelected = (track == _mediaPlayer.AudioTracks.GetActiveAudioTrack());
- if (isSelected) GUI.color= Color.green;
- if (GUILayout.Button(track.DisplayName, GUILayout.ExpandWidth(false)))
- {
- selectedTrack = track;
- }
- if (isSelected) GUI.color= Color.white;
- }
- GUILayout.EndHorizontal();
- if (selectedTrack != null)
- {
- _mediaPlayer.AudioTracks.SetActiveAudioTrack(selectedTrack);
- }
- }
- {
- GUILayout.Label("Text Tracks: " + _mediaPlayer.TextTracks.GetTextTracks().Count);
- GUILayout.BeginVertical();
- TextTrack selectedTrack = null;
- foreach (TextTrack track in _mediaPlayer.TextTracks.GetTextTracks())
- {
- bool isSelected = (track == _mediaPlayer.TextTracks.GetActiveTextTrack());
- if (isSelected) GUI.color= Color.green;
- if (GUILayout.Button(track.DisplayName, GUILayout.ExpandWidth(false)))
- {
- selectedTrack = track;
- }
- if (isSelected) GUI.color= Color.white;
- }
- GUILayout.EndHorizontal();
- if (selectedTrack != null)
- {
- _mediaPlayer.TextTracks.SetActiveTextTrack(selectedTrack);
- }
- }
- {
- GUILayout.Label("FPS: " + _mediaPlayer.Info.GetVideoDisplayRate().ToString("F2"));
- }
- #if (UNITY_STANDALONE_WIN)
- if (_mediaPlayer.PlatformOptionsWindows.bufferedFrameSelection != BufferedFrameSelectionMode.None)
- {
- IBufferedDisplay bufferedDisplay = _mediaPlayer.BufferedDisplay;
- if (bufferedDisplay != null)
- {
- BufferedFramesState state = bufferedDisplay.GetBufferedFramesState();
- GUILayout.BeginHorizontal();
- GUILayout.Label("Buffered Frames: " + state.bufferedFrameCount);
- GUILayout.HorizontalSlider(state.bufferedFrameCount, 0f, 12f);
- GUILayout.EndHorizontal();
- GUILayout.BeginHorizontal();
- GUILayout.Label("Free Frames: " + state.freeFrameCount);
- GUILayout.HorizontalSlider(state.freeFrameCount, 0f, 12f);
- GUILayout.EndHorizontal();
- GUILayout.Label("Min Timstamp: " + state.minTimeStamp);
- GUILayout.Label("Max Timstamp: " + state.maxTimeStamp);
- GUILayout.Label("Display Timstamp: " + _mediaPlayer.TextureProducer.GetTextureTimeStamp());
- }
- }
- #endif
- GUILayout.EndVertical();
- }
- }
- }
- #endif
|