简体   繁体   English

WPF:安装项目/发布版本中的 LibVLCSharp 集成

[英]WPF: LibVLCSharp integration in setup project/release version

So I have been against a wall for this one for a while now.所以我已经为这个而靠墙有一段时间了。

My requirement is to play .mp4 video file in a wpf application.我的要求是在 wpf 应用程序中播放.mp4视频文件。 Sounds simple enough, right?听起来很简单,对吧?

At first, I used built-in MediaElement class and everything worked.起初,我使用了内置的MediaElement class,一切正常。

But it turns out, MediaElement is based on Windows Media Player , and for people (myself included) who are using Windows 10 Pro N (or KN) versions, which are basically stripped-down versions of Windows 10, videos are not playing, because Windows Media Player is not included.但事实证明, MediaElement是基于Windows Media Player ,对于正在使用Windows 10 Pro N (or KN)版本的人(包括我自己),它们基本上是 ZAEA23489CE3AAA966406EBB28E0 的精简版本,因为视频不播放Windows Media Player不包括在内。

That is also reported by attaching an error callback to MediaElement , resulting in message:这也通过将错误回调附加到MediaElement来报告,从而产生消息:

"Windows Media Player version 10 or later is required"

Of course, one option is to show user a message and a link to download the feature pack ( https://www.microsoft.com/en-us/software-download/mediafeaturepack ), which includes Windows Media Player , but in all my years using Windows apps, I have NEVER seen any app do/ask that.当然,一种选择是向用户显示一条消息和一个下载功能包的链接( https://www.microsoft.com/en-us/software-download/mediafeaturepack ),其中包括Windows Media Player ,但总的来说我多年来使用 Windows 应用程序,我从未见过任何应用程序这样做/问过。 It is also wrong - the feature pack comes with alot more than just WMP and user might not want to bloat their system with unnecessary apps.这也是错误的 - 功能包附带的不仅仅是 WMP,用户可能不想用不必要的应用程序来膨胀他们的系统。 That's why user chose Windows 10 Pro N (or KN) in the first place.这就是为什么用户首先选择Windows 10 Pro N (or KN)

But then - how do other apps do it?但是然后 - 其他应用程序如何做到这一点? How are videos on Slack, Discord apps played on my Windows 10 Pro N ? Slack、Discord 应用程序上的视频如何在我的Windows 10 Pro N上播放?

A bit of googling and general solution is to use VideoLAN.LibVLC.Windows framework, because it is open-sourced, well maintained and has proven itself over the years on multiple platforms.一些谷歌搜索和通用解决方案是使用VideoLAN.LibVLC.Windows框架,因为它是开源的,维护良好,并且多年来在多个平台上证明了自己。

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

I have successfully integrated video playback, everything works in Debug version.我已经成功集成了视频播放,一切都在 Debug 版本中运行。

Now it's time to test it in Release version.现在是时候在 Release 版本中测试它了。 I create a new Setup project , build it, install it.我创建了一个新的Setup project ,构建它,安装它。

So here's the problem:所以问题来了:

My app runs just fine, but when I get to the section where video is supposed to play, I get an exception error:我的应用程序运行得很好,但是当我到达应该播放视频的部分时,出现异常错误:

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,

So, in my install directory C:\Program Files (x86)\My app\ , I find these 2 dlls:因此,在我的安装目录C:\Program Files (x86)\My app\中,我找到了这两个 dll:

LibVLCSharp.dll
LibVLCSharp.WPF.dll

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:我检查了 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

I copy that folder to my install directory and videos are now playing.我将该文件夹复制到我的安装目录,现在正在播放视频。 Ok, I can automate that folder copy during installation.好的,我可以在安装过程中自动复制该文件夹。

But now the problem is size .但现在的问题是尺寸

My app is 10 MB in size.我的应用程序大小为 10 MB。 That libvlc folder is 324 MB in size.libvlc文件夹大小为 324 MB。 It is quite unacceptable for a small 10 MB app to suddenly grow to be 334 MB large.一个 10 MB 的小应用程序突然增长到 334 MB 大是非常不可接受的。 I would understand 10-20 MB increase, but not by this much.我会理解增加 10-20 MB,但不会增加这么多。

I understand, that I can create two seperate installations - one for x64 and one for x86 systems.我知道,我可以创建两个单独的安装 - 一个用于x64 ,一个用于x86系统。 Great, that splits size in half.太好了,这把大小分成了两半。

Then by trial and error, I removed things from those folders that my app can live without and still play the videos.然后通过反复试验,我从那些文件夹中删除了我的应用程序可以不存在并仍然播放视频的内容。

I am left with this structure, which runs fine:我留下了这个运行良好的结构:

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

But it still weighs 125 MB.但它仍然重 125 MB。 If I delete anything from plugins folder, app crashes.如果我从插件文件夹中删除任何内容,应用程序就会崩溃。

Is there a better/correct way of including this "libvlc" folder to my Release version, without it blowing up my installer size?有没有更好/正确的方法将此“libvlc”文件夹包含到我的发布版本中,而不会增加我的安装程序大小?

Perhaps there is another, more lightweight framework that can play .mp4 files?也许还有另一个更轻量级的框架可以播放.mp4文件?

Did I jump into the wrong rabbit hole?我是不是跳错了兔子洞?

====================== Update ====================== ====================== 更新======================

Solved, thanks to @cube45 suggestion.解决了,感谢@cube45 的建议。

Indeed, I can delete plugins that I don't need, thus saving space (I initially deleted a required one, so I assumed all were mandatory, simply unlucky).事实上,我可以删除不需要的插件,从而节省空间(我最初删除了一个必需的插件,所以我认为所有插件都是强制性的,只是不走运)。

So again, by trial and error I only left those files that were needed for successfully displaying video.因此,再次通过反复试验,我只留下了成功显示视频所需的那些文件。

The resulting list:结果列表:

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

Same for x86 configuration. x86 配置相同。

The main problem, why the libvlc folder wasn't being generated in the install directory, was because I needed to explicitly add a content output for that directory.主要问题,为什么libvlc文件夹没有在安装目录中生成,是因为我需要为该目录显式添加内容 output 。

I did so by:我是这样做的:

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

And voila - now libvlc folder with it's contents are included in the installer file and placed in install directory.瞧——现在libvlc文件夹及其内容包含在安装程序文件中并放置在安装目录中。

However, even compressed, the installer file now is 140 MB large, because it included whole libvlc folder.但是,即使压缩,安装程序文件现在也有 140 MB 大,因为它包含整个libvlc文件夹。 We need to include only those files we need and skip the rest.我们只需要包含我们需要的那些文件并跳过 rest。

So that's where the link @cube45 provided came in handy.这就是@cube45提供的链接派上用场的地方。 Process, where we select only those files/folders that we need, is called Cherry picking .过程,我们 select 只有那些我们需要的文件/文件夹,被称为Cherry picking So I added following to *.csproj file:所以我在*.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>

And voila - now my installation file weighs only 23 MB, which is completely acceptable!瞧——现在我的安装文件只有 23 MB,这是完全可以接受的!

Oh and that size can be cut down by half, because this was built for Any CPU configuration.哦,这个尺寸可以减半,因为这是为Any CPU配置构建的。 So if I split this installation into two seperate ones, the weight would be ~11.5 MB (but then a whole new set of problems would occur, so I'm not gona delve into that).因此,如果我将此安装分成两个单独的安装,重量将约为 11.5 MB(但随后会出现一系列全新的问题,所以我不会深入研究)。

Long story short - success!长话短说——成功!

So a few things:所以有几点:

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

You only need to reference LibVLCSharp.WPF and VideoLAN.LibVLC.Windows , LibVLCSharp is a dependency of the .WPF project只需要引用LibVLCSharp.WPFVideoLAN.LibVLC.Windows即可, LibVLCSharp.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:我检查了 Debug 版本的文件夹(因为它在那里工作得很好),我看到我那里还有一个 libvlc 文件夹作为生成器,内容:

You should also have that in the Release folder too.您也应该在 Release 文件夹中拥有它。 If not, something might be wrong with VideoLAN.LibVLC.Windows or the way you're using it.如果不是,那么 VideoLAN.LibVLC.Windows 或您使用它的方式可能有问题。

I understand, that I can create two seperate installations - one for x64 and one for x86 systems.我知道,我可以创建两个单独的安装 - 一个用于 x64,一个用于 x86 系统。

Yes, that would avoid embedding libvlc twice, that's what I'd recommend是的,这将避免两次嵌入 libvlc,这就是我推荐的

If I delete anything from plugins folder, app crashes.如果我从插件文件夹中删除任何内容,应用程序就会崩溃。

That's the way you should customize it, but you would need to figure out by yourself what you really need (you'll likely only need the "file" access plugin, no gui plugin, no mux...).这就是你应该自定义它的方式,但你需要自己弄清楚你真正需要什么(你可能只需要“文件”访问插件,没有 gui 插件,没有 mux ......)。 I'd recommend taking a look at this documentation: https://code.videolan.org/videolan/libvlc-nuget/-/blob/master/cherry-picking.md我建议看看这个文档: https://code.videolan.org/videolan/libvlc-nuget/-/blob/master/cherry-picking.md

If that's not slim enough for you (for example, codec/libavcodec_plugin.dll is still too heavy for you), I'm afraid you'll have to build libvlc by yourself.如果这对您来说还不够苗条(例如,codec/libavcodec_plugin.dll 对您来说仍然太重),恐怕您必须自己构建 libvlc。 Warning: it's not a nice walk in the park.警告:这不是在公园里散步的好地方。

Perhaps there is another, more lightweight framework that can play.mp4 files?也许还有另一个更轻量级的框架可以播放.mp4 文件?

I only know about FFMediaElement and other ffmpeg-based projects, but I'm unsure about the ffmpeg licensing, and I did not test them myself.我只知道 FFMediaElement 和其他基于 ffmpeg 的项目,但我不确定 ffmpeg 许可,我自己没有测试它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM