http://www.taidous.com/bbs/article-860-1.html

 Unity视频播放有很多种实现方式,可根据要求来选择适当的实现,这里总结一下:

1. MovieTexture

Unity标准接口,支持的播放视频格式有.mov、.mpg、.mpeg、.mp4、.avi和.asf。仅支持PC端的本地视频播放。
    1. 在游戏对象中播放,就好比在游戏世界中创建一个Plane面对象,摄像机直直的照射在这个面上   
    在新建的一个plane平面,将其纹理绑定为电影纹理即可
    //设置当前对象的主纹理为电影纹理
    renderer.material.mainTexture = movTexture;
    //设置电影纹理播放模式为循环
    movTexture.loop = true;
    并可通过
    movTexture.Play();
    movTexture.Pause();
    movTexture.Stop();
    来进得播放控制。
    此时可以通过直接缩放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()视频显示区域即可

2. Handheld.PlayFullScreenMovie

Unity标准的视频播放接口,支持的播放视频格式有.mov、.mpg、.mpeg、.mp4、.avi和.asf。支持PC/移动端播放,支持本地在线播放
    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/路径下
    上面的方法在移动端是边下载边播放网络视频的,属于在线播放,不好的地方就是,再次观看还需要再次加载。可能在播放的时候判断是否已下载到本地如果在本地就可以播放本地,如果没有再从网上下载到本地

  3. MobileMovieTexture

Unity移动端第三方插件视频播放,分免费版和收费版,免费版视频加了水印,收费版无水印,但该插件本身有很多bug,其中最重要的是没有音频。它也不支持在线视频播放。

 4. EasyMovieTexture

