代码之家  ›  专栏  ›  技术社区  ›  mHelpMe

如何在MediaPlayer中播放语音合成器中的wav文件

  •  2
  • mHelpMe  · 技术社区  · 6 年前

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

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

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

    更新

    使用示例 on this page 我可以播放我的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 回复  |  直到 6 年前
        1
  •  6
  •   Pretasoc    6 年前

    默认情况下 synthesizer.SpeakAsync 将使用扬声器作为输出。将输出设置为wave文件。如果你现在打电话 合成器.SpeakAsync 合成器将与wave文件“对话”,在本例中,这意味着写入wave文件。所以呢 合成器.SpeakAsync 播放任何可听见的声音。

    参见示例 here

    一旦创建了wav文件,就可以用媒体播放器打开它。

    synthesizer.SpeakAsync("Youre text goes here");
    var pathUri = new Uri(path);
    player.Open(pathUri.AbsoluteUri);
    
        2
  •  2
  •   Dipen Shah    6 年前

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

    令我惊讶的是,每次我播放某个东西时,处理程序都会被以下内部异常调用: MILAVERR_INVALIDWMPVERSION (Exception from HRESULT: 0x88980507) .

    this post 其中指出,由于反竞争的政府政策,在少数国家视窗10是失踪的共同媒体应用程序。

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

    private SoundPlayer player = new SoundPlayer();
    player.SoundLocation = System.IO.Path.Combine(path, fileName);
    player.Play();