Unity Video Codec Plugin 開發記錄

不動虎王 發佈 2023-12-06T04:27:03.574956+00:00

公司要開發一款給Unity使用的全平台解碼,要求性能要好,IO要流暢(比引擎自帶),支持Vulkan(800美刀的AVPro就不得行),支持硬體解碼。時間2個月!先說下結論,搞定了,最難的是Android.

公司要開發一款給Unity使用的全平台解碼,要求性能要好,IO要流暢(比引擎自帶),支持Vulkan(800美刀的AVPro就不得行),支持硬體解碼。時間2個月!

先說下結論,搞定了,最難的是Android. PC最簡單

PC的最簡單,原因是可以任意斷點,Visual Studio對Windows平台上的支持非常完美,各種方式的調試都能得到支持。

編譯底層庫

我最先選擇的方案是基於開源的Player-VLC Player。

libVLC-失敗:

選擇理由,VLC本身就是全平台的視頻播放器,如果能基於VLC開發,理論上會非常簡單,只需要去掉它的UI,直接調用API即可,理論上難度最小。但是,事實證明,這浪費了我三天時間,當然也可能最初對Bash的命令行環境不熟悉,對各種工具還不適應。這三天我折騰了N遍,最後還是放棄了,主要原因有2個,第一當然是編譯不過(必須要做Linux下編譯,MSYS2都不得行),這個即使勉強編譯通過,最後的生成也沒法用VisualStudio舒適地調試。在對所有流程和API都不熟悉的時候,底層庫一定要是能調試的,否則錯了都沒辦法知道和解決。

重新選擇:

棄用libVLC後,選擇其實不多,要麼全部原生API走起 ,要麼就是找個替代的方案,在對比了很多方案後,最後選擇了FFMpeg的libAVCodec。FFMepge工程里有帶個FFPlayer,勉強可以參考下基本API的使用。


libAVCodec-編譯成功:

libAVCodec編譯就相對順利很多,在Windows平台下用Msys2環境,但是可以直接用VC Toolschain,當然,最終也肯定可以用VisualStudio調試。這個在後來被證明是非常正確的選擇。大概1天左右,第一個適配和精簡的libAVCodec就編譯成功, 從原始的大概40M,精簡到了10M再到3M。這個過程其實也是熟悉libAVCodec的過程。

Windows硬體解碼

搞定了庫之後,後面的開發就很玄幻了。非常幸運,在開發的同時(23年的3月份左右)出現了ChatGPT,這個至少解決了我初期80%以上的問題,有些回答不對,但是有啟發性。我最初的很多問題答案在網上搜不到,或者返回的內容就是胡說一氣的。比如,硬體解碼打開方式,這個在FFPlayer里沒有,在網上一搜各種說法,後來證明,大部分都是胡說八道的。GPT給出的答案也不完全正確,但是按照它說的思路,我逐漸找到了正確方法,這個證明至少節省了2-3周的嘗試時間。GPT傑出的表現貌似也僅僅在剛開始(3月)的時候,後面被封停一段時間再打開(4月)時候,GPT3被降智了(可能是逼迫大家去Plus GPT4),再問一樣的問題,回答都不靠譜。


Android

2周左右帶硬體解碼的Windows搞定後,基本思路和解碼流程基本就完成驗證和基本成熟了。開發Android理論上應該很輕鬆,但是,馬上就遇到了IO的問題。Android底層是JAVA,有些返回的文件路徑(比如Uniy 的StreamingAssets是 jar://的方式,這個直接用基於C開發libAVCodec去讀取肯定沒戲。這個部分問GPT,newbing,和各種開發論壇網站都搜不到。這部分最初我是放棄的,我採取拷貝視頻到App的沙盒目錄(可讀寫目錄),然後再用libavcodec去直接讀取,這個目錄是file://開始的,C API可以直接讀取。但是,這肯定不完美,這遇到較大的視頻文件的時候,第一次copy肯定很產生延遲,導致播放體驗不佳。最終,我發現libavcodec是可以register IO函數的,read,seak都可以被替換,我就嘗試用JNI的函數去讀取原來標準C IO不能實現讀取的內容,最終實現了Streaming Assets里視頻文件的直讀。JNI的橋接非常不直觀,很醜陋,好在GPT也幫忙完成大部分內容。節省了1-2周的時間。


Mac

Mac不難,但是很麻煩。Windows下的基於libCodec的代碼可以很容易移植適配Mac和IOS,Mac麻煩是它的開發環境XCode。不帶偏見的說,真的很難用,特別是在增加了無數莫名其妙的專有概念如: Framework,Bundle,Meta Lib等,各種語言Object C ,Swift,C++ ,C混合編程後,說實話,感覺Mac是人為在製造不兼容和障礙。Mac的開發難度主要是對它的額外的內容,Framework,Bundle,這些似是而非的內容的理解,對它各種繁瑣設置的適應,當然,還有噁心的開發者帳號,各種證書和簽名。

Mac在搞定了環境和最初的迷茫後,開發很順利,XCode也能和VisualStudio類似的各種斷點,整個底層適配Mac我只用了30分鐘,就加了個格式判定的分支就搞定了,非常簡單。


IOS

這個在搞定Mac後,應該是很簡單的,但是,IOS出現了個問題,就是在Mac上順利運行的Framework,而且在IOS沒有報錯,但是運行結果是錯的。由於Framework是以二進位包的形式存在於Unity Plugin目錄下,Unity Build的工程里實際上是沒有Framework的工程源碼的。在Mac和PC上很直覺的的Attach Process的調試方式,在模擬器和真機上都沒法實現。我問了降智後的GPT和不太靠譜的newbing,都是完全的錯誤回答。這個導致我整整一天都沒法推進。我甚至嘗試了,在Unitybuild出來的XCode工程里直接拖入需要調試的cpp運行,這個在Visualstudio上是一個很有效的技巧,但是在愚蠢的XCode上被解釋成了一個import強行插入到當前文件。最後還是本人不死心,發現了在Debug里有個直接輸入symbol的菜單,我嘗試輸入了一個必定調用的api,breaked!


總結下,Unity抹殺了平台的跨平台的鴻溝,降低的整個遊戲業界的開發難度,但是也相應使得我們的開發人員對各平台細節知之甚少。我遇到的問題,其實比我寫出的來的多得多,有些是彎路,有些也確實是目標平台為了綁定開發者而設的坑。比如醜陋的Object C,如果誰真的用這個語言寫出了成功的項目,要想遷移到其他平台,除非無限無聊和很多人力,否則,基本沒戲。

關鍵字: