Unity VideoPlayer组件视频播放功能

1、思路过程,确认方案
2、熟悉技术,了解用法
3、实操应用,解决问题
4、产品化

第一点:思路过程,确认方案

我也没做过,并且对于渲染相关也不了解,所以需要大神指路,但是前提自己也要先去了解自己所能了解到的信息

Unity应用广泛,相关需求的实现方案肯定有很多,多找几种方案让大家去评价

截图:


Unity VideoPlayer组件视频播放功能_第1张图片
image.png

根据大家的反馈,决定用Unity 5.6版本后新增的组件VIdeoPlayer

第二点:熟悉技术,了解用法

因为是官方原生组件,所以最权威文档就是Unity官方文档,一般只要百度搜Unity + 组件名就可以搜到,建议大家
在以后学习一些Unity组件时优先过一遍官方文档,我也是这次受益匪浅


Unity VideoPlayer组件视频播放功能_第2张图片
image.png

文档里会详细介绍这个API的用法,注意事项,比如:这个播放组件所支持的视频格式,这个就是很重要的信息:


image.png

第三点:实操应用,解决问题

准备:

VideoPLayer 主要用到两个组件,一个是VideoPlayer组件,二个是AudioSource组件
前者用于视频播放,后者用于声音播放

Unity VideoPlayer组件视频播放功能_第3张图片
videoplayer组件.png

介绍一下各字段:
source:代表播放源的来源,有Video Clip,URL两个选项,前者需要直接手动引用视频资源,后者的既可以在栏URL直接填链接地址,也可以在代码中指定,网络链接和本地地址皆可,这里用的就是URL源
Play On Awake:字面意思,组件激活时就直接播放
Loop:字面意思,循环播放
Playback Speed:字面意思,播放速度
Render Mode:字面意思,渲染模式,这个需要详细介绍一下,包含5个选项,

CameraFarPlane(基于摄像机的渲染,渲染在摄像机的远平面上,需要设置用于渲染的摄像机,同时可以修改alpha通道的值做透明效果,可用于背景播放器)
CameraNearPlane(基于摄像机的渲染,渲染在摄像机的近平面上,需要设置用于渲染的摄像机,同时可以修改alpha通道的值做透明效果,可用作前景播放器)
RenderTexture(渲染在RenderTexture上,可以用来做基于UGUI的播放器,这个时我们要用的)
MaterialOverride(将视频画面复制给所选Render的Material。需要选择具有Render组件的物体,可以选择赋值的材质属性。可制作360全景视频和VR视频)
APIOnly(没研究出来干嘛用的,官方文档也没提到)

AspectRatio:屏幕长宽比适应(目前发现在RenderTexture模式下不起作用,所以用了AspectRatioFitter)
AudioOutputMode:音频输出模式

None:不播放声音
AudioSource:用AudioSource播放使用
ControlledTracks:控制音轨,填需要的数量,再把对应AudioSource节点拖上去引用

本身这个组件在官网的属性字段,公共方法介绍的还是比较多的,大家有兴趣可以去看看,链接:https://docs.unity3d.com/ScriptReference/Video.VideoPlayer.html
这里给大家介绍一下常用的几个,属性字段上面已经说过了,下面介绍几个方法:

下面以vp作为已拿到的VideoPlayer组件
1.vp.Prepare()
为播放做好准备
2.vp.Play()
开始播放
3.vp.Stop()
停止播放
4.vp.prepareCompleted
视频准备完成时的执行事件
5.vp.errorReceived
播放发生错误时的执行事件
6.vp.loopPointReached
视频播放到最后时的执行事件,循环状态下,每一次循环播放到最后都会执行

执行

1.做好相关panel预设,对应节点挂好相关组件

Unity VideoPlayer组件视频播放功能_第4张图片
其他组件.png

2.拿到格式正确的视频文件
这里首先要说的是,视频文件是不能打成AB格式的,否则是没法正常播放的,所以从美术或者第三方拿到视频资源后要手动放到StreamingAssets目录下,保证打包时能被正常打包,当然不推荐每次都是手动复制,所以最好时在编包工具里动动手脚,这样美术那边更新资源也不用客户端再参与

