当前位置: 首页 > news >正文

⭐ Unity AVProVideo插件自带播放器 脚本重构 实现视频激活重置功能

一、功能概述

本笔记记录直接修改插件自带的场景播放其中 原始的 MediaPlayerUI 脚本,实现激活时自动重置播放器的功能。 我用的插件版本是 AVPro Video - Ultra Edition 2.7.3

修改后的脚本将具备以下特性:

  • 激活 GameObject 时自动重置播放位置到开头

  • 可配置是否在重置后自动开始播放

  • 可配置重置前的延迟时间

  • 视频播放结束后自动回到开头

  • 保留原始脚本所有功能

二、修改步骤

1. 添加新变量

在类变量声明区域添加以下变量:

[Header("Activation Behavior")]
[Tooltip("Reset playback to beginning when enabled")]
[SerializeField] bool _resetOnEnable = true;[Tooltip("Automatically start playback after reset")]
[SerializeField] bool _playOnReset = true;[Tooltip("Delay before resetting after enable (seconds)")]
[SerializeField] float _resetDelay = 0.1f;private Coroutine _resetCoroutine;

2. 添加 ResetPlayer 方法

在 Start() 方法后添加:

/// <summary>
/// Resets the player to beginning and optionally starts playback
/// </summary>
public void ResetPlayer()
{if (_mediaPlayer == null || _mediaPlayer.Control == null){Debug.LogWarning("MediaPlayer or Control is not available", this);return;}// Reset playback position_mediaPlayer.Control.Seek(0);// Reset audio state_audioVolume = 1f;_audioFade = 1f;_isAudioFadingUpToPlay = true;_audioFadeTime = 0f;ApplyAudioVolume();// Update UIUpdateVolumeSlider();// Start playback if configured to do soif (_playOnReset){_mediaPlayer.Play();// Trigger play feedback if overlay manager existsif (_overlayManager){_overlayManager.TriggerFeedback(OverlayManager.Feedback.Play);}}else{_mediaPlayer.Pause();}// Ensure controls are visible_controlsFade = 1f;if (_controlsGroup != null){_controlsGroup.alpha = 1f;_controlsGroup.gameObject.SetActive(true);}// Update timeline sliderif (_sliderTime != null){_sliderTime.value = 0f;}
}

3. 修改/添加 OnEnable 方法

private void OnEnable()
{if (_resetOnEnable){// Start reset coroutine with small delay to ensure everything is initializedif (_resetCoroutine != null){StopCoroutine(_resetCoroutine);}_resetCoroutine = StartCoroutine(DelayedReset());}
}

4. 添加 OnDisable 方法

private void OnDisable()
{if (_resetCoroutine != null){StopCoroutine(_resetCoroutine);_resetCoroutine = null;}
}

5. 添加 DelayedReset 协程

private IEnumerator DelayedReset()
{yield return new WaitForSeconds(_resetDelay);ResetPlayer();
}

6. 修改 Update 方法

// Check if video has finished playing
if (_mediaPlayer != null && _mediaPlayer.Control != null && _mediaPlayer.Control.IsFinished())
{// Reset to beginning but don't auto-play_mediaPlayer.Control.Seek(0);_mediaPlayer.Pause();// Update timeline sliderif (_sliderTime != null){_sliderTime.value = 0f;}
}

7. 修改 Awake 方法(可选)

void Awake()
{#if UNITY_IOSApplication.targetFrameRate = 60;#endif// 确保在第一次启用时也会重置if (_resetOnEnable && enabled && gameObject.activeInHierarchy){StartCoroutine(DelayedReset());}
}

三、使用说明

1. Inspector 配置

修改后,脚本的 Inspector 面板将显示新的配置选项:

  • Reset On Enable:是否在激活时重置

  • Play On Reset:重置后是否自动播放

  • Reset Delay:重置前的延迟时间(秒)

2. 代码调用

可以通过代码调用 ResetPlayer() 方法手动重置播放器:

GetComponent<MediaPlayerUI>().ResetPlayer();

3. 注意事项

  • 修改后的脚本保留了所有原始功能

  • 重置操作包括:播放位置、音频状态、UI 控件状态

  • 视频播放结束后会自动回到开头并暂停

四、实现原理

  1. 激活重置:通过 OnEnable 触发重置协程

  2. 延迟处理:使用 DelayedReset 协程确保组件完全初始化

  3. 完整重置ResetPlayer 方法处理所有重置逻辑

  4. 播放结束检测:在 Update 中检测播放结束状态

五、适用场景

  • 需要重复播放视频的场景

  • 视频播放器需要频繁激活/禁用的场景

  • 需要精确控制播放初始状态的场景

六、完整代码

// 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");//cyqq[Header("Activation Behavior")][Tooltip("Reset playback to beginning when enabled")][SerializeField] bool _resetOnEnable = true;[Tooltip("Automatically start playback after reset")][SerializeField] bool _playOnReset = true;[Tooltip("Delay before resetting after enable (seconds)")][SerializeField] float _resetDelay = 0.1f;private Coroutine _resetCoroutine;void Awake(){
#if UNITY_IOSApplication.targetFrameRate = 60;
#endif// 确保在第一次启用时也会重置if (_resetOnEnable && enabled &

相关文章:

  • azure web app创建分步指南
  • WPF响应式UI的基础:INotifyPropertyChanged
  • WPF的交互核心:命令系统(ICommand)
  • 工控机安装lubuntu系统
  • 跨平台浏览器集成库JxBrowser 支持 Chrome 扩展程序,高效赋能 Java 桌面应用
  • 玛哈特校平机实战指南:选型、应用痛点
  • Java String的使用续 -- StringBuilder类和StringBuffer
  • OpenCV---minAreaRect
  • Java八股-数据类型转换有哪些?类型互转会有什么问题?为什么用bigDecimal 不用double ?自动装箱和拆箱?包装类?
  • QML 滑动与翻转效果(Flickable与Flipable)
  • 随记 配置服务器的ssl整个过程
  • 华为云Flexus+DeepSeek征文 | 基于Dify和DeepSeek-R1开发企业级AI Agent全流程指南
  • Python训练营打卡Day40
  • 《系统集成项目管理工程师(第三版)》高效学习方法
  • Spring,SpringMVC,SpringBoot
  • Med-R1论文阅读理解-1
  • leetcode669.修剪二叉搜索树:递归法利用有序性精准剪枝
  • OAuth详解和应用
  • Netty 实战篇:为 Netty RPC 框架增加超时控制与重试机制,防止系统雪崩
  • 实验设计与分析(第6版,Montgomery)第5章析因设计引导5.7节思考题5.11 R语言解题
  • 做本地网站应该选什么内容/上海专业seo公司
  • 北京建设官网证书查询/搜索引擎优化是免费的吗
  • 给客户做网站建设方案/百度网址大全旧版
  • 长春模板建站公司/成都网络营销公司
  • 哪里有网站建设培训班/电话销售如何快速吸引客户
  • 安庆市住房和建设厅网站首页/市场运营和市场营销的区别