unity中怎样实现调整视频播放速度的功能?( 二 )

————————————————原方案——————————————————————问题已解决,虽然解决方式坑了点,但好歹可以实现了。还在寻找更好的解决方案(??????) ?思路:把视频文件放到Pr里面切成序列帧(要和原视频的速度一致,比如原视频是每秒60帧,那么切的时候也要每秒切60张图片出来。如果切的时候只切每秒24帧,那么慢放视频的时候就有卡顿的视觉效果,不好不好)——\u0026gt;把序列帧用assetbundle的方法打包——\u0026gt;用的时候就架好相机正对着一个面片——\u0026gt;解读这个资源包,把打包好的图片按顺序贴到面片上——\u0026gt;通过改变timeScale来改变贴图的速度,假装改变视频播放的速度——\u0026gt;为其他东西写不受timeScale改变的代码(比如动画)——\u0026gt;再设置一下引擎每秒渲染多少次(如果快播,每秒实际贴图100次,那把这100帧都渲染出来完全没必要。为了性能考虑,不论视频是快播还是慢播,就固定unity每秒渲染30次)。——————————————上部分代码———————————————————————1.视频播放控制的代码:资源包名为00,01,02...包里面的图片名为00000,000001,000002...using UnityEngine;using System.Collections;public class VideoPlayer : MonoBehaviour {\t// 控制器将传来的信息\tDtoVideo _dtoVideo =null;// 视频源信息\tpublic DtoVideo dtoVideo\t{\t\tget { return this._dtoVideo;}\t\tset { _dtoVideo = value;}\t}\tStatus _states=Status.Pause;// 视频状态,初始化为暂停\tpublic Status states\t{\t\tget { return this._states;}\t\tset { _states = value;}\t}\tint _goFrame=0;// 程序从哪帧开始\tpublic int goFrame\t{\t\tget { return this._goFrame;}\t\tset { _goFrame = value;}\t}\t// 自己用的信息\tGameObject plane;// 背景面片\tTexture tx;// 贴图\tAssetBundle assetBundle;// 资源包\tint bag=0;// 现在加载的第几个包\tstring bags="";// 现在加载的包名\tint frame=0;// 现在渲染第几帧\tstring loads="";// 现在加载的物体名\tint bagFrame=0;// 已渲染到包中的第几张图\tGameObject ownController;// 控制器\tpublic bool open=false;// 是否打开播放器\t// Use this for initialization\tvoid Start () \t{\t\tInitialize();// 初始化//\t\tFullScreen(plane);// 全屏播放\t}\t\t// Update is called once per frame\tvoid Update () \t{\t\tif(states==Status.StartOver)// 如果视频重播\t\t{\t\t\t// 释放内存\t\t\tassetBundle.Unload(false);\t\t\tResources.UnloadUnusedAssets();\t\t}\t}\tvoid FixedUpdate()\t{\t\tif(states==Status.Play \u0026amp;\u0026amp; open==true)// 如果视频继续播放\t\t{\t\t\tif(bags=="")// 初始化\t\t\t{\t\t\t\tCalcaulteBag(goFrame);//\t\t\t\tbags=bag.ToString("d2")+".assetbundle";\t\t\t\tLoadTexture(dtoVideo.Path,bags);// 加载资源包\t\t\t\tassetBundle.Load(loads);// 加载图片\t\t\t}\t\t\tloads=frame.ToString("d6");// 物体名为帧数补0,到6位数为止\t\t\tRendererTexture(plane,loads);// 渲染\t\t\townController.GetComponent\u0026lt;OwnController\u0026gt;().frameVideo=frame;// 返回当前帧数给控制器\t\t\tframe++;// 加帧\t\t\tbagFrame++;// 加包中帧\t\t\tif(bagFrame\u0026gt;=dtoVideo.Each \u0026amp; bag\u0026lt;dtoVideo.Number-1)// 换包播放\t\t\t{\t\t\t\tbag++;// 加包\t\t\t\tbagFrame=0;// 包中帧归位0\t\t\t\t// 释放内存\t\t\t\tassetBundle.Unload(false);\t\t\t\tResources.UnloadUnusedAssets();\t\t\t\tbags=\t\t\t\t#if UNITY_ANDROID\t\t\t\t"Android"+\tbag.ToString("d2")+".assetbundle";\t\t\t\t#elif UNITY_STANDALONE_WIN || UNITY_EDITOR\t\t\t\tbag.ToString("d2")+".assetbundle";\t\t\t\t#else\t\t\t\tbag.ToString("d2")+".assetbundle";\t\t\t\t#endif\t\t\t\tLoadTexture(dtoVideo.Path,bags);// 读包\t\t\t\t//Debug.Log("change bags:"+bags);\t\t\t}\t\t\tif(frame\u0026gt;=dtoVideo.Tote)// 循环播放\t\t\t{\t\t\t\tframe=0;// 帧数归位0\t\t\t\tbag=0;// 包归位0\t\t\t\tbagFrame=0;// 包中帧归位0\t\t\t\townController.GetComponent\u0026lt;OwnController\u0026gt;().round++;// 加圈数\t\t\t\t// 释放内存\t\t\t\tassetBundle.Unload(false);\t\t\t\tResources.UnloadUnusedAssets();\t\t\t\tbags=\t\t\t\t#if UNITY_ANDROID\t\t\t\t"Android"+\tbag.ToString("d2")+".assetbundle";\t\t\t\t#elif UNITY_STANDALONE_WIN || UNITY_EDITOR\t\t\t\tbag.ToString("d2")+".assetbundle";\t\t\t\t#else\t\t\t\tbag.ToString("d2")+".assetbundle";\t\t\t\t#endif\t\t\t\tLoadTexture(dtoVideo.Path,bags);// 读包\t\t\t\t//Debug.Log("reload bags:"+bags);\t\t\t\t//Debug.Log("already finish round:"+ownController.GetComponent\u0026lt;OwnController\u0026gt;().round);\t\t\t}\t\t}\t}\t/// \u0026lt;summary\u0026gt;\t/// 初始化\t/// \u0026lt;/summary\u0026gt;\tpublic void Initialize()\t{\t\tstring PlaneName = "background";// 背景面片名\t\tplane=GameObject.Find(PlaneName);\t\tif(plane==null)\t\t{\t\t\tDebug.Log("VideoPlayer can\u0026#39;t find background plane");\t\t}\t\tstring ControllerName="own controller";// 控制器载体名\t\townController=GameObject.Find(ControllerName);\t\tif(ownController==null)\t\t{\t\t\tDebug.Log("VideoPlayer can\u0026#39;t find controller");\t\t}\t\t// 获取控制器传来的信息\t\tstates=ownController.GetComponent\u0026lt;OwnController\u0026gt;().status;\t\tDebug.Log("initialize video player");\t}\t/// \u0026lt;summary\u0026gt;\t/// 计算第几帧开始的时候处于哪个包\t/// \u0026lt;/summary\u0026gt;\t/// \u0026lt;param name="goFrame"\u0026gt;初始帧\u0026lt;/param\u0026gt;\tpublic void CalcaulteBag(int goFrame)\t{\t\tframe=goFrame;// 当前帧为初始帧\t\tbag=goFrame/dtoVideo.Each;// 当前包=初始帧/每包帧数\t bags=\t\t#if UNITY_ANDROID\t\t"Android"+\tbag.ToString("d2")+".assetbundle";\t\t#elif UNITY_STANDALONE_WIN || UNITY_EDITOR\t\tbag.ToString("d2")+".assetbundle";\t\t#else\t\tbag.ToString("d2")+".assetbundle";\t\t#endif\t}\t/// \u0026lt;summary\u0026gt;\t/// 渲染贴图\t/// \u0026lt;/summary\u0026gt;\t/// \u0026lt;param name="plane"\u0026gt;面片\u0026lt;/param\u0026gt;\t/// \u0026lt;param name="loadname"\u0026gt;贴图名\u0026lt;/param\u0026gt;\tpublic void RendererTexture(GameObject plane,string loadname)\t{\t\ttx = assetBundle.Load(loadname) as Texture;\t\tplane.renderer.material.mainTexture=tx;\t}\t\t/// \u0026lt;summary\u0026gt;\t/// 加载背景序列图资源\t/// \u0026lt;/summary\u0026gt;\t/// \u0026lt;param name="pathURL"\u0026gt;路径名\u0026lt;/param\u0026gt;\t/// \u0026lt;param name="abName"\u0026gt;包名\u0026lt;/param\u0026gt;\tpublic void LoadTexture(string pathURL,string abName)\t{\t\tassetBundle = AssetBundle.CreateFromFile(pathURL+ abName);\t\tif(assetBundle==null)\t\t{\t\t\tDebug.Log("assetBundle doesn\u0026#39;t exist");\t\t}\t\t\t}\t/// \u0026lt;summary\u0026gt;\t/// 全屏播放\t/// \u0026lt;/summary\u0026gt;\t/// \u0026lt;param name="plane"\u0026gt;背景面片\u0026lt;/param\u0026gt;\tpublic void FullScreen(GameObject plane)\t{\t\tif(plane!=null)\t\t{\t\t\tScreen.SetResolution(1366,768,true);\t\t\tplane.transform.localScale=new Vector3(1.366f,1,0.768f);\t\t\tDebug.Log("background full screen");\t\t}\t}\t/// \u0026lt;summary\u0026gt;\t/// 释放AssetBundle\t/// \u0026lt;/summary\u0026gt;\tpublic void CleanAssetBundle()\t{\t\t// 释放内存\t\tassetBundle.Unload(false);\t\tResources.UnloadUnusedAssets();\t}}


推荐阅读