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演示场景,很容易使用,基本功能都已封装好,直接使用就行。以下是我将它封装好的功能写成一个单列。
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.

© 版权声明
免责声明:本站所有资源由用户自发上传,仅供学习交流,如有侵犯您的权益,请联系站长删除;
All resources on this site are free and are only for learning and exchange. If any of them infringe upon your rights and interests, please contact the webmaster for deletion
THE END






![[UE人物模型]F2 Modern Girl Riley现代女孩莱利-盘古CG网](http://pangucg.com/wp-content/uploads/2025/06/微信截图_20250617134240.jpg)






暂无评论内容