1. 程式人生 > >unity 中播放視頻

unity 中播放視頻

shader int inpu 包含 assets vid 網絡 拉伸 上下文

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的賦值,在5.0x版本上是無法通過將視頻拖入Project視頻來自動造成紋理的。


2. 在GUI層面播放。它其實和貼圖非常相像,因為播放視頻用到的MovieTexture屬於貼圖Texture的子類。
//繪制電影紋理
GUI.DrawTexture(newRect(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. 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播放視頻
4. 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采樣方式來訪問紋理。

unity 中播放視頻