.net core 調用 winrt 運用時的關鍵
這兩日想寫一個簡單的視頻合成的小工具,如果不是為了分發使用,直接腳本ffmepg或直接用python便能完成了,然而現在遇到這樣需要,所以考慮直接用.net+winform的形式快速完成。
看到win rt裡的視頻編輯頗為簡單,於是打算直接用win ui3寫個小工具,結果發現這東西,跟ump不清不楚的關係,由於是自用,部署起來超級麻煩,而最簡單的方法是發佈到微軟應用商店,然後再下載,這是在開什麼玩笑。
於是改了個方法,採用.net core6,創建了一個winform的應用,由於視頻合成需要使用overlay layer,而對於綠幕之類的要進行自動透明,因此必然要用到Chroma Key技術讓通道透明,這一塊是需要自己完成的。
通過winrt 的media可以在CompositeFrame裡直接使用directx,相當於可以直接使用gpu合成,根據使用大數據算法的經驗來說,這樣的效率肯定會高很多。
結果提示必須要使用win2d這個庫,一引用了這個庫後,立即慘不忍睹,因為.net core5.0以上的運行時根本不支持這個,於是又去翻了下微軟的文夾,發現說得不明不白的。
關鍵是在引用win2d後,提示一大堆引用的接口找不到,很顯然這些接口是需要有一個地方進行定義的,完全不熟悉這方面,著實麻煩。
msdn上給出來的解決方案描述上很容易讓人產生偏頗,例如文檔上是這樣寫的:
.NET Core 是 .NET 平臺的重點,.NET 5 是最新主要版本。 它是一個開源的跨平臺運行時,可用於構建設備、雲和 IoT 應用程序。
以前版本的 .NET Framework 和 .NET Core 都內置了 WinRT(一種特定於 Windows 的技術)知識。 為了支持 .NET 5 的可移植性和高效性目標,我們從 .NET 編譯器和運行時中撤銷了 WinRT 投影支持,將其移到了 C#/WinRT 工具包中。 C#/WinRT 的目標是通過舊版 C# 編譯器和 .NET 運行時提供的內置 WinRT 支持來提供奇偶校驗。 有關詳細信息,請參閱 Windows 運行時類型的 .NET 映射。
跟著文檔走,然後會告訴你需要安裝:Install-Package Microsoft.Windows.CsWinRT -Version 1.4.1
繞了半天,最後你發現這是在教你如果創建一個普通的類庫後,如何生成WinMD文件的,而實際上只要你直接按模板創造一個windows 運行時項目,它就能夠生成了,所以這裡說了半天,對於實際並無任何意義。
如果你建立一個新的window form 窗口應用,然後創建一個運行庫組件進行引用的話,直接就會告訴你類似:
嚴重性 代碼 說明 項目 文件 行 禁止顯示狀態
錯誤 NU1201 項目 Effects 與 net6.0-windows10.0.17763 (.NETCoreApp,Version=v6.0) 不兼容。 項目 Effects 支持: uap10.0.17763 (UAP,Version=v10.0.17763)
最後實在是想放棄,直接改用ffmpeg來做了,這樣多簡單,然而ffmpge是直接使用cpu來進行運算的,如果要調用gpu,又要裝cuda配置一番,對於分發部署相當的麻煩。
最後反覆摸索之下,終於弄清楚如何直接在winform裡進行調用了,其實說白了非常簡單。
首先.net core 的winform模板後,nuget引入 Microsoft.VCRTForwarders.140,以及Microsoft.Windows.SDK.Contracts,再引入win2d,這樣還沒有結束,如果是用的.net 6.0運行時,你將會發現類似的提示:
嚴重性 代碼 說明 項目 文件 行 禁止顯示狀態
錯誤 NETSDK1130 無法引用 Windows.AI.MachineLearning.MachineLearningContract.winmd。不支持以 .NET 5 或更高版本為目標時,請直接飲用 Windows 元數據組件。有關詳細信息,請參閱 https://aka.ms/netsdk1130 WinFormsApp1 C:\Program Files\dotnet\sdk\6.0.100\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.targets 1003
顯然需要降低.net core的版本,根據實際上看,降到.net core3.1是最合適的。
不得不說,微軟給出來的文檔也是不清不楚的,總感覺微軟還是沒有拋棄那份小家子氣,一方面想著搞開放,想要做大覆蓋率,一邊又不清不楚,想要通過一定的封閉性來維護windows平臺的優勢性,給出來的文檔總是不夠清晰詳實,很多時候都不給出簡單直白的落地方案。
比在mac os或linux上的開發來說,雖然看起來生態封閉,但在很多的功能實現與開發上,給出來的方案極其詳實,擁有大量開包即用的東西。
以這個案例來說,雖然與 rt 運行時的交互,會有性能上的開銷,但實驗下來,處理一個視頻調用ffmpeg合成視頻,需要花費25s,而通過調用win10的提供功能,僅僅只需要8s,這樣級別的優化非常容易。
最後記錄一下詳細的文件配置,方便以後查閱:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows10.0.17763.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<PlatformTarget>x86</PlatformTarget>
<LangVersion>10.0</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VCRTForwarders.140" Version="1.0.7" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.22000.196" />
</ItemGroup>
</Project>