⭐ 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 控件状态
-
视频播放结束后会自动回到开头并暂停
四、实现原理
-
激活重置:通过
OnEnable
触发重置协程 -
延迟处理:使用
DelayedReset
协程确保组件完全初始化 -
完整重置:
ResetPlayer
方法处理所有重置逻辑 -
播放结束检测:在
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 &
相关文章:

⭐ Unity AVProVideo插件自带播放器 脚本重构 实现视频激活重置功能
一、功能概述 本笔记记录直接修改插件自带的场景播放其中 原始的 MediaPlayerUI 脚本,实现激活时自动重置播放器的功能。 我用的插件版本是 AVPro Video - Ultra Edition 2.7.3 修改后的脚本将具备以下特性: 激活 GameObject 时自动重置播放位置到开头 可配置是否在重置后自…...
互联网大厂Java求职面试:云原生微服务架构设计与AI大模型集成实战
互联网大厂Java求职面试:云原生微服务架构设计与AI大模型集成实战 面试场景设定 人物设定: 李明(技术总监):拥有15年分布式系统架构经验,主导过多个亿级用户系统的重构,对云原生和AI融合有深…...

详解K8s API Server 如何处理请求的?
详解K8s API Server 如何处理请求的? Kubernetes(K8s)是一个强大的容器编排系统,而API Server(kube-apiserver) 是它的核心组件之一。 如果把 K8s 比作一个国家,API Server 就是政府机构,所有资源的创建、修改、删除都要经过它审批! 🎯 API Server 的作用 📌 A…...

