需求:
项目需要在vr设备(htc vive、pico、小π等vr设备)中显示在线视频和播放本地视频的功能。
茶话:
当前做的比较好有htc vive的ViveCinema,场景做比较漂亮。他使用的是FFmpeg+SDL+GLEW。FFmpeg作为视频解析的库在业内是非常有名,视频的解析是从头实现的,大部分其他开源项目都是基于它来实现解复用、解析等操作。SDL是一套开放源代码的跨平台多媒体开发库,另外在游戏方面使用的人是比较多的。GLEW不用说,opengl wrapper。但是ViveCinema仅支持本地视频,那么在线视频呢?
unity3d是比较轻量级的游戏引擎,在手机3d游戏市场可谓如日中天。其灯光渲染效果可能没有ue4等pc游戏引擎好,但是其操作的简易性,开发效率高等特点,得到了大量vr设备厂商和开发人员的青睐。对于C++程序来说,pc端ue4是最好的选择,C#的内存方面的操作实在蹩脚,p/invoke也是非常蛋疼的。无奈vr设备厂商提供unity3d的包,项目采用unity3d开发。
确定使用unity3d开发,那么问题来了,怎么加载视频呢?
首先需要了解vlc的结构,在此花了大量的时间......
思路是:
1、去vlc官网下载vlc库(http://www.videolan.org/vlc/download-windows.html),当前是vlc-2.2.4-win64.zip;
2、解压,分别将axvlc.dll、libvlc.dll、libvlccore.dll、npvlc.dll四个dll和plugins文件夹拷贝至unity3d项目Assert文件夹;
3、使用p/invoke 实现以上dll的接口,获取vlc视频流、视频相关信息和控制事件;
4、在unity3d中新建一个sprite对象,并添加视频控制的cs代码,进行播放视频功能控制;
5、根据3中的接口控制播放,并取得视频流的回调,新建一个视频流的cache数组,将回调函数中的视频流数据放入cache数组中;
6、开始时在ui线程中,起一个定时器获取视频流数据,我这里设置的是每个20ms执行一次,如果正常播放的话,每秒执行50次,就是50帧,应该够了;
6、定时器中处理,在5中得到cache数组中取一帧数据。使用Texture2D类,新建Texture2D对象,关键函数为LoadRawTextureData,即将二进制流数据转换为texture2d材质。然后使用Sprite.Create()使用转换好的Texture2d变为sprite精灵对象。这样就显示在4中新建的sprite对象中了。
7、还有些乱七八糟的参数和事件,后续慢慢解决...
碰到的问题:
unity3d中如何使用unsafe代码?
a、不知道为什么我的vr机器上VS不能打开unity3d项目的属性,在笔记本上可以打开,打开方法,右键项目属性-Build-General-Allow Unsafe Code打上勾;
b、在unity3d项目的Assert下面新建一个名为:smcs.rsp的文件,文件内容为:-unsafe;
c、修改项目的player setting中Other Settings的Optimization中Api Compatibility Level改为.Net 2.0 Subset。(关键)
简单实现 重播,开始/暂停,下一个等功能。4k视频,这个视频播放时间显示不正确....
欢迎来交流群交流:323929978