一:引言
首先,今天有了一个想法。所以我决定制作一个VR播放器。纯手工打造,24K金不敢说,100%真心。
导入资源神马的不说了,直接上代码。而且也没有人制作过,所以有压力,不过动力更大。(Ps:2016-12-31,12:31)
二:关于视频播放要知道的一些事
视频的帧率问题
三:Unity自带了两种播放API
1- MovieTexture(视频纹理)
优点:简单,高效的快速完成播放
缺点:此种方法无法应用于移动端。movietexture只能播放OGG和OVG
转码可以使用:
Theora Converter .NET
Paste_Image.png
ffmpeg将视频转成.ogv
ffmpeg - i “文件路径/文件名.格式” -s3000x1500(分辨率) -r25(帧率) -b:v8782(码率,默认单位为Bit/s)"输出文件路径/输出文件名.格式"
2-Handheld(标准的视频播放接口)
缺点:
可操作性非常差,几乎达不到我们想要的结果,而且也只支持全屏的普通视频的播放。
注意点:
将视频文件放置在Assets/StreamingAssets/路径下,经测试.MP4可用。
MoveTexture
1.在游戏对象中播放,就好比在游戏世界中创建一个Plane面对象,摄像机直直的照射在这个面上 在新建的一个plane平面,将其纹理绑定为电影纹理即可//设置当前对象的主纹理为电影纹理renderer.material.mainTexture = movTexture;//设置电影纹理播放模式为循环movTexture.loop = true; 并可通过 movTexture.Play(); movTexture.Pause(); movTexture.Stop(); mov Texturu.pitch =1f 正常播放2f两倍速度 来进得播放控制。 此时可以通过直接缩放plane平面来达到缩放视频的目的 至于MovieTexture的赋值,在4.6x/5.0x版本上是无法通过将视频拖入Project视频来自动造成纹理的2.在GUI层面播放。它其实和贴图非常相像,因为播放视频用到的MovieTexture属于贴图Texture的子类。//绘制电影纹理GUI.DrawTexture (new Rect (0,0, Screen.width,Screen.height),movTexture,ScaleMode.StretchToFill); 播放视频的大小是屏幕的宽高,如果想动态的修改视频的宽或高直接修改new Rect()视频显示区域即可
Handheld
url_movie="http://dl.nbrom.cn/17051/c3e408229342723fbdf62d0bcf1d549c.mp4?fsname=Criminal_Minds_S01E01.mp4";Handheld.PlayFullScreenMovie(url_movie, Color.black,FullScreenMovieControlMode.Full);Handheld.PlayFullScreenMovie("test.mp4", Color.black,FullScreenMovieControlMode.CancelOnInput);将视频文件放置在Assets/StreamingAssets/路径下上面的方法在移动端是边下载边播放网络视频的,属于在线播放,不好的地方就是,再次观看还需要再次加载。可能在播放的时候判断是否已下载到本地如果在本地就可以播放本地,如果没有再从网上下载到本地注意:1. 将视频资源拷贝到外置存储(如sd卡),通过外置存储绝对路径调用stringpath = Application.persistentDataPath +"xxx.mp4";2. 在BuildApk的时候,将视频资源放在StreamingAssets子目录下,通过视频名字调用stringpath ="xxx.mp4";
Api
四:视频播放插件
第三方插件:进行播放
GitHub有大量的视频播放插件,自己去搜索.
EasyMovieTexture
MobileMovieTexture
MobilePlayer
Mobile movie texture for android :利用开源视频编解码库Theora进行视频解码,然后通过Unity Texture实现显示。
1-使用插件
由于CardBoard中VR播放不能使用自带的两种方式所以下面的项目中,直接使用插件,此处不再啰嗦介绍
2-项目准备
一段视频,N张图片,一个梦幻的场景,各种好听的音乐,那么导入资源。此处使用视频插件Easy Movie Texture
资源可以加群494141729获取
VR视频播放
Paste_Image.png
Paste_Image.png
选中平台设置
Paste_Image.png
3-播放代码
关于视频播放的代码,设置暂停,停止,加载,全屏等usingUnityEngine;usingSystem.Collections;usingUnityEngine.UI;publicclassTest_Movie_Player:MonoBehaviour{publicText totalTime;publicText movieTime;publicSlider movieSlider;publicMaterial renderMaterial;publicintmovieSpeed =1000;privateMediaPlayerCtrl mediaPlayerCtrl;privateRawImage movieRawImage;privateVector2 reducteOffsetMax;privateboolisFinish =false;privateboolisPlay =false;privateboolisCtrlMovie =false;privateintfastbackTemp =0;privateinttotaltime =0;voidStart(){ Init(); mediaPlayerCtrl.OnEnd += OnEnd; }//////初始化函数///publicvoidInit(){ mediaPlayerCtrl =this.transform.GetComponent(); movieRawImage =this.transform.GetComponent(); mediaPlayerCtrl.m_bAutoPlay =false;if(movieRawImage.material ==null) movieRawImage.material = renderMaterial; reducteOffsetMax = movieRawImage.rectTransform.offsetMax; }voidUpdate(){ UpdateMovieSlider(); UpdateMovieTime(); UpdateTotalTime(); }//////更新视频进度条///publicvoidUpdateMovieSlider(){if(mediaPlayerCtrl.GetSeekPosition() !=0&& !isCtrlMovie) {floatslider = (float)mediaPlayerCtrl.GetSeekPosition() / (float)mediaPlayerCtrl.GetDuration(); movieSlider.value= slider; } }//////更新视频总时间///publicvoidUpdateTotalTime(){if(this.totalTime.text !=null&& isPlay) {if(totaltime != mediaPlayerCtrl.GetDuration() /1000) { totaltime = mediaPlayerCtrl.GetDuration() /1000;intmin = totaltime /60;intseconds = totaltime - min *60;this.totalTime.text =" / "+ min +":"+ seconds; } } }//////更新视频时间///publicvoidUpdateMovieTime(){if(this.movieTime.text !=null&& isPlay) {intmovieTime = mediaPlayerCtrl.GetSeekPosition() /1000;intmin = movieTime /60;intseconds = movieTime - min *60;this.movieTime.text = min +":"+ seconds; } }//////视频播放///publicvoidMoviePlay(){ mediaPlayerCtrl.Play(); isPlay =true; isFinish =false; }//////视频暂停///publicvoidMoviePause(){ isPlay =false; mediaPlayerCtrl.Pause(); }//////视频停止///publicvoidMovieStop(){ isPlay =false; mediaPlayerCtrl.Stop(); }//////读取视频//////读取视频的路径publicvoidMovieLoad(stringnamePtah){ mediaPlayerCtrl.Load(namePtah); mediaPlayerCtrl.m_bAutoPlay =false; isPlay =false; isFinish =false; }//////视频设置循环播放///publicvoidMovieLoop(){ mediaPlayerCtrl.m_bLoop = !mediaPlayerCtrl.m_bLoop; }//////视频全屏显示///publicvoidOnClickFullScreen(){if(mediaPlayerCtrl.m_bFullScreen) { mediaPlayerCtrl.m_bFullScreen =false; movieRawImage.rectTransform.offsetMax = reducteOffsetMax; movieRawImage.rectTransform.offsetMin = -reducteOffsetMax; }else{ mediaPlayerCtrl.m_bFullScreen =true; movieRawImage.rectTransform.offsetMax =newVector2(0,0); movieRawImage.rectTransform.offsetMin =newVector2(0,0); } }//////关闭视频界面///publicvoidOnClickClose(){ mediaPlayerCtrl.Stop(); movieRawImage.gameObject.SetActive(false); }//////移动视频进度条///publicvoidOnDragSlider(){if(!isPlay)return;intseekPos = (int)(movieSlider.value* mediaPlayerCtrl.GetDuration()); mediaPlayerCtrl.SeekTo(seekPos); }//////按下视频进度条///publicvoidOnPoniterDownSlider(){if(!isPlay)return; MoviePause(); isCtrlMovie =true;intseekPos = (int)(movieSlider.value* mediaPlayerCtrl.GetDuration()); mediaPlayerCtrl.SeekTo(seekPos); }//////弹起视频进度条///publicvoidOnPoniterUpSlider(){if(!isPlay)return; MoviePlay(); isCtrlMovie =false; }publicboolGetIsFullScreen(){returnmediaPlayerCtrl.m_bFullScreen; }publicboolGetIsLoop(){returnmediaPlayerCtrl.m_bLoop; }voidOnEnd(){ isFinish =true; } }
绑定事件
全景视频播放
全景视频跟着头部移动的方法,看到sphere对象上挂在了GvrViewer.cs脚本,然后把VRModelEnabled属性设置为false,这样就调整配置文件就可以全景视频跟着头部移动而观看视频效果了
调整配置文件
To support devices using the TI S3D library for stereo mode we must
add the following library.
Devices that require this are: ODG X6
-->
To support the ODG R7 in stereo mode we must add the following library.
-->
参考资料:
http://blog.csdn.net/adambieber/article/details/52334280