我有带有一些模块的 wpf prism 应用程序。一个模块中包含文件夹“sounds”和 mysound.wav,wav 文件具有构建操作的“资源”值(打包在结果 dll 中)。我想播放这个 wav 文件,但我无法为它创建有效的 Uri。
Uri(@"pack://application:,,,/MyGame;component/sounds/mysound.wav")
不工作。
它说“应用程序”权限用于引用编译时已知的内容(即您有对程序集的引用)。
因为您正在使用 Prism 并且模块是动态加载的,所以这可能意味着您不能使用“应用程序”来引用它们......(但另一方面,这可能意味着如果程序集被加载到应用程序中,那么“应用程序”可以解析为该程序集中的项目)。
因此,如果您将 WAV 文件标记为“内容”,那么该文件将是松散的,您可以使用“siteoforigin”来访问它(也可能是“应用程序”,具体取决于您对 Microsoft 链接的解释)。
确保将“复制到输出目录”设置为“始终复制”或“如果较新则复制”,以便将 WAV 文件输出到您的构建目录。
但是,您不想要“松散”的文件,所以搜索继续......
MediaPlayer
,MediaElement
并且MediaTimeline
只允许通过 .Source 属性设置媒体“文件”......并且只需要一个 Uri。
没有任何方法可以将“源”设置为来自Stream
...如果有,那么您可以在您的 Prism 模块中有一个方法来按名称查找/加载声音文件并将其作为流返回。
(您可能不喜欢听到 Silverlight 可以从 Stream 加载媒体对象)。
以下是一些其他想法,用于将嵌入在您的程序集/模块中的 WAV 文件的数据提供给 MediaElement、MediaPlayer 或 MediaTimeline:
将您的 WAV 文件嵌入到模块中...但是当您需要播放它们时...您将 WAV 内容写入临时文件,然后设置 Uri 以指向该临时文件。
尝试并使用可以接受流的 MediaElement / MediaPlayer 的 Silverlight 版本,并编写您的模块以使其使用 Silverlight ....在 WPF 应用程序中托管 Silverlight 有各种技巧......这将如何工作我不知道。
注册您自己的“协议”,然后您可以在 Uri 中使用。
使用 WebRequest.RegisterPrefix 注册您的协议前缀,并为它提供一个 WebRequest 工厂,即实现 IWebRequestCreate 的东西。
然后通过从 WebRequest 派生来创建您自己的 WebRequest 类型......并让该工厂返回它的实例......您的实现将管理从资源流中请求数据......您可以通过 GetResourceStream 和返回的 StreamResourceInfo 中的 .Stream 属性。
然后你可以使用类似 new Uri("loadwavfrom://mysound.wav")
也许使用PackageStore ....将所有WAV文件作为部件添加到商店......然后将Uri获取到该包中的“Part”并将其作为.Source传递。
http://hackingsilverlight.blogspot.co.uk/2009/12/silverlight-hosting-in-wpf.html
更新:
我尝试了 RegisterPrefix 和 PackageStore,但他们不允许它工作。
看到这个帖子:
因为 MediaPlayer/MediaTimeline 等在下面使用 Windows Media Player,......当你认为 Windows Media 是一个本机应用程序时......它是否可以从 .NET 程序集中访问“资源”是非常值得怀疑的。
因此,从外观上看,它不知道如何访问媒体,除非通过本地或基于 HTTP 的 Uris。
当您使用指向“内容”文件的“应用程序”包 URI 时,当将其提供给下面的媒体播放器时,它必须映射到本地文件 URL。
所以我能想到的可能的解决方法是:
将 WAV 文件保留为“资源”...但根据需要将数据写入临时文件...并将该临时文件作为 Uri 提供。
将 WAV 文件作为“内容”放入您的项目中...并为该文件提供正确的 Uri
编写您自己的基本本地 HTTP 服务器/或使用 IIS 并“托管”WAV 文件……然后您可以使用基于 HTTP 的 URL 来访问该文件。(我知道很多麻烦)。
使用不同的媒体播放器控件....一个支持访问 .NET 程序集中的资源....或允许您提供一个代理,您可以在其中向播放器提供数据。你可以看看http://vlcdotnet.codeplex.com/