公司要开发一款给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,如果谁真的用这个语言写出了成功的项目,要想迁移到其他平台,除非无限无聊和很多人力,否则,基本没戏。