c# AVPro Video - Ultra Edition官方插件使用介绍
AvproVideo,官网中有免费的,免费的带了水印。不介意水印去下载,挺好使的。收费的在Unity商店中能找到:(这里我从淘宝上花“重金”买了一个玩玩)以前都是用的AvPro免费版的,1点几那种版本的,也挺好使,相对这个来说,这个就是某东版本的,那个是拼夕夕版本的。
常用API
获取MediaPlayer组件,使用代码如下:
MediaPlayer meida;
//播放
media.Control.Play();
//暂停
media.Control.Pause();
//停止
media.Control.Stop();
//重播
media.Control.Rewind();
//设置播放链接AbsolutePathOrURL是Url的形式,可以选择文件夹的形式,设置对应文件夹属性即可
media.OpenMedia(MediaPathType.AbsolutePathOrURL,"视频链接",true);
//StreamingAssets文件目录下的视频地址
media.OpenMedia(MediaPathType.RelativeToStreamingAssetsFolder,"视频名称",true);
//事件监听
media.Events.AddListener(OnVideoEvent);
private void OnVideoEvent(MediaPlayer arg0, MediaPlayerEvent.EventType arg1, ErrorCode arg2)
{
switch (arg1)
{
case MediaPlayerEvent.EventType.MetaDataReady:
break;
case MediaPlayerEvent.EventType.ReadyToPlay:
break;
case MediaPlayerEvent.EventType.Started:
break;
case MediaPlayerEvent.EventType.FirstFrameReady:
break;
case MediaPlayerEvent.EventType.FinishedPlaying:
print("无循环状态下播放完成");
break;
case MediaPlayerEvent.EventType.Closing:
print(".Closing...");
break;
case MediaPlayerEvent.EventType.Error:
print(".Error...");
break;
case MediaPlayerEvent.EventType.SubtitleChange:
break;
case MediaPlayerEvent.EventType.Stalled:
break;
case MediaPlayerEvent.EventType.Unstalled:
break;
case MediaPlayerEvent.EventType.ResolutionChanged:
break;
case MediaPlayerEvent.EventType.StartedSeeking:
break;
case MediaPlayerEvent.EventType.FinishedSeeking:
print("循环设置状态下播放结束...");
break;
case MediaPlayerEvent.EventType.StartedBuffering:
break;
case MediaPlayerEvent.EventType.FinishedBuffering:
break;
case MediaPlayerEvent.EventType.PropertiesChanged:
break;
case MediaPlayerEvent.EventType.PlaylistItemChanged:
break;
case MediaPlayerEvent.EventType.PlaylistFinished:
break;
case MediaPlayerEvent.EventType.TextTracksChanged:
break;
//case MediaPlayerEvent.EventType.TextCueChanged://=> SubtitleChange
// break;
default:
break;
}
}
Demo源码
该插件有很详细的demo演示场景,很容易使用,基本功能都已封装好,直接使用就行。以下是我将它封装好的功能写成一个单列。文章来源:https://www.toymoban.com/news/detail-697823.html
using RenderHeads.Media.AVProVideo.Demos.UI;
using RenderHeads.Media.AVProVideo;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
namespace Demo
{
public class MediaManager : MonoBehaviour
{
public static MediaManager m_Ins;
[SerializeField] MediaPlayer _mediaPlayer = null;
[Header("Options")]
[SerializeField] float _keyVolumeDelta = 0.05f;
[SerializeField] float _jumpDeltaTime = 5f;
[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] 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 _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()
{
m_Ins = this;
#if UNITY_IOS
Application.targetFrameRate = 60;
#endif
}
void Start()
{
if (_mediaPlayer)
{
_audioVolume = _mediaPlayer.AudioVolume;
}
SetupPlayPauseButton();
SetupTimeBackForwardButtons();
SetupVolumeButton();
SetupSubtitlesButton();
SetupAudioSpectrum();
CreateTimelineDragEvents();
CreateVideoTouchEvents();
CreateVolumeSliderEvents();
UpdateVolumeSlider();
}
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;
}
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;
}
}
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>());
}
}
/// <summary>
/// 视频播放链接设置
/// </summary>
/// <param name="url"></param>
public void SetMediaUrl(string url, MediaPathType type = MediaPathType.AbsolutePathOrURL)
{
#if UNITY_EDITOR || UNITY_WIN
_mediaPlayer.OpenMedia(type, url, true);
#elif UNITY_ANDROID
_mediaPlayer.OpenMedia(type, url, true);
#endif
}
public MediaPlayer GetMediaPlayer { get {
return _mediaPlayer;
}
}
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 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 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();
}
}
}
}
public void Play()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (_overlayManager)
{
_overlayManager.TriggerFeedback(OverlayManager.Feedback.Play);
}
_mediaPlayer.Play();
}
}
public void Pause(bool skipFeedback = false)
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (!skipFeedback)
{
if (_overlayManager)
{
_overlayManager.TriggerFeedback(OverlayManager.Feedback.Pause);
}
}
_mediaPlayer.Pause();
}
}
public void Stop()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
_mediaPlayer.Stop();
_mediaPlayer.CloseMedia();
}
}
public void Rewind()
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
if (_overlayManager)
{
_overlayManager.TriggerFeedback(OverlayManager.Feedback.Play);
}
_mediaPlayer.Rewind(true);
_mediaPlayer.Play();
}
}
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.Control.IsMuted())
{
MuteAudio(false);
}
else
{
MuteAudio(true);
}
}
}
public void MuteAudio(bool mute)
{
if (_mediaPlayer && _mediaPlayer.Control != null)
{
// Change mute
_mediaPlayer.Control.MuteAudio(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 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;
}
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);
}
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 (_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);
}
}
// Updated stalled display
if (_overlayManager)
{
_overlayManager.Reset();
if (_mediaPlayer.Info.IsPlaybackStalled())
{
_overlayManager.TriggerStalled();
}
}
// Update keyboard input
if (_enableKeyboardControls)
{
// 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();
}
}
// 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.Control.IsMuted())
{
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);
}
// 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)
{
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;
}
}
}
#region GUI 显示一大堆几乎没用的
// void OnGUI()
// {
// // NOTE: These this IMGUI is just temporary until we implement the UI using uGUI
// 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();
// }
#endregion
}
}
调用
void Start()
{
MediaManager.m_Ins.SetMediaUrl("AVProVideoSamples/BigBuckBunny-360p30-H264.mp4",MediaPathType.RelativeToStreamingAssetsFolder);
MediaManager.m_Ins.GetMediaPlayer.Events.AddListener(OnVideoEvent);
//播放
// MediaManager.m_Ins.Play();
//暂停
// MediaManager.m_Ins.Pause();
}
private void OnVideoEvent(MediaPlayer arg0, MediaPlayerEvent.EventType arg1, ErrorCode arg2)
{
switch (arg1)
{
case MediaPlayerEvent.EventType.MetaDataReady:
break;
case MediaPlayerEvent.EventType.ReadyToPlay:
break;
case MediaPlayerEvent.EventType.Started:
break;
case MediaPlayerEvent.EventType.FirstFrameReady:
break;
case MediaPlayerEvent.EventType.FinishedPlaying:
break;
case MediaPlayerEvent.EventType.Closing:
print(".Closing...");
break;
case MediaPlayerEvent.EventType.Error:
print(".Error...");
break;
case MediaPlayerEvent.EventType.SubtitleChange:
break;
case MediaPlayerEvent.EventType.Stalled:
break;
case MediaPlayerEvent.EventType.Unstalled:
break;
case MediaPlayerEvent.EventType.ResolutionChanged:
break;
case MediaPlayerEvent.EventType.StartedSeeking:
break;
case MediaPlayerEvent.EventType.FinishedSeeking:
print("播放结束...");
break;
case MediaPlayerEvent.EventType.StartedBuffering:
break;
case MediaPlayerEvent.EventType.FinishedBuffering:
break;
case MediaPlayerEvent.EventType.PropertiesChanged:
break;
case MediaPlayerEvent.EventType.PlaylistItemChanged:
break;
case MediaPlayerEvent.EventType.PlaylistFinished:
break;
case MediaPlayerEvent.EventType.TextTracksChanged:
break;
//case MediaPlayerEvent.EventType.TextCueChanged://=> SubtitleChange
// break;
default:
break;
}
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
MediaManager.m_Ins.SetMediaUrl("AVProVideoSamples/RenderHeads-1080p30-H264.mp4", MediaPathType.RelativeToStreamingAssetsFolder);
}
if (Input.GetKeyDown(KeyCode.A))
{
MediaManager.m_Ins.Stop();
}
if (Input.GetKeyDown(KeyCode.S))
{
MediaManager.m_Ins.Rewind();
}
}
结语
相对Unity自带的VideoPlayer,我更喜欢用这个,功能更齐全,主要是好使,某些平台更好使。
注意这个收费插件在安卓下使用需要在PlayerSettings => OtherSettings =>Rendering =>AutoGraphicsAPI需要取消掉,然后GraphicsAPIS设置OpenGL2或者3.
源码地址:文章来源地址https://www.toymoban.com/news/detail-697823.html
到了这里,关于Unity播放器插件-AVPro Video - Ultra Edition介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!