网上去找发现语音合成效果都差不多,没有太好的,TTS有点过于古老,然后发现SpeechSynthesizer不错
程序界面
废话不说上代码
PlayItem.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TextToSpeech.General
{
public class PlayItem
{
public string Content { get; set; }
public int Index { get; set; }
public int Lenght { get; set; }
}
}
主程序
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Speech.Synthesis;
using System.Windows;
using System.Windows.Forms;
using TextToSpeech.General;
using TextToSpeech.Properties;
namespace TextToSpeech
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
private SpeechSynthesizer speechSynthesizer = new SpeechSynthesizer();
private List<PlayItem> PlayData = new List<PlayItem>();
private int PlayLine = 0;
public MainWindow()
{
InitializeComponent();
this.Left = Settings.Default.Left;
this.Top = Settings.Default.Top;
this.Width = Settings.Default.Width;
this.Height = Settings.Default.Height;
}
private void Play()
{
PlayLine++;
LbPlayLine.Content = $"播放:{PlayLine.ToString()}行";
Play(PlayLine);
}
private void Play(int playLine)
{
if (playLine < PlayData.Count())
{
speechSynthesizer.SpeakAsync(PlayData[playLine].Content);
try
{
TbTextBox.Focus();
//选择指定行内容
TbTextBox.Select(PlayData[playLine].Index, PlayData[playLine].Lenght);
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
else
{
LbPlayLine.Content = $"播放结束:{PlayLine.ToString()}行";
}
}
private void synth_StateChanged(object sender, StateChangedEventArgs e)
{
if(e.State == SynthesizerState.Ready)
{
Play();
}
}
private void Button_Click_Open(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog fileDialog = new System.Windows.Forms.OpenFileDialog();//打开文件对话框
fileDialog.InitialDirectory = System.AppDomain.CurrentDomain.BaseDirectory;//初始化路径
fileDialog.Filter = "文档(*.txt)|*.txt";//或"图片(*.jpg;*.bmp)|*.jpg;*.bmp";//过滤选项设置,文本文件,所有文件。
fileDialog.FilterIndex = 0;//当前使用第二个过滤字符串
fileDialog.RestoreDirectory = true;//对话框关闭时恢复原目录
fileDialog.Title = "选择文档";
if (fileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Settings.Default.FilePath = fileDialog.FileName;
Settings.Default.Save();
TbTextBox.Text = ReadFile(fileDialog.FileName);
}
}
private void Button_Click_Start(object sender, RoutedEventArgs e)
{
speechSynthesizer.StateChanged += new EventHandler<StateChangedEventArgs>(synth_StateChanged);
Play();
}
private void Button_Click_Stop(object sender, RoutedEventArgs e)
{
Stop();
}
private void Stop()
{
speechSynthesizer.StateChanged -= new EventHandler<StateChangedEventArgs>(synth_StateChanged);
speechSynthesizer.SpeakAsyncCancelAll();
}
private string ReadFile(string path)
{
try
{
string str = "";
// 创建一个 StreamReader 的实例来读取文件
// using 会自动释放资源
using (StreamReader sr = new StreamReader(path))
{
// 从文件读取并显示行,直到文件的末尾
str = sr.ReadToEnd();
}
var datas = str.Split('\n');
int index = 0;
foreach (var data in datas)
{
PlayItem playItem = new PlayItem();
playItem.Content = data;
playItem.Index = index;
playItem.Lenght = data.Length + 1;
index += playItem.Lenght;
PlayData.Add(playItem);
}
return str;
}
catch (Exception ex)
{
return ex.Message;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
LoadingWindow loadingWindow = new LoadingWindow();
loadingWindow.Show();
TbTextBox.FontSize = Settings.Default.FontSize;
if (!string.IsNullOrEmpty(Settings.Default.FilePath))
{
TbTextBox.Text = ReadFile(Settings.Default.FilePath);
}
PlayLine = Settings.Default.PlayLine;
LbPlayLine.Content = $"播放:{PlayLine.ToString()}行";
loadingWindow.Close();
}
private void Window_Closed(object sender, EventArgs e)
{
Stop();
Settings.Default.PlayLine = PlayLine;
Settings.Default.Save();
}
private void Button_Click_Set(object sender, RoutedEventArgs e)
{
try
{
PlayLine = int.Parse(TbPlayLine.Text) - 1;
if(PlayLine<=0)
{
PlayLine = 0;
}
speechSynthesizer.SpeakAsyncCancelAll();
}
catch(Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
private void Window_LocationChanged(object sender, EventArgs e)
{
Settings.Default.Left = this.Left;
Settings.Default.Top = this.Top;
Settings.Default.Width = this.Width;
Settings.Default.Height = this.Height;
Settings.Default.Save();
}
private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
{
Settings.Default.Left = this.Left;
Settings.Default.Top = this.Top;
Settings.Default.Width = this.Width;
Settings.Default.Height = this.Height;
Settings.Default.Save();
}
private void Button_Click_Add(object sender, RoutedEventArgs e)
{
TbTextBox.FontSize = TbTextBox.FontSize + 1 ;
Settings.Default.FontSize = TbTextBox.FontSize;
Settings.Default.Save();
}
private void Button_Click_Subtract(object sender, RoutedEventArgs e)
{
TbTextBox.FontSize = TbTextBox.FontSize - 1;
Settings.Default.FontSize = TbTextBox.FontSize;
Settings.Default.Save();
}
}
}
界面代码
<Window x:Class="TextToSpeech.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"
xmlns:local="clr-namespace:TextToSpeech"
mc:Ignorable="d"
Title="TextShoundPlay" Height="450" Width="800" Loaded="Window_Loaded" Closed="Window_Closed" LocationChanged="Window_LocationChanged" SizeChanged="Window_SizeChanged">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0">
<TextBox x:Name="TbTextBox" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/>
</Grid>
<StackPanel Grid.Row="0" Grid.Column="1">
<Button Content="打开" Click="Button_Click_Open"/>
<Button Content="播放" Click="Button_Click_Start"/>
<Button Content="停止" Click="Button_Click_Stop"/>
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<TextBlock Text="转到:"></TextBlock>
<TextBox x:Name="TbPlayLine" Text="0" Width="60"></TextBox>
<TextBlock Text="行"></TextBlock>
</StackPanel>
<Button Content="跳转" Click="Button_Click_Set"/>
<Label x:Name="LbPlayLine"></Label>
<Button Content="增大字体" Click="Button_Click_Add"/>
<Button Content="减小字体" Click="Button_Click_Subtract"/>
</StackPanel>
</Grid>
</Window>