当前位置: 首页 > 知识库问答 >
问题:

如何在MediaPlayer中播放SpeechSynthesizer中的wav文件

壤驷俊逸
2023-03-14

我有一些代码(在WPF应用程序中),当一些文本被复制到剪贴板时,它将使用SpeechSynthesizer读出文本(我所有的代码都在这篇文章的底部)。

然而,以这种方式播放音频不允许我暂停、倒带或播放等。

所以我想我应该使用SpeechSynthesis来保存一个wav文件。然后使用MediaPlayer类,因为它很容易暂停、播放等。

但是,保存文件后,该文件不会在我的媒体播放器中播放。这个文件很好,当我手动运行它时,它工作得非常好。我想使用MediaPlayer,因为我已经为它编写了一些代码。

最新消息

使用本页上的示例,我可以播放我的wav文件。我不知道为什么我的代码中没有运行该文件?在上面的例子中,我知道他们正在使用一个媒体元素,并在我的代码中尝试了这一点。我不是只播放视频和音频,因此我使用MediaPlayer。

这是我目前所有的代码。文件正在保存,但媒体播放器没有播放任何内容。据我所知,我的计算机上的音量很大。

     using System;
     using System.Windows;
     using System.Windows.Controls;
     using System.Windows.Media;
     using System.Windows.Media.Imaging;
     using System.Windows.Interop;
     using System.IO;
     using System.Speech.Synthesis;
     using System.Windows.Controls.Primitives;
     using System.Windows.Threading;

     namespace CSWPFClipboardViewer
     {
      /// <summary>
      /// Main window of the application, also will be used to get clipboard messages.
      /// </summary>
      public partial class MainWindow : Window
      {
        #region Private fields

        /// <summary>
        /// Next clipboard viewer window 
        /// </summary>
        private IntPtr hWndNextViewer;

        /// <summary>
        /// The <see cref="HwndSource"/> for this window.
        /// </summary>
        private HwndSource hWndSource;

        private bool isViewing;

        private MediaPlayer mePlayer = new MediaPlayer();

        #endregion

        public MainWindow()
        {
           InitializeComponent();
        }

        #region Clipboard viewer related methods

        private void InitCBViewer()
        {
            WindowInteropHelper wih = new WindowInteropHelper(this);
            hWndSource = HwndSource.FromHwnd(wih.Handle);

            hWndSource.AddHook(this.WinProc);   // start processing window messages
            hWndNextViewer = Win32.SetClipboardViewer(hWndSource.Handle);   // set this window as a viewer
            isViewing = true;
        }

        private void CloseCBViewer()
        {
            // remove this window from the clipboard viewer chain
           Win32.ChangeClipboardChain(hWndSource.Handle, hWndNextViewer);

           hWndNextViewer = IntPtr.Zero;
           hWndSource.RemoveHook(this.WinProc);
           pnlContent.Children.Clear();
           isViewing = false;
        }

        private void DrawContent()
        {
           pnlContent.Children.Clear();

           if (Clipboard.ContainsText())
           {
              string path = @"C:\Users\MyPath\";
              string fileName = "MyFile.wav";

              // delete previous file if it exists
              if (File.Exists(path + fileName))
                  File.Delete(path + fileName);

              // we have some text in the clipboard.
              TextBox tb = new TextBox();
              tb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
              tb.FontSize = 24;
              tb.Text = Clipboard.GetText();
              tb.IsReadOnly = true;
              tb.TextWrapping = TextWrapping.Wrap;
              pnlContent.Children.Add(tb);

              SpeechSynthesizer synthesizer = new SpeechSynthesizer();
              synthesizer.Volume = 100;  // 0...100
              synthesizer.Rate = 3;     // -10...10

              //Asynchronous
              synthesizer.SetOutputToWaveFile(path + fileName);
              synthesizer.SpeakCompleted += new EventHandler<SpeakCompletedEventArgs>(synth_SpeakCompleted);
              synthesizer.SpeakAsync(Clipboard.GetText());


             }
            else
            {
               Label lb = new Label();
               lb.Content = "The type of the data in the clipboard is not supported by this sample.";
               pnlContent.Children.Add(lb);
            }
         }

    private IntPtr WinProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case Win32.WM_CHANGECBCHAIN:
                if (wParam == hWndNextViewer)
                {
                    // clipboard viewer chain changed, need to fix it.
                    hWndNextViewer = lParam;
                }
                else if (hWndNextViewer != IntPtr.Zero)
                {
                    // pass the message to the next viewer.
                    Win32.SendMessage(hWndNextViewer, msg, wParam, lParam);
                }
                break;

            case Win32.WM_DRAWCLIPBOARD:
                // clipboard content changed
                this.DrawContent();
                // pass the message to the next viewer.
                Win32.SendMessage(hWndNextViewer, msg, wParam, lParam);
                break;
        }

        return IntPtr.Zero;
    }

    #endregion

    #region Control event handlers

    void synth_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
    {
        string path = @"C:\Users\MyPath\";
        string fileName = "MyFile.wav";

        mePlayer.Open(new Uri(path + fileName));
        mePlayer.Play();
    }

    private void btnSwitch_Click(object sender, RoutedEventArgs e)
    {
        // switching between start/stop viewing state
        if (!isViewing)
        {
            this.InitCBViewer();
            btnSwitch.Content = "Stop viewer";
        }
        else
        {
            this.CloseCBViewer();
            btnSwitch.Content = "Start viewer";
        }
    }

    private void btnClose_Click(object sender, RoutedEventArgs e)
    {
        this.Close();
    }

    private void Window_Closed(object sender, EventArgs e)
    {
        this.CloseCBViewer();
    }

    #endregion
    }
  }

