使用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); //事件監(jiān)聽
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("開始執(zhí)行...");
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秒,按需調(diào)整等待時間
Debug.Log("開始等待0.3秒, i = " + i);
yield return new WaitForSeconds(0.5f);
Debug.Log("結(jié)束等待0.3秒, i = " + i);
//取第一秒的圖
Texture2D texture2D = mediaPlayer.ExtractFrame(null, 1);
if (texture2D == null)
{
Debug.LogWarning($"需要調(diào)整等待時間 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]; //將數(shù)據(jù)保存到VideoUrlInfo組件上
//給圖片添加點擊事件,我這里的需求是點擊后才播放視頻
EventTriggerListener.Get(video).OnClick = (go) => PlayVideo(go.GetComponent<VideoUrlInfo>().videoUrl);
yield return null;
}
LoadFinish = true;
}
所有代碼:
/* ======================================================================================
* 作 者:
* 主 題:
* 主要功能:
* 詳細描述:
* 創(chuàng)建時間: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("開始執(zhí)行...");
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秒,按需調(diào)整等待時間
Debug.Log("開始等待0.3秒, i = " + i);
yield return new WaitForSeconds(0.5f);
Debug.Log("結(jié)束等待0.3秒, i = " + i);
//取第一秒的圖
Texture2D texture2D = mediaPlayer.ExtractFrame(null, 1);
if (texture2D == null)
{
Debug.LogWarning($"需要調(diào)整等待時間 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]; //將數(shù)據(jù)保存到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); //事件監(jiān)聽
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>();
//網(wǎng)上找的測試地址
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; //已經(jīng)加載完成
//quanImage.Deactivate(); //隱藏
break;
}
switch (arg2)
{
case ErrorCode.LoadFailed:
//videoTip.text = "加載出錯,網(wǎng)絡連接不穩(wěn)定, 請稍后重試!!!";
//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.創(chuàng)建一個空對象并添加TestAVPro(自己寫的腳本)
2.創(chuàng)建Scroll View
3.給Scroll View 的Content添加Grid Layout Group 和 Content Size Fitter組件,按需調(diào)整里面參數(shù)
4創(chuàng)建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文章來源:http://www.zghlxwxcb.cn/news/detail-550305.html
插件僅供學習交流,請勿用于商業(yè)用途文章來源地址http://www.zghlxwxcb.cn/news/detail-550305.html
到了這里,關于Unity AVPro Video 加載視頻第一秒圖片與例子的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!