Unity移动端第三方视频播放插件,支持视频本地播放,支持RTSP。
    1>. 初始化加载,该部分主要在Unity中将播放视频的地址(本地/URL)传送到Android,并完成MediaPlayer的初始化            
    2>. Android创建一个Surface,并将其与之前创建的MediaPlayer绑定       
    3>. 结合视频绘制载体计算图像拉伸比
    4>. 根据视频宽高比创建VideoTexture并传到Android与
        m_VideoTexture = new Texture2D(Call_GetVideoWidth(), Call_GetVideoHeight(), TextureFormat.RGB565, false);
        Call_SetUnityTexture(m_VideoTexture.GetNativeTextureID());
    5>. 设置视频窗口,完成TextureId与surface的绑定
        SetWindowSize(GetVideoWidth(),GetVideoHeight(),m_iUnityTextureID ,m_bRockchip);
    6>. 更新纹理
        Call_UpdateVideoTexture();
        m_SurfaceTexture.updateTexImage();
    7>. 播放视频
        使用MediaPlayer播放视频

    5. MediaPlayer + SurfaceTexture

    播放组件上层使用MediaPlayer来处理,在成功创建并设置好setDataSource后,需要创建GL_TEXTURE_EXTERNAL_OES格式的纹理ID来与MediaPlayer生成联系。
    在这里我们需要使用SurfaceTexture的理由是,它能代替SurfaceHolder,使得当我们指定图像流的输出目标为照相机预览或视频解码时,我们在每一帧中得到的所有数据不需要直接用于显示在设备上,而是可以选择先输出到SurfaceTexture上,在上屏之前可能做一些自定义扩展。当调用updateTexImage()时,用来创建SurfaceTexture的纹理对象内容被更新为包含图像流中最近的图片。
    SurfaceTexture对象可以在任何线程里创建。但updateTexImage()只能在包含纹理对象的OpenGL ES上下文所在的线程里创建。可以得到帧信息的回调可以在任何线程被调用。这一点要注意,上下文如果不一致,视频无法上屏。
    这里还有个要求就是在创建纹理的时候,需要使用使用GL_TEXTURE_EXTERNAL_OES作为纹理目标,其是OpenGL ES扩展GL_OES_EGL_image_external定义的。这种纹理目标会对纹理的使用方式造成一些限制。每次纹理绑定的时候,都要绑定到GL_TEXTURE_EXTERNAL_OES,而不是GL_TEXTURE_2D。而且,任何需要从纹理中采样的OpenGL ES 2.0 shader都需要声明其对此扩展的使用,例如,使用指令”#extension GL_OES_EGL_image_external:require”。这些shader也必须使用samplerExternalOES采样方式来访问纹理。这部分在后面采样器中有说明。
    几个重要的技术点如下:
  • Shader采样 YUV->RGB
    这里片元着色器的使用如下:
    该Shader是针对GL_TEXTURE_EXTERNAL_OES的一种扩展,完成YUV到RGB的转换,采样出来的数据需要绘制到Unity纹理上,这里面不能直接操作,需要借助FBO和EGLImage来操作。该片元着色器的写法在使用SurfaceTexture里面已经有提及。
  • EGLImage
    EGLImage代表一种由EGL客户API(如OpenGL,OpenVG)创建的共享资源类型。它的本意是共享2D图像数据,而在这里使用它的目的在于经过EGLImage创建的2D纹理,能够bind到任意的载体GameObject上面。
    如何创建EGLImage,创建的标准接口如下
    EGLImageKHR eglCreateImageKHR(
                            EGLDisplay dpy,
                            EGLContext ctx,
                            EGLenum target,
                            EGLClientBuffer buffer,
                            const EGLint *attrib_list);
    target决定了创建EGLImage的方式,例如在Android系统中专门定义了一个称为EGL_NATIVE_BUFFER_ANDROID的Target,支持通过ANativeWindowBuffer创建EGLImage对象,而Buffer则对应创建EGLImage对象时的使用数据来源。
    1) 首先需要一个ANativeWindowBuffer。
    该buffer可以通过ANativeWindow的接口dequeueBuffer来获取。
    这个对象的api接口较多,它对buffer的管理类似于如下
    这部分操作可以参考下面这篇文章
    http://tangzm.com/blog/?p=167
    在获取buffer之前要创建一个ANativeWindow对象。
    2) 通过该ANativeWindowBuffer来创建EGLImage
    3) 成功创建了EGLImage后,可能通过它来创建一个2D纹理
    这个2D纹理在后面创建FBO的时候会用到。
  • FBO - Frame Buffer Object
    FBO即帧缓存对象,它是OpenGL管线的最终渲染目的地。在OpenGL渲染管线中,几何数据和纹理在FBO内部经过多次转化和多次测试,最后以二维像素的形式显示在屏幕上。它是一些二维数组和OpenG所使用的存储区的集合:颜色缓存、深度缓存、模板缓存和累计缓存。默认情况下,OpenGL将帧缓冲区作为渲染最终目的地。此帧缓冲区完全由window系统生成和管理。这个默认的帧缓存被称作“window系统生成”(window-system-provided)的帧缓冲区。
    有两种类型的“帧缓存关联图像”:纹理图像(texture images)和渲染缓存图像(renderbuffer images)。如果纹理对象的图像数据关联到帧缓存,OpenGL执行的是“渲染到纹理”(render to texture)操作。如果渲染缓存的图像数据关联到帧缓存,OpenGL执行的是离线渲染(offscreen rendering)。
    具体的操作如下:
    在这里使用了通过上一步EGLImage生成的2D纹理mTex,这样的话后续就可以通过操作FBO对象来获取MediaPlayer中SurfaceTexture中的每一帧数据。
关于FBO的详细接口说明,可见下面链接
    http://blog.csdn.net/dreamcs/article/details/7691690
  • SurfaceTexture.updateTexImage
    当MediaPlayer中当新的帧流可用时,调用updateTexImage从图像流中提取最近一帧到纹理图像中,此时由于同处一个上下文中,首先需要执行一次FBO绑定操作,这是由于GL_TEXTURE_EXTERNAL_OES的特性决定的,实际上这个操作是为了下帧准备的。
    然后将shader采样出来的数据帧跟Unity纹理ID绑定后就可上屏。
    PS: 这里没有截很代码的详细逻辑,只是原理,可能有理解不到位的地方,欢迎指证。

