文章目录
- MySpeech类
- 快进
文章目录
- MySpeech类
- 快进
txt阅读器系列:
- 需求分析和文件读写
- 目录提取类💎列表控件与目录
- 字体控件绑定💎前景/背景颜色
- 书籍管理系统💎用树形图管理书籍
- 语音播放💎播放进度显示
MySpeech类
speech的操作逻辑可以理解为一边合成语音,一边播放语音,所以理论上来说并不能对播放位置进行跳转。
如果有着强烈的跳转愿望,那么就需要对文本进行分割,考虑到SpeechSynthesizer是个密封类,不让被继承,所以新建一个类,并用st来调节阅读的起始位置。
internal class MySpeech
{
public SpeechSynthesizer speech;
public string text;
public int st, charPosition;
public MySpeech(string text)
{
this.text = text;
speech = new SpeechSynthesizer();
st = 0;
}
public void Speak()
{
speech.SpeakAsync(text[st..]);
}
public void ctrlTask()
{
switch (speech.State.ToString())
{
case "Paused": speech.Resume(); break;
case "Speaking": speech.Pause(); break;
case "Ready": Speak(); break;
}
}
public void Jump(int L)
{
st += L + charPosition;
st = Math.Max(st, 0);
st = Math.Min(st, text.Length);
speech.SpeakAsyncCancelAll();
Speak();
}
}
然后将主窗口中的所有SpeechSynthesizer对象替换为MySpeech对象,由于对一些函数采用了同名封装,所以除了更改SpeechSynthesizer speech为MySpeech speech之外,其他地方的改动只有两处,一是speech.Speak()中没有参数了;二则是speech.SpeakProgress += Speech_SpeakProgress; 改为 speech.speech.SpeakProgress += Speech_SpeakProgress;,即调用MySpeech 中的SpeechSynthesizer对象来实现绑定。
在MySpeech
类中,SpeakAsync
为异步朗读,用这个函数的好处是,无需担心阻塞主窗口,从而在主程序中也就无需新建线程来Speak
,而只需
private void btnReadStart_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
speech.ctrlTask();
txt.Focus();
btn.Content = btn.Content.ToString()== "▶️" ? "⏯️" : "▶️";
}
另一方面,在跳转过程中,启用了SpeakAsyncCancelAll
来终止Speak
线程,从而可以重新开始朗读。
快进
首先,在Speech_SpeakProgress
函数中更改speech
中的开始游标st
,即添加如下代码
speech.st = e.CharacterPosition;
然后,新增两个按钮,并注册btnSpeechJump_Click
事件,
<Button Content="⏪" Click="btnSpeechJump_Click"/>
<Button Content="▶️" Width="20" Click="btnReadStart_Click"/>
<Button Content="⏩" Click="btnSpeechJump_Click"/>
其内容为
private void btnSpeechJump_Click(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
int flag = btn.Content.ToString() == "⏩" ? 1 : -1;
txtInfo.Text = (flag * 20).ToString();
speech.Jump(flag * 20);
txt.Focus();
}
其功能是每次点击快进,则前进20个字符,最终效果如下
当然,这个20不一定合理,所以最后可将其设为可设的,并为其分配一个参数。另外,快进和快退这两个按钮两侧还有两个按钮,预留用于跳转到下一章节。