C#Win32

    using System;
    using System.Runtime.InteropServices;

    namespace CSWPFClipboardViewer
    {
      /// <summary>
      /// This static class holds the Win32 function declarations and constants needed by
      /// this sample application.
      /// </summary>
      internal static class Win32
      {
         /// <summary>
         /// The WM_DRAWCLIPBOARD message notifies a clipboard viewer window that 
         /// the content of the clipboard has changed. 
         /// </summary>
         internal const int WM_DRAWCLIPBOARD = 0x0308;

         /// <summary>
         /// A clipboard viewer window receives the WM_CHANGECBCHAIN message when 
         /// another window is removing itself from the clipboard viewer chain.
         /// </summary>
    internal const int WM_CHANGECBCHAIN = 0x030D;

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern IntPtr SetClipboardViewer(IntPtr hWndNewViewer);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
   }
 }

XAML

 <Window x:Class="CSWPFClipboardViewer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Clipboard Viewer" Height="500" Width="640" Background="Black" Closed="Window_Closed">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Foreground="White" Margin="6,0,6,0">Clipboard content:</Label>

    <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right">
        <Button x:Name="btnSwitch" Width="90" Height="25" Content="Start viewer" Padding="3" Margin="6,6,6,6" Click="btnSwitch_Click" />
        <Button x:Name="btnClose" Width="90" Height="25" Content="Close" Padding="3" Margin="6,6,6,6" Click="btnClose_Click" />
    </StackPanel>

    <DockPanel x:Name="pnlContent" Grid.Row="1" Background="White" Margin="6,6,6,6" LastChildFill="True"/>
</Grid>

共有2个答案

弘浩博
2023-03-14

当我试图复制你的问题时,我发现了一些非常有趣的事情。令人惊讶的是,我也有同样的问题。为了调试它,我探索了MediaPlayer API,并在代码中添加了MediaFailed事件处理程序。

令我惊讶的是,每次我播放一些东西时,处理程序都会被以下内部异常调用:MILAVERR\u INVALIDWMPVERSION(来自HRESULT:0x88980507的异常)

更多的谷歌搜索导致了这篇文章,文章指出,由于少数国家的反竞争政府政策,视窗10缺少常见的媒体应用程序。

要解决此问题,您可以确保已安装WMP 10或更高版本,或者只需使用SoundPlayer

private SoundPlayer player = new SoundPlayer();
player.SoundLocation = System.IO.Path.Combine(path, fileName);
player.Play();
东方化
2023-03-14

默认情况下,合成器。SpeakAsync将使用扬声器作为输出。将输出设置为波形文件。如果您现在调用合成器。SpeakAsync合成器将对波形文件“说话”,在本例中,这意味着写入波形文件。所以合成器。SpeakAsync不会播放任何声音。

有关更多指南,请参见此处的示例

创建wav文件后,您可以使用媒体播放器将其打开。

synthesizer.SpeakAsync("Youre text goes here");
var pathUri = new Uri(path);
player.Open(pathUri.AbsoluteUri);
 类似资料:
  • 问题内容: 我尝试pygame播放wav文件,如下所示: 但是它改变了声音,我不知道为什么!我阅读了此链接解决方案,但无法解决播放wave文件的问题! 对于此解决方案,我不知道应该导入什么? 对于这个解决方案/ dev / dsp在新版本的linux中不存在: 而当我尝试pyglet它给我这个错误: 问题答案: 您可以使用PyAudio。我的Linux上的一个示例可以正常工作:

  • 我目前正在尝试学习音频编程。我的目标是打开一个wav文件,提取所有内容并使用RtAudio播放示例。 我制作了一个WaveLoader类,让我提取样本和元数据。我用这本指南来做这件事,我用010编辑器检查了一切都是正确的。这是010编辑器的快照,显示了结构和数据。 这就是我在WaveLoader类中存储原始样本的方式: 如果我打印出我得到的每个样本:1, -3, 4, -5... 问题是,我不确定

  • 问题内容: 我正在尝试使用Java播放* .wav文件。我希望它执行以下操作: 按下按钮时,播放一声短促的哔声。 我已经用谷歌搜索了,但是大多数代码都没有用。有人可以给我一个简单的代码片段来播放.wav文件吗? 问题答案: 没有Java反射的解决方案 , ) Java反射会降低性能。跑步:

  • 在我的应用程序中,我使用下面的代码使用带有Stream_Notification的MediaPlayer播放一个简短的通知声音。问题是,当应用播放通知声音,同时音乐播放器应用在后台播放音乐时,通知声音会中断(暂停)音乐播放。如何才能让自己APP的通知声音与背景音乐播放同步播放?多谢了。

  • 问题内容: 如何在Java应用程序中播放和文件?我正在使用。我尝试在互联网上查找类似以下示例的内容: 但是,这只会播放文件。 问题答案: 如何在Java应用程序中播放和文件?我正在使用。我尝试在互联网上查找类似以下示例的内容: 但是,这只会播放文件。

  • } 我不知道如何用java从我的电脑(不是从URL)播放wav文件。我确信我把它放在了正确的地方,SRC(我还把它放在了几乎所有的地方以防万一...). 第一次尝试来自http://www.cs.cmu.edu/~illah/CLASSDOCS/javasound.pdf,它给了我一个catch语句。 第二次尝试是把我的记录。mediafire上的wav文件。然而,这并没有奏效。线程“main”j