Unity视频播放的各种实现方式汇总的更多相关文章

  1. 如何实现Windows Phone代码与Unity相互通信(插件方式)

    原地址:http://www.cnblogs.com/petto/p/3915943.html 一些废话 原文地址: http://imwper.com/unity/petto/%E5%A6%82%E ...

  2. Android中三种超实用的滑屏方式汇总(转载)

    Android中三种超实用的滑屏方式汇总   现如今主流的Android应用中,都少不了左右滑动滚屏这项功能,(貌似现在好多人使用智能机都习惯性的有事没事的左右滑屏,也不知道在干什么...嘿嘿),由于 ...

  3. Asp.net页面间传值方式汇总

    七种传值方式,分别是:URL传值,Session传值,Cookie传值,Server.Transfer传值,Application传值,利用某些控件的PostBackUrl属性和使用@Previous ...

  4. XML解析方式汇总

    XML解析方式汇总 分类: XML2011-08-23 19:19 167人阅读 评论(0) 收藏 举报 xmlstringexceptionattributesclassiterator DOM解析 ...

  5. web 存储方式汇总:Cookies,Session, Web SQL; Web Storage(LocalStorage ,SessionStorage),IndexedDB,Application Cache,Cache Storage

    1 1 1 web 存储方式汇总: 旧的方式: Cookies; Session; Web SQL; 新的方式 HTML5 : Web Storage(LocalStorage ,SessionSto ...

  6. Web 前端必备的各种跨域方式汇总

    Web 前端必备的各种跨域方式汇总 跨域方式汇总 同源策略 协议相同 + 域名相同 + 端口相同 https://www.xgqfrms.xyz/index.html https://www.xgqf ...

  7. Unity 视频播放杂谈

    http://www.cnblogs.com/zsb517/p/4060814.html 背景:      游戏机中想加入舞蹈元素,最先的想法是开发舞蹈游戏,然后通过动画来表现舞蹈,给用户提供舞蹈教学 ...

  8. Python安装包或模块的多种方式汇总

    windows下安装python第三方包.模块汇总如下(部分方式同样适用于其他平台): 1. windows下最常见的*.exe,*msi文件,直接运行安装即可: 2. 安装easy_install, ...

  9. linux线程间同步方式汇总

    抽空做了下linux所有线程间同步方式的汇总(原生的),包含以下几个: 1, mutex 2, condition variable 3, reader-writer lock 4, spin loc ...

随机推荐

  1. 2016年12月7日 星期三 --出埃及记 Exodus 21:2

    2016年12月7日 星期三 --出埃及记 Exodus 21:2 "If you buy a Hebrew servant, he is to serve you for six year ...

  2. 【SQL】SQL中笛卡尔积、内连接、外连接的数据演示

    SQL的查询语句中,常使用到内连接.外连接,以及连接的基础--笛卡尔积运算. 在简单的SQL中,也许我们还分辨清楚数据如何连接,一旦查询复杂了,脑子也犯浆糊了,迷迷糊糊的. 本文,简单以数据形式记录连 ...

  3. CentOS 6.5 64位 安装zabbix-2.2.0

    安装环境: VM 10 + CentOS-6.5-x86_64-minimal 虚拟机网络是NAT方式, 动态IP Xshell登录到Centos操作 刚装的centos,啥都没有,先配一下yum 首 ...

  4. C# 模拟鼠标写字

    经常看到别人拿个四四方方的写字板用笔写字,用C#其实也可以实现,大致思路就是处理鼠标的坐标和Graphics, 代码如下: 首先声明两个全局变量 bool isMouseDown = false; P ...

  5. hnoi 2016 省选总结

    感觉省选好难的说...反正我数据结构太垃圾正解想到了也打不出来打一打暴力就滚粗了! DAY1 0+20+30 DAY2 60-20+0+60 最后170-20分,暴力分还是没有拿全! 然而这次是给了5 ...

  6. C#堆栈和托管堆

    首先堆栈和堆(托管堆)都在进程的虚拟内存中.(在32位处理器上每个进程的虚拟内存为4GB) 堆栈stack 堆栈中存储值类型. 堆栈实际上是向下填充,即由高内存地址指向低内存地址填充. 堆栈的工作方式 ...

  7. FlexSlider插件的详细设置参数 http://www.woothemes.com/flexslider/ -----幻灯片插件

    $(window).load(function() { $('.flexslider').flexslider({ namespace: 'flex-', //控件的命名空间,会影响样式前缀 anim ...

  8. jsp get方式请求参数中包含中文乱码问题解决

    1. 自己接收到参数之后在后台进行转码处理 2: 修改tomcat的配置文件  server.xml <Connector port="8080" protocol=&quo ...

  9. Java I/O 对象序列化

    我们知道对象的持持久化有三种方式: 1: 对象序列化 2: XML 3: 数据库技术 序列化可以帮助使得对象的生命周期不取决与程序是否正在执行,它可以生存于程序的调用之间. 只要将任何对象序列化到单一 ...

  10. shell script针对参数已经有配置好变量名称

    /path/to/scriptname opt1 opt2 opt3 opt4 $ $ $ $ $ 这样够清楚了吧?运行的脚本档名为 $0 这个变量,第一个接的参数就是 $1 啊- 所以,只要我们在 ...