• Unity AVPro Video 加载视频第一秒图片与例子


    使用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();
        }
        
        /// 
        /// 加载视频第一秒图片
        /// 
        /// 
        /// 
        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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    所有代码:

    /* ======================================================================================
    *      作 者:
    *      主 题:
    *      主要功能:
    
    *      详细描述:
    
    *      创建时间: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();
        }
    
        /// 
        /// 加载视频
        /// 
        /// 
        /// 
        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;
        }
    
        /// 
        /// 图片被点击播放视频(图片是第一秒的视频)
        /// 
        /// 
        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;
            }
        }
    
        /// 
        /// 关闭视频 displayUGUI的点击事件
        /// 
        private void CloseVideo()
        {
            displayUGUI.gameObject.SetActive(false);
            mediaPlayer.Stop();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199

    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;
    
    /// 
    /// UI添加点击事件
    /// 
    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;
        }
        /// 
        /// 判断是否是第二次点击
        /// 
        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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    工程地址
    提取码:o93j

    插件仅供学习交流,请勿用于商业用途

  • 相关阅读:
    ARM汇编与C言语的混合编程
    Hive笔记2(Hive 数据类型,DDL 数据定义,DML 数据操作)
    JAVA微信小程序影视交流评论小程序系统毕业设计 开题报告
    K8S常用命令
    Share| Membership in the American Society of Professionals in P
    健身用什么耳机比较好、五款适合健身房运动的耳机推荐
    class id
    vue-pdf在vue框架中的使用
    解析人工智能管理对社会生产力的发展
    获取淘宝详情api接口(获取主图desc)
  • 原文地址:https://blog.csdn.net/weixin_44238530/article/details/127813173