C#语音播报(通过CoreAudioAPI完成对扬声器的控制)

1,效果:

  • 作用:
  1. 可对当前内容(例如此例中的重量信息)进行语音合成播报 。
  2. 可设置系统扬声器音量与状态(是否静音),同时根据扬声器状态同步更新当前控件状态与值,实现强制PC扬声器按照指定的音量进行播报,杜绝人为静音的可能。

2,引入相关程序集,命名空间。

  • 程序集

        微软语音合成程序集:System.Speech

        第三方程序集:CoreAudioAPI(为方便使用,进行了部分修改包装)

  • 命名空间:
using System.Speech.Synthesis;
using CoreAudioAPIs;

3,代码:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="112*"/>
            <ColumnDefinition Width="320*"/>
            <ColumnDefinition Width="85*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="59*"/>
            <RowDefinition Height="51*"/>
            <RowDefinition Height="77*"/>
            <RowDefinition Height="43*"/>
            <RowDefinition Height="32*"/>
            <RowDefinition Height="58*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="重量:" FontSize="32" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,8"></TextBlock>
        <TextBox Grid.Column="1" VerticalContentAlignment="Center" x:Name="txtWeight" FontSize="30"></TextBox>
        <ComboBox x:Name="combo01" Grid.Column="2" VerticalContentAlignment="Center" FontSize="32">
            <ComboBoxItem FontSize="32" IsSelected="True">KG</ComboBoxItem>
            <ComboBoxItem FontSize="32">T</ComboBoxItem>
            <ComboBoxItem FontSize="32">G</ComboBoxItem>
        </ComboBox>
        <Button x:Name="btnPlay" Content="播报" FontSize="25" Grid.Row="1" Grid.Column="1" Margin="20,3" Click="btnPlay_Click"></Button>
        <Grid Grid.Row="2" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition ></RowDefinition>
                <RowDefinition ></RowDefinition>
               
            </Grid.RowDefinitions>
            <TextBlock x:Name="txtStatus" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Status}" Foreground="{Binding StatusForeground}" FontSize="16"></TextBlock>
            <TextBlock FontSize="24" Grid.Row="1"  Text="PC扬声器设置" HorizontalAlignment="Center" VerticalAlignment="Bottom"></TextBlock>
        </Grid>
        
        <TextBlock Text="播放音量:" Grid.Row="3" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,11,0,10"></TextBlock>
        <Slider Grid.Row="3" Grid.Column="1" ValueChanged="slider01_ValueChanged" Minimum="0" VerticalAlignment="Center" Maximum="100" x:Name="slider01" SmallChange="1" LargeChange="5" TickPlacement="BottomRight" IsSnapToTickEnabled="True" Margin="0,11,0,10"></Slider>

        <TextBlock Grid.Row="3" Grid.Column="2" FontSize="16" VerticalAlignment="Center" Margin="10,0" DockPanel.Dock="Left" Text="{Binding ElementName=slider01 ,Path=Value}"></TextBlock>
        <CheckBox Grid.Row="4" x:Name="muteCheck01" Click="muteCheck01_Checked" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="16">静音</CheckBox>

    </Grid>
 public partial class MainWindow : Window, System.ComponentModel.INotifyPropertyChanged
    {
        VolumeControl volumeControl = new VolumeControl();
        public event PropertyChangedEventHandler PropertyChanged;
        SpeechSynthesizer speeker = new SpeechSynthesizer();
        public MainWindow()
        {
            InitializeComponent();
            volumeControl.VolumeStateChange += VolumeControl_VolumeStateChange;
            slider01.Value = Volume;
            muteCheck01.IsChecked = Mute;
            this.DataContext = this;
            Status = "准备就绪!";
            StatusForeground = new SolidColorBrush(Colors.Green);
        }
        
        public bool Mute
        {
            get
            {
                return volumeControl.IsMuted;
            }
            set
            {
                volumeControl.IsMuted = value;
                OnPropertyChanged(nameof(Mute));
            }
        }
        public int Volume
        {
            get
            {
                return volumeControl.Volume;
            }
            set
            {
                volumeControl.Volume = value;
                OnPropertyChanged(nameof(Volume));
            }
        }
        string status;
        public string Status
        {
            get
            {
                return status;
            }
            set
            {
                status = value;
                OnPropertyChanged(nameof(Status));
            }
        }
        Brush statusForeground = new SolidColorBrush(Colors.Black);
        public Brush StatusForeground
        {
            set
            {
                statusForeground = value;
                OnPropertyChanged(nameof(statusForeground));
            }
            get
            {
                return statusForeground;
            }
        }
        private void VolumeControl_VolumeStateChange(bool mute, int volumeValue)
        {
            Dispatcher.Invoke(() =>
            {
               //移除注册,否则更新控件时将出现循环,这也是不用绑定的原因
                slider01.ValueChanged -= slider01_ValueChanged;
                muteCheck01.Checked -= muteCheck01_Checked;
                this.muteCheck01.IsChecked = mute;
                slider01.Value = volumeValue;
                //重新注册
                slider01.ValueChanged += slider01_ValueChanged;
                muteCheck01.Checked += muteCheck01_Checked;
            });
        }
        private void slider01_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            Volume = (int)slider01.Value;
        }
        private void muteCheck01_Checked(object sender, RoutedEventArgs e)
        {
            Mute = muteCheck01.IsChecked.HasValue ? muteCheck01.IsChecked.Value : false;
        }
      
        private void btnPlay_Click(object sender, RoutedEventArgs e)
        {
            PromptBuilder builder = new PromptBuilder();
            builder.AppendText("当前重量:", PromptVolume.Loud);
            builder.AppendBreak(PromptBreak.Medium);
            PromptStyle style = new PromptStyle();
            style.Emphasis = PromptEmphasis.Strong;
            style.Rate = PromptRate.Medium;
            style.Volume = PromptVolume.ExtraLoud;
            builder.StartStyle(style);
            builder.AppendTextWithHint(txtWeight.Text.Trim(), SayAs.NumberCardinal);
            builder.EndStyle();
            string str = "";
            switch (combo01.Text)
            {
                case "KG":
                    str = "千克";
                    break;
                case "G":
                    str = "克";
                    break;
                default:
                    str = "吨";
                    break;
            }
            builder.AppendBreak(PromptBreak.Small);
            builder.AppendText(str, PromptEmphasis.Strong);
            SpeechBroadcasting(builder);
        }
        async void SpeechBroadcasting(PromptBuilder builder)
        {
            Status = "播报中.....";
            StatusForeground = new SolidColorBrush(Colors.Orange);
            await Task.Run(() =>
             {
                 //耗时长
                 speeker.Speak(builder);
             }).ContinueWith(t =>
             {
                 Dispatcher.Invoke(() =>
                 {
                     Status = "播报完成!";
                     StatusForeground = new SolidColorBrush(Colors.BlueViolet);
                 });
                 System.Threading.Thread.Sleep(1000);
             });
            Status = "准备就绪!";
            StatusForeground = new SolidColorBrush(Colors.Green);
        }
        void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

4,Demo链接:

https://download.csdn.net/download/lingxiao16888/89298014

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值