Unity 視頻播放雜談


背景:

     游戲機中想加入舞蹈元素,最先的想法是開發舞蹈游戲,然后通過動畫來表現舞蹈,給用戶提供舞蹈教學方面的體驗,但是舞蹈游戲本身的開發就需要很長的時間(就人太少),不用談后續的舞蹈和音樂的版權啦,所以現在想走另外一條途徑,在unity中播放舞蹈教學視頻,加上UI和一些檢測來實現舞蹈教學,而且這套框架寫完之后,內容很容易擴展,畢竟不需要針對每個舞蹈設計動畫。但是Unity中視頻播放就是各種蛋疼,尤其是在android下面,OK ,下面的內容很多是從網上整理下來:

1 Win/Mac

     首先在Windows和Mac上 需要Quick Time7.0以上的版本。Unity支持的視頻播放格式還是蠻多如.mov、.mpg、.mpeg、.mp4、.avi、.asf,甚至.H264等等,使用起來也很簡單,真的很簡~~單。 在WIN/MAC下,Unity提供了MovieTexture紋理,對導入的視頻Unity會自動進行轉換。MovieTexture繼承與Texture類,提供了視頻播放中需要的簡單控制播放/暫停/停止:
 
Pause Pauses playing the movie.
Play Starts playing the movie.
Stop Stops playing the movie, and rewinds it to the beginning.
MovieTexture給出的參數也是在不多,考慮到視頻會是從網絡中進行下載,檢測isReadyToPlay很有必要,isPlaying給出是否在播放的參數,loop控制是否循環播放,duration是一個很有用的東西,給出當前播放到的位置。
audioClip Returns the AudioClip belonging to the MovieTexture.
duration The time, in seconds, that the movie takes to play back completely.
isPlaying Returns whether the movie is playing or not.
isReadyToPlay If the movie is downloading from a web site, this returns if enough data has been downloaded so playback should be able to start without interruptions.
loop Set this to true to make the movie loop.
測試一下,具體的使用方式雨松給出的很詳細:Unity3D研究之兩種方式播放游戲視頻以在平面顯示為例,測試代碼的核心代碼如下:
1         renderer.material.mainTexture = movie; //設置材質
2 
3         movie.loop = true;                     //循環播放
4         movie.Play();                          //播放
5         movie.Pause();                         //暫停
6         movie.Stop();
clipboard
 
unity中提供的視頻播放功能還是先對簡單化,如果只是簡單的播放倒也無所謂,但是如果是進行視頻方面的開發,肯定不能滿足要求。例如常用的 回放、快進、快退、定點播放等等都沒提供。對於快進,有網友通過在同一個GameObject上綁定一個AudioSource,利用其pitch參數可以進行控制,不過我沒有測出來。 還有一種方法就是合適的第三方插件,如AVPro QuickTime,可以實現快進、快退、頂點播放、多窗口播放等等(如果在window下,例子中是視頻文件以及內部的參數中.bin的后綴要去掉),不過這個插件只能在win/mac上使用~~ 。
 
這個插件的代碼是研究unity底層不錯的例子,Unity實現的功能有限,但是可以通過利用視頻編解碼庫對視頻進行解碼,然后利用Unity底層提供的渲染功能(如GL)實現表面的視頻播放功能。
[​IMG]       [​IMG]

2 移動端

在移動端,unity並不提供MovieTexture,AVPro QuickTime也用不了,其最基本的顯示方案使用通過PlayFullScreenMovie()函數進行全屏播放,根據其官網解釋,主要有以下方面:

(1)視頻流直接從設備存儲器中獲得,所以文件只能是單獨提供,視頻文件放置在StreamingAssets 文件夾中
(2) 視頻播放過陳中,Unity將會停止;播放結束后unity自動恢復;播放過程中屏幕中的顏色會變為播放器的背景顏色,播放之后恢復。
(3)在IOS中,內部實際上是調用MPMoviePlayerController的方法
(4)能夠支持的格式: .mov, .mp4, .mpv, and .3gp ,H.264,MPEG-4 Part 2 video

 Handheld.PlayFullScreenMovie ("StarWars.mp4", Color.black, FullScreenMovieControlMode.CancelOnInput);

話不投機,兩句多,還是果斷第三方插件,Mobile movie texture for android 就是很不錯的東西,利用開源視頻編解碼庫Theora進行視頻解碼,然后通過Unity Texture實現顯示。下圖為多視頻顯示效果:

 
        
應用中的一些問題:
(1)因為視頻編解碼庫是使用
Theora ,所以只能支持OGG、OGV格式的視頻和音頻,如果要使用其他格式則需要轉換一下,可以Theora Converter .NET工具進行轉換。

(2)視頻seek功能不是很精確,雖然能用
(3)多視頻播放問題,如果想要多少視頻同時播放,需要理解內部代碼的實現,修改后可以湊合着使用。多視頻播放的另外一個問題是效率問題,如果是N個視頻,可能就會有N個后台線程在進行解碼操作,相應的也會有N個渲染管道進行渲染,我在RK3188上進行三個不同視頻的播放,就會有卡頓。多視頻播放中間理解的關鍵代碼在下面,Texture2D.CreateExternalTexture 函數從視頻中獲得貼圖資源,SetTextures()進行繪制,如果使用多個視頻,需要多個材質(也就是多個渲染管道)。
        private void AllocateTexures()
        {
            m_ChannelTextures[0] = Texture2D.CreateExternalTexture(m_yStride, m_yHeight, TextureFormat.BGRA32, false, false, GetNativeYHandle(m_nativeContext));
            m_ChannelTextures[1] = Texture2D.CreateExternalTexture(m_uvStride, m_uvHeight, TextureFormat.RGBA32, false, false, GetNativeCrHandle(m_nativeContext));
            m_ChannelTextures[2] = Texture2D.CreateExternalTexture(m_uvStride, m_uvHeight, TextureFormat.RGBA32, false, false, GetNativeCbHandle(m_nativeContext));

            if (m_movieMaterials != null)
            {
                for (int i = 0; i < m_movieMaterials.Length; ++i)
                {
                    var mat = m_movieMaterials[i];

                    if (mat != null)
                    {
                        SetTextures(mat);
                    }
                }
            }
            
        }

        public void SetTextures(Material material)
        {
            material.SetTexture("_YTex", m_ChannelTextures[0]);
            material.SetTexture("_CrTex", m_ChannelTextures[1]);
            material.SetTexture("_CbTex", m_ChannelTextures[2]);

            material.SetTextureScale("_YTex", m_uvYScale);
            material.SetTextureOffset("_YTex", m_uvYOffset);

            material.SetTextureScale("_CbTex", m_uvCrCbScale);
            material.SetTextureOffset("_CbTex", m_uvCrCbOffset);
        }


轉載 請注明:細雨淅淅


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM