.net core 调用 winrt 运用时的关键

.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>

 
三符风云涌

Leave a Reply