WPF:安装 project/release 版本中的 LibVLCSharp 集成

WPF: LibVLCSharp integration in setup project/release version

所以我已经为此犹豫了一段时间。

我的要求是在 wpf 应用程序中播放 .mp4 视频文件。听起来很简单,对吧?

起初,我使用内置 MediaElement class 并且一切正常。

但事实证明,MediaElement 是基于 Windows Media Player,对于使用 Windows 10 Pro N (or KN) 版本的人(包括我自己)来说,这些版本基本上是 Windows 10,视频没有播放,因为Windows Media Player不包括在内。

这也是通过将错误回调附加到 MediaElement 来报告的,导致消息:

"Windows Media Player version 10 or later is required"

当然,一种选择是向用户显示一条消息和 link 以下载功能包 (https://www.microsoft.com/en-us/software-download/mediafeaturepack),其中包括 Windows Media Player,但在我这些年使用Windows 应用程序,我从未见过任何应用程序 do/ask。这也是错误的——功能包不仅包含 WMP,而且用户可能不想让不必要的应用程序使他们的系统膨胀。这就是用户首先选择 Windows 10 Pro N (or KN) 的原因。

但是 - 其他应用程序是如何做到的? Slack、Discord 应用程序上的视频如何在我的 Windows 10 Pro N 上播放?

谷歌搜索和通用解决方案是使用 VideoLAN.LibVLC.Windows 框架,因为它是开源的、维护良好的并且多年来在多个平台上证明了自己。

好的,我得到它的 nuget 包,因为它是本机代码,我还下载了一个包装器库以在 WPF 中使用它 - LibVLCSharpLibVLCSharp.WPF.

我已经成功集成了视频播放,Debug版本一切正常。

现在是时候在 Release 版本中测试它了。我创建了一个新的 Setup project,构建它,安装它。

所以问题来了:

我的应用程序运行得很好,但是当我到达应该播放视频的部分时,出现异常错误:

Failed to load required native libraries. 
Have you installed the latest LibVLC package from nuget for your target platform?
Search paths include 
C:\Program Files (x86)\My app\libvlc\win-x64\libvlc.dll,
C:\Program Files (x86)\My app\libvlc\win-x64\libvlccore.dll; 
C:\Program Files (x86)\My app\libvlc\win-x64\libvlc.dll,
C:\Program Files (x86)\My app\libvlc\win-x64\libvlccore.dll; 
C:\Program Files (x86)\My app\libvlc.dll,

因此,在我的安装目录 C:\Program Files (x86)\My app\ 中,我找到了这两个 dll:

LibVLCSharp.dll
LibVLCSharp.WPF.dll

我检查了 Debug 版本的文件夹(因为它在那里工作得很好),我发现我还有一个 libvlc 文件夹作为生成器,内容为:

libvlc
- win-x64
-- hrtfs
-- locale
-- lua
-- plugins
-- libvlc.dll
-- libvlc.lib
-- libvlccore.dll
-- libvlccore.lib
- win-x86
-- hrtfs
-- locale
-- lua
-- plugins
-- libvlc.dll
-- libvlc.lib
-- libvlccore.dll
-- libvlccore.lib

我将该文件夹复制到我的安装目录,现在正在播放视频。 好的,我可以在安装过程中自动复制该文件夹。

但是现在的问题是size.

我的应用程序大小为 10 MB。 libvlc 文件夹的大小为 324 MB。 一个 10 MB 的小应用程序突然增长到 334 MB 是非常不可接受的。我会理解增加 10-20 MB,但不会增加这么多。

我知道,我可以创建两个单独的安装 - 一个用于 x64,一个用于 x86 系统。 太棒了,大小一分为二。

然后通过反复试验,我从那些文件夹中删除了我的应用程序可以在没有它们的情况下仍然可以播放视频的内容。

我剩下这个结构,它运行良好:

libvlc
- win-x64
-- plugins
-- libvlc.dll
-- libvlccore.dll

但它仍然有 125 MB 的重量。如果我从插件文件夹中删除任何内容,应用程序就会崩溃。

有没有一种 better/correct 方法可以将这个“libvlc”文件夹包含到我的发布版本中,而不会增加我的安装程序大小?

也许有另一个更轻量级的框架可以播放 .mp4 个文件?

我是不是跳错兔子洞了?

======================更新================= =====

已解决,感谢@cube45建议。

的确,我可以删除我不需要的插件,从而节省space(我最初删除了一个必需的,所以我认为所有都是强制性的,只是不幸)。

再一次,通过反复试验,我只留下了成功显示视频所需的那些文件。

结果列表:

libvlc
- win-x64
-- libvlc.dll
-- libvlccore.dll
-- plugins
--- access
---- libimem_plugin.dll
--- codec
---- libavcodec_plugin.dll
---- libd3d11va_plugin.dll
--- video_output
---- libdirect3d9_plugin.dll
---- libdirect3d11_plugin.dll
---- libdrawable_plugin.dll
---- libvmem_plugin.dll

x86 配置相同。

主要问题,为什么 libvlc 文件夹没有在安装目录中生成,是因为我需要为该目录​​显式添加内容输出。

我这样做的:

1. Right clicked on **my setup project -> View -> File System**
2. Right clicked on **Application Folder -> Add -> Project Output**
3. Selected **Content Files -> Ok**

瞧 - 现在 libvlc 文件夹及其内容包含在安装程序文件中并放置在安装目录中。

但是,即使压缩后,安装程序文件现在也有 140 MB,因为它包括 整个 libvlc 文件夹。我们只需要包含我们需要的那些文件并跳过其余的。

这就是提供的link@cube45派上用场的地方。 我们 select 只有我们需要的那些 files/folders 的过程称为 Cherry picking。所以我在 *.csproj 文件中添加了以下内容:

  <ItemGroup>
    <VlcWindowsX64IncludeFiles Include="libvlc.dll" />
    <VlcWindowsX64IncludeFiles Include="libvlccore.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\access\libimem_plugin.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\codec\libavcodec_plugin.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\codec\libd3d11va_plugin.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\video_output\libdirect3d9_plugin.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\video_output\libdirect3d11_plugin.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\video_output\libdrawable_plugin.dll" />
    <VlcWindowsX64IncludeFiles Include="plugins\video_output\libvmem_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="libvlc.dll" />
    <VlcWindowsX86IncludeFiles Include="libvlccore.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\access\libimem_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\codec\libavcodec_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\codec\libd3d11va_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\video_output\libdirect3d9_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\video_output\libdirect3d11_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\video_output\libdrawable_plugin.dll" />
    <VlcWindowsX86IncludeFiles Include="plugins\video_output\libvmem_plugin.dll" />
  </ItemGroup>

瞧 - 现在我的安装文件只有 23 MB,完全可以接受!

哦,那个大小可以减少一半,因为这是为 Any CPU 配置构建的。因此,如果我将此安装分成两个单独的安装,重量将约为 11.5 MB(但随后会出现一系列全新的问题,因此我不会深入研究)。

长话短说 - 成功!

所以有几件事:

Ok, I get it's nuget package, and since it is native code, I also download a wrapper libraries to use it in WPF - LibVLCSharp and LibVLCSharp.WPF.

你只需要引用LibVLCSharp.WPFVideoLAN.LibVLC.WindowsLibVLCSharp.WPF项目的依赖

I check the Debug version's folder (because it was working just fine there) and I see that I also have a libvlc folder being generater there, with contents:

Release 文件夹中也应该有它。如果不是,则 VideoLAN.LibVLC.Windows 或您使用它的方式可能有问题。

I understand, that I can create two seperate installations - one for x64 and one for x86 systems.

是的,这样可以避免两次嵌入 libvlc,这就是我的建议

If I delete anything from plugins folder, app crashes.

这就是您应该自定义的方式,但是您需要自己弄清楚您真正需要什么(您可能只需要“文件”访问插件,不需要 gui 插件,不需要 mux...) .我建议您查看此文档:https://code.videolan.org/videolan/libvlc-nuget/-/blob/master/cherry-picking.md

如果这对你来说不够苗条(例如,codec/libavcodec_plugin.dll 对你来说仍然太重),恐怕你必须自己构建 libvlc。警告:在公园散步可不是什么好事。

Perhaps there is another, more lightweight framework that can play .mp4 files?

我只知道 FFMediaElement 和其他基于 ffmpeg 的项目,但我不确定 ffmpeg 许可,我自己也没有测试它们。