微调数据处理
1. 数据爬取 我们将爬取的1G文件都保存到all_m_files目录下 查看原始数据文件数量: find /root/all_m_files -type f | wc -l 2. 数据预处理 仅保留UTF-8 格式文件,且所有保留的代码文件长度必须大于20行 import os import pandas as pddef try_read…...
✨1.1.1 按位与运算替代求余运算优化场景
在计算机编程中,使用按位与运算(&)替代求余运算(%)可以提高效率的特殊场景是:当除数是 2 的整数次幂(即 ( b 2^n ),其中 ( n ) 为自然数)时。例如,( b …...

解决开发者技能差距:AI 在提升效率与技能培养中的作用
企业在开发者人才方面正面临双重挑战。一方面,IDC 预测,到2025年,全球全职开发者将短缺400万人;另一方面,一些行业巨头已暂停开发者招聘,转而倚重人工智能(AI)来满足开发需求。这不禁…...

XCTF-web-easyphp
解析 第一个条件( k e y 1 ): i s s e t ( key1):isset( key1):isset(a) && intval(KaTeX parse error: Expected EOF, got & at position 14: a) > 6000000 &̲& strl…...

Transformer 通关秘籍11:Word2Vec 及工具的使用
将文字文本转换为词向量(word embedding)的过程中,一个非常著名的算法模型应该就是 Word2Vec 了。 相信大家或多或少都听说过,本节就来简单介绍一下 Word2Vec 。 什么是 Word2Vec ? Word2Vec 可以非常有效的创建词嵌入向量&…...

【DAY34】GPU训练及类的call方法
内容来自浙大疏锦行python打卡训练营 浙大疏锦行 知识点: CPU性能的查看:看架构代际、核心数、线程数GPU性能的查看:看显存、看级别、看架构代际GPU训练的方法:数据和模型移动到GPU device上类的call方法:为什么定义前…...

Flutte ListView 列表组件
目录 1、垂直列表 1.1 实现用户中心的垂直列表 2、垂直图文列表 2.1 动态配置列表 2.2 for循环生成一个动态列表 2.3 ListView.builder配置列表 列表布局是我们项目开发中最常用的一种布局方式。Flutter中我们可以通过ListView来定义列表项,支持垂直和水平方向展示…...

muduo库的初步认识和基本使用,创建一个简单查询单词服务系统
小编在学习完muduo库之后,觉得对于初学者,muduo库还是有点不好理解,所以在此,小编来告诉大家muduo库的初步认识和基本使用,让初学者也可以更快的上手和使用muduo库。 Muduo由陈硕大佬开发,是⼀个基于 非阻塞…...
电脑如何保养才能用得更久
在这个数字化的时代,电脑已经成为了我们生活和工作中不可或缺的伙伴。无论是处理工作文档、追剧娱乐,还是进行创意设计,电脑都发挥着至关重要的作用。那么,如何让我们的电脑“健康长寿”,陪伴我们更久呢?今…...
Oracle的NVL函数
Oracle的NVL函数是一个常用的空值处理函数,主要用于在查询结果中将NULL值替换为指定的默认值。以下是关于NVL函数的详细说明: 基本语法 NVL(expr1, expr2) 如果expr1为NULL,则返回expr2如果expr1不为NULL,则返回expr1本身 …...

【HTML/CSS面经】
HTML/CSS面经 HTML1. script标签中的async和defer的区别2. H5新特性(1 标签语义化(2 表单功能增强(3 音频和视频标签(4 canvas和svg绘画(5 地理位置获取(6 元素拖动API(7 Web Worker(…...

git查看commit属于那个tag
1. 快速确认commit原始分支及合入tag # git describe 213b4b3bbef2771f7a1b8166f6e6989442ca67c8 查看commit合入tag # git describe 213b4b3bbef2771f7a1b8166f6e6989442ca67c8 --all 查看commit原始分支 2.查看分支与master关系 # git show --all 0.5.67_0006 --stat 以缩…...
如何从ISO镜像直接制作Docker容器基础镜像
引言 这段最值得总结的经验知识,就是如何在ISO镜像的基础上,直接做出docker base image,无需联网! 特别地,对于一些老旧OS系统,都能依此做出docker base image! 例如,某些老旧系统,CentOS 6,…...
网站缓存入门与实战:浏览器与Nginx/Apache服务器端缓存,让网站速度起飞!(2025)
更多服务器知识,尽在hostol.com 嘿,各位站长和网站管理员朋友们!咱们精心打造的网站,内容再好,设计再炫,如果用户打开它的时候,加载速度慢得像“老牛拉破车”,那体验可就大打折扣了…...

mysql-mysql源码本地调试
前言 先进行mysql源码本地编译:mysql源码本地编译 1.本地调试 这里以macbook为例 1.使用vscode打开mysql源码 2.创建basedir目录、数据目录、配置文件目录、配置文件 cd /Users/test/ mkdir mysqldir //创建数据目录和配置目录 cd mysqldir mkdir conf data …...

PCIe— Legacy PCI
Legacy Model 该器件通过将其引脚置位到控制器来生成中断。 在较旧的系统中,这个控制 器通常是Intel 8259 PIC,有15个IRQ输入和一个INTR输出。 然后,PIC将断 言INTR以通知CPU一个或多个中断正在挂起。 一旦CPU检测到INTR的断言…...

PostgreSQL数据库配置SSL操作说明书
背景: 因为postgresql或者mysql目前通过docker安装,只需要输入主机IP、用户名、密码即可访问成功,这样其实是不安全的,可能会通过一些手段获取到用户名密码导致数据被窃取。而ES、kafka等也是通过用户名/密码方式连接,…...
MySQL 的 super_read_only 和 read_only 参数
MySQL 的 super_read_only 和 read_only 参数 一、参数基本概念 1. read_only 参数 作用:控制普通用户是否只能读取数据影响范围:所有非SUPER权限的用户默认值:OFF(可读写) 2. super_read_only 参数 作用…...

低碳理念在道路工程中的应用-预制路面
一、引子 在上一篇文章里,给大家介绍了预制基层的应用,有人提出,既然基层能够预制,那么,道路面层能不能预制呢,有没有相关的研究成果和应用实例呢?答案是肯定的,在本篇文章中&#x…...

12-后端Web实战(登录认证)
在前面的课程中,我们已经实现了部门管理、员工管理的基本功能,但是大家会发现,我们并没有登录,就直接访问到了Tlias智能学习辅助系统的后台。 这是不安全的,所以我们今天的主题就是登录认证。最终要实现的效果是&#…...
TIDB创建索引失败 mkdir /tmp/tidb/tmp_ddl-4000/1370: no such file or directory.
TIDB创建索引失败:解决“mkdir /tmp/tidb/tmp_ddl-4000/1370: no such file or directory”问题 在使用 TIDB 数据库时,我们有时会遇到创建索引失败的问题。常见的错误信息为: mkdir /tmp/tidb/tmp_ddl-4000/1370: no such file or directo…...
Redis 插入中文乱码键
Java 代码: Bean// 静态代理模式: Redis 客户端代理类增强public StringRedisTemplateProxy stringRedisTemplateProxy(RedisKeySerializer redisKeySerializer,StringRedisTemplate stringRedisTemplate,RedissonClient redissonClient) {stringRedisTemplate.setK…...
Mac OS 使用说明
Mac 的启动组合键 了解可通过在启动时按住一个或多个按键来访问的 Mac 功能和工具。 若要使用这些组合键中的任何一个,请在按下电源按钮以开启 Mac 后或在 Mac 开始重新启动后,立即按住相应按键。请一直按住,直至电脑出现对应的行为。 !!!上…...

4.2.2 Spark SQL 默认数据源
在本实战概述中,我们探讨了如何在 Spark SQL 中使用 Parquet 格式作为默认数据源。首先,我们了解了 Parquet 文件的存储特性,包括其二进制存储方式和内嵌的 Schema 信息。接着,通过一系列命令,我们演示了如何在 HDFS 上…...

234. Palindrome Linked List
目录 一、题目描述 方法一、使用栈 方法二、将链表全部结点值复制到数组,再用双指针法 方法三、递归法逆序遍历链表 方法四、快慢指针反转链表 一、题目描述 234. Palindrome Linked List 方法一、使用栈 需要遍历两次。时间复杂度O(n),空间复杂度…...
广州邮科高频开关电源:以创新科技赋能通信能源绿色未来
在数字化浪潮席卷全球的当下,通信网络作为信息社会的基石,其稳定运行对电源系统的可靠性、效率及智能化水平提出了更高要求。作为国内通信电源领域的领军企业,广州邮科凭借其自主研发的高频开关电源技术,以高效节能、智能管控、绿…...
day41 python图像识别任务
目录 一、数据预处理:为模型打下坚实基础 二、模型构建:多层感知机的实现 三、训练过程:迭代优化与性能评估 四、测试结果:模型性能的最终检验 五、总结与展望 在深度学习的旅程中,多层感知机(MLP&…...