使用AVPro Video 加载视频第一秒的图片
原理:使用AVPro Video插件的MediaPlayer
mediaPlayer.OpenMedia(new MediaPath(url链接, MediaPathType.AbsolutePathOrURL), false);
然后等待一定时间
使用ExtractFrame截取视频
Texture2D texture2D = mediaPlayer.ExtractFrame(null, 1);
UI效果:
点击图片进行播放,在点击一下关闭播放
部分代码:
using RenderHeads.Media.AVProVideo;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using UnityEngine;
using UnityEngine.UI;
[SerializeField] private MediaPlayer mediaPlayer;
[SerializeField] private DisplayUGUI displayUGUI; //显示视频
//预制体 => 一个Image
[SerializeField] private GameObject VideoPlayerPre; //视频
[SerializeField] private bool LoadFinish; //所有链接都加载完成的标记
// Start is called before the first frame update
void Start()
{
Init();
}
private void Init()
{
if (mediaPlayer == null)
{
mediaPlayer = transform.Find("MediaPlayer").GetComponent<MediaPlayer>();
}
//mediaPlayer.Events.AddListener(OnMediaPlayerEvent); //事件监听
if (displayUGUI == null)
{
displayUGUI = transform.Find("VideoDisplay").GetComponent<DisplayUGUI>();
if (displayUGUI.CurrentMediaPlayer == null)
{
displayUGUI.CurrentMediaPlayer = mediaPlayer;
}
}
//按需添加, 我的需求是设备是摄像机(播放视频流)时,displayUGUI没有点击事件,设备告警(会有mp4视频链接), displayUGUI有点击事件(可以关闭,打开另一个视频)
//EventTriggerListener.Get(displayUGUI.gameObject).OnClick = (go) => CloseVideo();
}
/// <summary>
/// 加载视频第一秒图片
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private IEnumerator LoadVideo(List<string> urls)
{
yield return null; //下一帧开始处理
Debug.Log("开始执行...");
if (urls.Count == 0) yield break;
for (int i = 0; i < urls.Count; i++)
{
mediaPlayer.OpenMedia(new MediaPath(urls[i], MediaPathType.AbsolutePathOrURL), false);
//等待0.3秒,按需调整等待时间
Debug.Log("开始等待0.3秒, i = " + i);
yield return new WaitForSeconds(0.5f);
Debug.Log("结束等待0.3秒, i = " + i);
//取第一秒的图
Texture2D texture2D = mediaPlayer.ExtractFrame(null, 1);
if (texture2D == null)
{
Debug.LogWarning($"需要调整等待时间 i = {i} url = {urls[i]}"); //加载失败
continue;
}
//将视频第一秒加载到图片上
GameObject video = Instantiate<GameObject>(VideoPlayerPre);
video.SetActive(true);
video.transform.SetParent(scrollRect.content);
//需要用Image, 我尝试使用RawImage无法显示图像
video.GetComponent<Image>().sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), new Vector2(0.5f, 0.5f));
video.GetComponent<VideoUrlInfo>().videoUrl = urls[i]; //将数据保存到VideoUrlInfo组件上
//给图片添加点击事件,我这里的需求是点击后才播放视频
EventTriggerListener.Get(video).OnClick = (go) => PlayVideo(go.GetComponent<VideoUrlInfo>().videoUrl);
yield return null;
}
LoadFinish = true;
}
所有代码:
/* ======================================================================================
* 作 者:
* 主 题:
* 主要功能:
* 详细描述:
* 创建时间:2022-11-11 19:52:34
* 修改记录:
* 版 本:1.0
=======================================================================================*/
using RenderHeads.Media.AVProVideo;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using UnityEngine;
using UnityEngine.UI;
public class TestAVPro : MonoBehaviour
{
[SerializeField] private MediaPlayer mediaPlayer;
[SerializeField] private DisplayUGUI displayUGUI; //显示视频
[SerializeField] private ScrollRect scrollRect; //滚动视图
//预制体
[SerializeField] private GameObject VideoPlayerPre; //视频
[SerializeField] private bool LoadFinish; //所有链接都加载完成的标记
// Start is called before the first frame update
void Start()
{
Init();
//测试
Test();
}
/// <summary>
/// 加载视频
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
private IEnumerator LoadVideo(List<string> urls)
{
yield return null; //下一帧开始处理
Debug.Log("开始执行...");
if (urls.Count == 0) yield break;
for (int i = 0; i < urls.Count; i++)
{
mediaPlayer.OpenMedia(new MediaPath(urls[i], MediaPathType.AbsolutePathOrURL), false);
//等待0.3秒,按需调整等待时间
Debug.Log("开始等待0.3秒, i = " + i);
yield return new WaitForSeconds(0.5f);
Debug.Log("结束等待0.3秒, i = " + i);
//取第一秒的图
Texture2D texture2D = mediaPlayer.ExtractFrame(null, 1);
if (texture2D == null)
{
Debug.LogWarning($"需要调整等待时间 i = {i} url = {urls[i]}"); //加载失败
continue;
}
//将视频第一秒加载到图片上
GameObject video = Instantiate<GameObject>(VideoPlayerPre);
video.SetActive(true);
video.transform.SetParent(scrollRect.content);
//需要用Image, 我尝试使用RawImage无法显示图像
video.GetComponent<Image>().sprite = Sprite.Create(texture2D, new Rect(0, 0, texture2D.width, texture2D.height), new Vector2(0.5f, 0.5f));
video.GetComponent<VideoUrlInfo>().videoUrl = urls[i]; //将数据保存到VideoUrlInfo组件上
//给图片添加点击事件,我这里的需求是点击后才播放视频
EventTriggerListener.Get(video).OnClick = (go) => PlayVideo(go.GetComponent<VideoUrlInfo>().videoUrl);
yield return null;
}
LoadFinish = true;
}
/// <summary>
/// 图片被点击播放视频(图片是第一秒的视频)
/// </summary>
/// <param name="url"></param>
private void PlayVideo(string url)
{
if (!LoadFinish) return;
if (url.IsNullOrEmpty()) return;
displayUGUI.gameObject.SetActive(true);
mediaPlayer.OpenMedia(new MediaPath(url, MediaPathType.AbsolutePathOrURL));
}
private void Init()
{
if (mediaPlayer == null)
{
mediaPlayer = transform.Find("MediaPlayer").GetComponent<MediaPlayer>();
}
mediaPlayer.Events.AddListener(OnMediaPlayerEvent); //事件监听
if (displayUGUI == null)
{
displayUGUI = transform.Find("VideoDisplay").GetComponent<DisplayUGUI>();
if (displayUGUI.CurrentMediaPlayer == null)
{
displayUGUI.CurrentMediaPlayer = mediaPlayer;
}
}
//按需添加, 我的需求是设备是摄像机(播放视频流)时,displayUGUI没有点击事件,设备告警(会有mp4视频链接), displayUGUI有点击事件(可以关闭,打开另一个视频)
EventTriggerListener.Get(displayUGUI.gameObject).OnClick = (go) => CloseVideo();
if (scrollRect == null)
{
scrollRect = transform.Find("ScrollView").GetComponent<ScrollRect>();
}
if (VideoPlayerPre == null)
this.VideoPlayerPre = transform.Find("VideoPlayerPre").gameObject;
VideoPlayerPre.SetActive(false); //不需要显示
}
private void Test()
{
List<string> urls = new List<string>();
//网上找的测试地址
urls.Add("http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4"); //驯龙高手
urls.Add("http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4"); //紧急救援
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319222227698228.mp4"); //玩具总动员
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4"); //叶问4 先行预告甄子丹过招美
urls.Add("http://vfx.mtime.cn/Video/2019/03/18/mp4/190318231014076505.mp4"); //预告刘德华对决古天
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710171112971120.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710122716702150.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4");
//压测一下
urls.Add("http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4"); //驯龙高手
urls.Add("http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4"); //紧急救援
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319222227698228.mp4"); //玩具总动员
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4"); //叶问4 先行预告甄子丹过招美
urls.Add("http://vfx.mtime.cn/Video/2019/03/18/mp4/190318231014076505.mp4"); //预告刘德华对决古天
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710171112971120.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710122716702150.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4");
urls.Add("http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4"); //驯龙高手
urls.Add("http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4"); //紧急救援
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319222227698228.mp4"); //玩具总动员
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4"); //叶问4 先行预告甄子丹过招美
urls.Add("http://vfx.mtime.cn/Video/2019/03/18/mp4/190318231014076505.mp4"); //预告刘德华对决古天
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710171112971120.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710122716702150.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4");
urls.Add("http://vfx.mtime.cn/Video/2019/02/04/mp4/190204084208765161.mp4"); //驯龙高手
urls.Add("http://vfx.mtime.cn/Video/2019/03/21/mp4/190321153853126488.mp4"); //紧急救援
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319222227698228.mp4"); //玩具总动员
urls.Add("http://vfx.mtime.cn/Video/2019/03/19/mp4/190319212559089721.mp4"); //叶问4 先行预告甄子丹过招美
urls.Add("http://vfx.mtime.cn/Video/2019/03/18/mp4/190318231014076505.mp4"); //预告刘德华对决古天
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710171112971120.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710122716702150.mp4");
urls.Add("http://vfx.mtime.cn/Video/2021/07/10/mp4/210710095541348171.mp4");
StartCoroutine(LoadVideo(urls));
}
private void OnMediaPlayerEvent(MediaPlayer arg0, MediaPlayerEvent.EventType arg1, ErrorCode arg2)
{
switch (arg1)
{
case MediaPlayerEvent.EventType.Started: //开始播放的事件
//videoLoad = true; //已经加载完成
//quanImage.Deactivate(); //隐藏
break;
}
switch (arg2)
{
case ErrorCode.LoadFailed:
//videoTip.text = "加载出错,网络连接不稳定, 请稍后重试!!!";
//videoTip.Activate(); //显示
//videoLoad = true; //加载出错
//quanImage.Deactivate(); //隐藏
break;
case ErrorCode.DecodeFailed:
break;
}
}
/// <summary>
/// 关闭视频 displayUGUI的点击事件
/// </summary>
private void CloseVideo()
{
displayUGUI.gameObject.SetActive(false);
mediaPlayer.Stop();
}
}
UI
1.创建一个空对象并添加TestAVPro(自己写的脚本)
2.创建Scroll View
3.给Scroll View 的Content添加Grid Layout Group 和 Content Size Fitter组件,按需调整里面参数
4创建MediaPlayer和displayUGUI组件
5.关闭自动播放和自动打开6.需要改名称和脚本中对应(按照自己的来改)
7.一个工具类型,给UI添加点击事件
using UnityEngine;
using UnityEngine.EventSystems;
/// <summary>
/// UI添加点击事件
/// </summary>
public class EventTriggerListener : EventTrigger
{
public delegate void voidDelegate(GameObject obj);
public voidDelegate OnBtnDown;
public voidDelegate OnBtnUp;
public voidDelegate OnEnter;
public voidDelegate OnExit;
public voidDelegate OnStay;
public voidDelegate OnClick;
public voidDelegate OnDoubleClick;
private bool isEnter = false;
public void Update()
{
if (isEnter)
{
if (OnStay != null)
{
OnStay(gameObject);
}
}
}
public static EventTriggerListener Get(GameObject obj)
{
EventTriggerListener eventTriggerListener = obj.GetComponent<EventTriggerListener>();
if (eventTriggerListener == null)
{
eventTriggerListener = obj.AddComponent<EventTriggerListener>();
}
return eventTriggerListener;
}
/// <summary>
/// 判断是否是第二次点击
/// </summary>
private bool isTwo = true;
private bool isOver = true;
public override void OnPointerDown(PointerEventData eventData)
{
if (OnBtnDown != null)
{
OnBtnDown(gameObject);
}
isTwo = !isTwo;
if (!isOver)
{
return;
}
isOver = false;
Invoke("SelectClick", 0.3f);
}
public void SelectClick()
{
if (isTwo)
{
if (OnDoubleClick != null)
{
OnDoubleClick(gameObject);
}
}
else
{
if (OnClick != null)
{
OnClick(gameObject);
}
}
isTwo = true;
isOver = true;
}
public override void OnPointerUp(PointerEventData eventData)
{
if (OnBtnUp != null)
{
OnBtnUp(gameObject);
}
}
public override void OnPointerEnter(PointerEventData eventData)
{
if (OnEnter != null)
{
OnEnter(gameObject);
}
isEnter = true;
}
public override void OnPointerExit(PointerEventData eventData)
{
if (OnExit != null)
{
OnExit(gameObject);
}
isEnter = false;
}
}
工程地址
提取码:o93j文章来源:https://www.toymoban.com/news/detail-550305.html
插件仅供学习交流,请勿用于商业用途文章来源地址https://www.toymoban.com/news/detail-550305.html
到了这里,关于Unity AVPro Video 加载视频第一秒图片与例子的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!