这里遇到过的坑就是,凡人这边目前走的是编运行编解压的模式,所以刚进游戏实际视频资源还没解压出来,不过凡人这边bird有一个提前解压列表,视频文件加进去即可

3.VideoPlayer是被导出的,lua内可以直接拿到这个组件直接使用,但是这里是启动游戏时的播放,所以代码写在了凡人这边的启动流程里,上面了解了相关用法后,下面的代码就很好理顺,没复杂的逻辑:

        public static void VideoPlayerPrepare()
        {
            if (Instance.VideoPlayerNode != null)
            {
                Instance.vp = Instance.VideoPlayerNode.gameObject.GetComponent();
#if UNITY_EDITOR
                Instance.vp.url = Util.DataPath + "/Arts_fanren/CGVideo/" + "videoCG_0.mp4";
#else
                Instance.vp.url = Util.DataPath + "/" + "videoCG_0.mp4";
#endif
                Instance.vp.prepareCompleted += Instance.VideoPlayerPlay; //当视频准备好可以播放时的回调
                Instance.vp.loopPointReached += Instance.VideoPlayerEnd; //当视频放到最后时的回调
                Instance.vp.errorReceived += Instance.VideoPlayerError; //当视频播放出错时的回调
                Instance.vp.Prepare();

                if (Instance.TouchToggle != null)
                {
                    Instance.TouchToggle.onValueChanged.AddListener(delegate { Instance.TouchToggleChange(Instance.TouchToggle); });
                }

                if (Instance.SkipBtn != null)
                {
                    Instance.SkipBtn.onClick.AddListener(() => Instance.VideoSkipClick());
                }

                if (Instance.TouchToggle != null && Instance.SkipBtn != null)
                    Instance.SkipBtn.gameObject.SetActive(Instance.TouchToggle.isOn);

                Instance.VideoPlayerNode.SetActive(true);
            }

           return;
        }

        void VideoPlayerPlay(UnityEngine.Video.VideoPlayer vp)
        {
            vp.Play();
         
        }

        void VideoPlayerEnd(UnityEngine.Video.VideoPlayer vp)
        {
            DoEndThing(vp);
        }

        void VideoPlayerError(UnityEngine.Video.VideoPlayer vp, string desc)
        {
            DoEndThing(vp);
        }

        public static bool GetVideoPlayerState()
        {
            return Instance.ifPlayEnd;
        }

        void VideoSkipClick()
        {
            var vp = Instance.vp;
            DoEndThing(vp);
        }

        void DoEndThing(UnityEngine.Video.VideoPlayer vp)   //播放结束,重置状态,播放记录
        {
            vp.Stop();
            Instance.VideoPlayerNode.SetActive(false);
            Instance.ifPlayEnd = true;
            RecordVideoPlayState();
        }

        //记录已播放状态
        void RecordVideoPlayState()   //记录播放状态
        {
            string filePath = Util.DataPath + "/cghaveplayed.txt";
            if (File.Exists(filePath))
            {
                return;
            }

            string str = "yes,there is nothing!";
            System.IO.File.WriteAllText(filePath, str);
        }

        public static bool GetVideoPlayState()   //是否播放过
        {
            string filePath = Util.DataPath + "/cghaveplayed.txt";
            if (File.Exists(filePath))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        void TouchToggleChange(Toggle change)
        {
            if (Instance.TouchToggle.isOn == true)
            {
                Instance.SkipBtn.gameObject.SetActive(true);
            }
            else
            {
                Instance.SkipBtn.gameObject.SetActive(false);
            }
        }

到这里视频播放这块已经结束了,具体应用在哪个位置就看具体需求怎么提了

第四步:产品化

1.时序优化
目前视频播放是在游戏更新流程之后的,后来阿俊建议参考市面的游戏,都是一进游戏就播放视频,再看到实际游戏画面,对提高留存有一定的帮助,所以这块是要优化

2.播放视频同时后台同时解压
这是个缩短玩家等待感受很性价比的做法,主线程播放视频,其他线程去做解压,凡人这边目前是边玩边解压,所以对于其他项目如果要做视频播放的话是个不错的思路

你可能感兴趣的:(Unity VideoPlayer组件视频播放功能)