【问题标题】:How to play a WPF Sound File resource如何播放 WPF 声音文件资源
【发布时间】:2013-02-28 20:39:46
【问题描述】:

我正在尝试在我的 WPF 应用程序中播放声音文件。目前我有以下电话:

private void PlaySound(string uriPath)
{
    Uri uri = new Uri(@"pack://application:,,,/Media/movepoint.wav");
    var player = new MediaPlayer();
    player.Open(uri);
    player.Play();
}

现在,如果我将 Media/movepoint.wav 指定为构建操作 Content 并将其加载为相对或绝对文件路径,它工作正常,所以我怀疑这与 Pack URI 有关,但我不能一辈子我想知道什么。

目标是将文件存储为资源,使其在输出目录中不可用。我可以提供 WAV 副本或 MP3 副本。

【问题讨论】:

    标签: c# .net wpf media-player


    【解决方案1】:

    我尝试使用图像文件进行此操作,就 uri 而言,它与声音文件的工作方式相同,因为它只是另一种资源。我使用了下面的代码,它与你所拥有的基本匹配。

    new Uri(@"pack://application:,,,/Resources/logo.png")
    

    确保您的“媒体”文件夹没有嵌套在任何其他文件夹中。如果是,您还需要包含该文件夹。

    使用 .NET Framework 4.0,VS2012。

    This link 很好地描述了整个“包装”方案。

    编辑

    有关此主题的更多研究似乎表明,您想要做的事情可能无法使用音频或视频文件。以下内容摘自this MSDN page的备注部分。

    虽然你可以在 Extensible 中声明这个类的一个实例 应用程序标记语言 (XAML),您无法加载和播放其媒体 不使用代码。若要仅在 XAML 中播放媒体,请使用 MediaElement。 此外,如果您在 XAML 中声明一个实例,则唯一的实际用途是 Player 属性的填充属性元素语法。

    在您的应用程序中分发媒体时,您不能使用媒体 文件作为项目资源。在您的项目文件中,您必须改为设置 媒体类型为 Content 并将 CopyToOutputDirectory 设置为 PreserveNewest 或 Always。

    MediaPlayer 可以在两种不同的模式下使用,具体取决于是什么 驱动播放器:独立模式或时钟模式。在独立 模式下,MediaPlayer 类似于图像和媒体打开 通过 Open 方法驱动播放。在时钟模式下, MediaPlayer 可以被认为是动画的目标,因此 它将在 Timing 中有相应的 Timeline 和 Clock 条目 控制播放的树。有关媒体模式的更多信息,请参阅 多媒体概述。

    MediaPlayer 与 MediaElement 的不同之处在于它不是 可以直接添加到用户界面 (UI) 的控件 应用。要显示使用 MediaPlayer 加载的媒体,一个 VideoDrawing 或必须使用 DrawingContext。

    【讨论】:

    • 乍一看我有点困惑,因为我们的 Pack URI 语法是相同的。然而,“Resouces”有什么特别之处吗?现在媒体文件夹位于程序集的根目录。我需要做/Resources/Media/吗?谢谢
    • 刚试过 PlaySound("pack://application:,,,/Resources/Media/movepoint.mp3");而且没有运气(是的,我更新了代码):)
    • 感谢您的澄清。考虑到版权侵权风险,我可以理解他们为什么会这样做。我已将您的答案标记为正确。谢谢
    • 这不是版权问题。 WPF/XAML 提供的 MediaElement 和 MediaPlayer 类都使用外部 Windows Media Player 程序来处理音频/视频文件。因为 Windows Media Player 是一个单独的程序并且没有嵌入到 .NET 框架中,所以它不能像访问其他 pack-URI 资源一样访问编译到您的程序中的资源文件。相反,Windows Media Player 只能播放从 Web 服务流式传输或存储在磁盘文件中的媒体。
    【解决方案2】:

    以下似乎适用于 .NET Framework 4.5:

    var sri = Application.GetResourceStream(new Uri("pack://application:,,,/MyAssemblyName;component/Resources/CameraShutter.wav"));
    
    if ((sri != null)) 
    {
      using (s == sri.Stream) 
      {
        System.Media.SoundPlayer player = new System.Media.SoundPlayer(s);
        player.Load();
        player.Play();
      }
    }
    

    CameraShutter.wav 作为 Resource 嵌入到我的项目中(并位于 Resources 子文件夹中,如包 URI 中所示)。

    【讨论】:

      【解决方案3】:

      如果 .wav 文件是嵌入式资源,您也可以将 Stream 加载到 SoundPlayer。请注意,在此示例中,资源位于项目根目录中名为 Resources 的文件夹中,这就是它被写为 {0}.Resources.{1} 的原因。

      //the wav filename
      string file = "emergency_alarm_002.wav";
      
      //get the current assembly
      var assembly = System.Reflection.Assembly.GetExecutingAssembly();
      
      //load the embedded resource as a stream
      var stream = assembly.GetManifestResourceStream(string.Format("{0}.Resources.{1}", assembly.GetName().Name, file));
      
      //load the stream into the player
      var player = new System.Media.SoundPlayer(stream);
      
      //play the sound
      player.Play();
      

      【讨论】:

        【解决方案4】:

        这似乎也有效,而且可能比那一长串包装或组装的东西更容易记住.. 我打开 Resources.resx 并在其中拖动了一个名为 aa_pickup.wav 的声音文件,然后将其属性设置为 Copy to Output Dir = Copy Always。

        System.IO.Stream str = Properties.Resources.aa_pickup;
        System.Media.SoundPlayer snd = new System.Media.SoundPlayer(str);
        snd.Play();
        

        现在..如果我能弄清楚如何改变音量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-15
          • 2014-05-09
          • 2010-09-12
          • 1970-01-01
          • 1970-01-01
          • 2011-05-06
          相关资源
          最近更新 更多