【问题标题】:play wav in prism application在 prism 应用程序中播放 wav
【发布时间】:2012-09-01 08:24:04
【问题描述】:

我有带有一些模块的 wpf prism 应用程序。一个模块中包含文件夹“sounds”和 mysound.wav,wav 文件具有构建操作的“资源”值(打包在结果 dll 中)。我想播放这个 wav 文件,但我无法为其创建有效的 Uri。

Uri(@"pack://application:,,,/MyGame;component/sounds/mysound.wav")

不工作。

【问题讨论】:

    标签: wpf prism


    【解决方案1】:

    它说“应用程序”权限用于引用编译时已知的内容(即您有对程序集的引用)。

    因为您使用的是 Prism 并且模块是动态加载的,这可能意味着您不能使用“应用程序”来引用它们...(但另一方面,这可能意味着如果程序集被加载到应用程序中,然后“应用程序”可以解析为该程序集中的项目)。

    因此,如果您将 WAV 文件标记为“内容”,则该文件将是松散的,您可以使用“siteoforigin”来访问它(也可能是“应用程序”,具体取决于您对 Microsoft 链接的解释)。

    确保将“复制到输出目录”设置为“始终复制”或“如果较新则复制”,以便将 WAV 文件输出到您的构建目录。

    但是,您不想要“松散”的文件,所以搜索继续......


    MediaPlayerMediaElementMediaTimeline 只允许通过 .Source 属性设置媒体“文件”...而且只需要一个 Uri。

    没有任何方法可以将“源”设置为来自Stream...如果有,那么您可以在您的 Prism 模块中有一个方法来按名称查找/加载声音文件和将其作为流返回。

    (您可能不喜欢听到 Silverlight 可以从 Stream 加载媒体对象)。


    以下是将嵌入在程序集/模块中的 WAV 文件数据提供给 MediaElement、MediaPlayer 或 MediaTimeline 的其他一些想法:

    • 将您的 WAV 文件嵌入到模块中...但是当您需要播放它们时...您将 WAV 内容写入临时文件,然后设置 Uri 以指向该临时文件.

    • 尝试使用可以接受 Streams 的 Silverlight 版本的 MediaElement / MediaPlayer,并编写您的模块以使其使用 Silverlight...。在 WPF 应用程序中托管 Silverlight 有各种技巧... .我不知道这会有多好。

    • 注册您自己的“协议”,然后可以在 Uri 中使用。

      使用 WebRequest.RegisterPrefix 注册您的协议前缀,以及 为它提供一个 WebRequest 工厂,即实现的东西 IWebRequestCreate.

      然后通过从 WebRequest 派生来创建您自己的 WebRequest 类型 ...并让该工厂返回它的实例.....您的 实施将管理从资源请求数据 流....您可以通过 GetResourceStream 和 .Stream 访问 返回的 StreamResourceInfo 中的属性。

      然后你可以使用类似的东西,例如新的 Uri("loadwavfrom://mysound.wav")

    • 也许使用 PackageStore....将所有 WAV 文件作为部分添加到存储中...然后将 Uri 获取到该包中的“部分”并将其作为 .Source 传递。

    • http://msdn.microsoft.com/en-us/library/3tf230ta

    • 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/

    【讨论】:

    • 感谢您的回复。但结果我必须将我的 WAV 文件打包在 dll 中并从 dll 中调用它。如果我要使用像你这样的方法,我必须在 Shell 文件夹中创建文件夹“声音”,但这是不可能的,因为每个游戏都有不同声音的文件夹。我检查了我的项目结构的屏幕截图:在左侧面板上有带有动态加载模块的 shell.exe 的结果 shell 文件夹,在右侧面板上有一个带有 WAV 文件参数的解决方案结构。
    • 问题更加全球化!音频的 MediaTimeline 是否支持 PackURI?我试图检查一些代码 Application.GetResourceStream(new Uri(@"pack://application:,,,/MyGame01;component/sounds/reelstop.wav")) 并且它有效,我认为 MediaTimeline 有问题
    • 因此,归根结底,如果您将 WAV 文件嵌入到应用程序外部的程序集中...无法通过以下方式解析这些嵌入的 WAV 文件来源。 不是外部的!我想从放置在“MyGame01”的views文件夹中的类中获取源代码以及放置在其中的声音,我不需要从外部程序集中获取smt。
    • 你能显示你正在使用的 XAML...你说你使用 MediaTimeLine 但它不起作用......如果你使用 MediaElement/MediaPlayer 并在上面设置 Source 会怎样?跨度>
    • 这样会更容易...把它放在 DropBox 或其他地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多