音响巡检工具

概要

JBL GO2音响无音频十分钟左右时,自动关机。

情况基本就是下面第二点:

解决:制作音响巡检软件防关机,定期(目前设置5s)监测电脑扬声器状态,周期判断(周期可设置)内是否有声音在播放,若系统有在播放则工具不播放语音(音量可设置),反之工具播放语音。附加:扬声器日志输出,关闭时先隐藏到托盘图标。

代码实现

窗体类+三个工具类(语音、定时器、扬声器)

Form1.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;

namespace 后台声音操作
{
    public partial class Form1 : Form
    {
        Speech_Device _speechDevice;
        System_Timers_Timer system_Timers_Timer;
        DateTime _lastUpdateTime = DateTime.MinValue;
        private bool _autoPlayFlag;
        private int _perionSeconds;

        public Form1()
        {
            InitializeComponent();
            // 初始化托盘图标
            InitializeTrayIcon();
            // 初始化语音合成器
            InitSpeech();
            // 初始化定时器+监测扬声器状态
            InitTimerWithStatus();
        }



        private void InitSpeech()
        {
            _speechDevice = new Speech_Device();
            // 初始化周期
            this._perionSeconds = (int)this.perionUpDown.Value * 60;
        }

        private void btnPlay_Click(object sender, EventArgs e)
        {
            // 将文本转换为语音并播放
            _speechDevice.Play(this.richTextBox1.Text);
        }


        private void btnPlayAuto_Click(object sender, EventArgs e)
        {
            // 将文本转换为语音并定期判断播放
            this.btnPalyAuto.Text = this.btnPalyAuto.Text.Equals("定期播放") ? "取消定期播放" : "定期播放";
            this._autoPlayFlag = this._autoPlayFlag ? false : true;
            this._lastUpdateTime = DateTime.Now;
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            // 关闭
            _speechDevice.Stop();
            system_Timers_Timer.Stop();
            base.OnFormClosing(e);
        }

        private void InitTimerWithStatus()
        {
            system_Timers_Timer = new System_Timers_Timer(new Action<object, ElapsedEventArgs>((s, e) =>
                {
                    Task.Run(() =>
                    {
                        (bool, List<string>) statusAndText = Voice_Device.GetStatus();
                        //子线程才可以使用音量设备
                        List<string> audioInfos = statusAndText.Item2;
                        this.logBox?.Invoke(new Action(() =>
                        {
                            this.logBox.Items.Add(DateTime.Now.ToString("HH:mm:ss"));
                            this.logBox.Items.AddRange(audioInfos.ToArray());
                            //超过50条日志时 重新记录
                            if (this.logBox.Items.Count > 50) { this.logBox.Items.Clear(); }
                            //扬声器有声音时,刷新更新时间
                            this._lastUpdateTime = statusAndText.Item1 ? DateTime.Now : this._lastUpdateTime;
                            //扬声器周期内没声音,播报一次
                            if (_autoPlayFlag && Math.Abs((this._lastUpdateTime - DateTime.Now).TotalSeconds) > this._perionSeconds) { this._lastUpdateTime = DateTime.Now; _speechDevice.Play(this.richTextBox1.Text); }
                        }));

                    });

                }));
            system_Timers_Timer.Start(5000);

        }

        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            // 更新 NumericUpDown 控件的值
            this.voiceUpDown.Value = this.voiceBar.Value;
            _speechDevice.Edit_VolumeAndRate(this.voiceBar.Value);
        }

        private void numericUpDown1_ValueChanged(object sender, EventArgs e)
        {
            // 更新 TrackBar 控件的位置
            this.voiceBar.Value = (int)this.voiceUpDown.Value;
            _speechDevice.Edit_VolumeAndRate(this.voiceBar.Value);

        }

        private void numericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            // 更新周期
            this._perionSeconds = (int)this.perionUpDown.Value * 60;
        }




        #region 隐藏到图标
        
        //系统托盘图标
        private NotifyIcon TrayIcon;
       
        private void InitializeTrayIcon()
        {
            this.Text = "音响巡检工具";
            this.Icon = Icon.ExtractAssociatedIcon("favicon.ico");
            this.FormClosing += OnFormClosing;
            TrayIcon = new NotifyIcon()
            {
                Icon = SystemIcons.Asterisk,
                Visible = true,
                ContextMenu = new ContextMenu(new MenuItem[] {
                new MenuItem("退出", Exit) //右键小菜单
            })
            };
            TrayIcon.Icon = Icon.ExtractAssociatedIcon("favicon.ico");
            TrayIcon.Text = "音响巡检工具";
            TrayIcon.Click += TrayIcon_Click;
        }

        protected void OnFormClosing(object sender, FormClosingEventArgs e)
        {
            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                this.Hide();
            }
        }

        private void TrayIcon_Click(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Normal;
            this.Show();
        }

        private void Exit(object sender, EventArgs e)
        {
            TrayIcon.Visible = false;
            System.Windows.Forms.Application.Exit();
        }
        #endregion

    }
}

Speech_Device.cs

using System.Speech.Synthesis;

namespace 后台声音操作
{
    /// <summary>
    /// 语音播放工具
    /// </summary>
    public class Speech_Device
    {
        private SpeechSynthesizer _synthesizer;
        int _volume = 10;
        int _rate = 0;

        public Speech_Device()
        {
            _synthesizer = new SpeechSynthesizer();
            // 选择中文语音
            _synthesizer.SelectVoiceByHints(VoiceGender.NotSet, VoiceAge.Adult, 0, new System.Globalization.CultureInfo("zh-CN"));
        }

        public void Edit_VolumeAndRate(int volume, int rate = 0)
        {
            this._volume = volume;
            this._rate = rate;
        }

        public void Play(string text)
        {
            // 设置音量和语速
            _synthesizer.Volume = this._volume;
            _synthesizer.Rate = this._rate;
            // 将文本转换为语音并播放
            _synthesizer.SpeakAsync(text);

        }
        public void Stop()
        {
            // 关闭语音合成器
            _synthesizer?.Dispose();
        }

    }


}

System_Timers_Timer.cs

using System;
using System.Timers;

namespace 后台声音操作
{
    /// <summary>
    /// 定时器工具
    /// </summary>
    internal class System_Timers_Timer
    {
        Timer _timer = new Timer();

        public System_Timers_Timer(Action<object,ElapsedEventArgs> action)
        {
            //定时执行的任务
            ElapsedEventHandler elapsedEventHandler = new ElapsedEventHandler(action);
            _timer.Elapsed += elapsedEventHandler;
        }

        public void Start(double Interval)
        {
            _timer.Interval = Interval;
            _timer.Start();
        }

        public void Stop()
        {
            _timer?.Stop();
            _timer?.Dispose();
        }
    }
}

Voice_Device.cs

using CSCore.CoreAudioAPI;
using System;
using System.Collections.Generic;

namespace 后台声音操作
{
    /// <summary>
    /// 扬声器工具
    /// </summary>
    class Voice_Device
    {
        public static (bool, List<string>) GetStatus()
        {
            bool hasVoice = false;
            List<string> audioInfos = new List<string>();
            using (var sessionManager = GetDefaultAudioSessionManager2(DataFlow.Render))
            {
                using (var sessionEnumerator = sessionManager.GetSessionEnumerator())
                {
                    foreach (var session in sessionEnumerator)
                    {
                        using (var audioSessionControl2 = session.QueryInterface<AudioSessionControl2>())
                        {
                            var process = audioSessionControl2.Process;
                            using (var audioMeterInformation = session.QueryInterface<AudioMeterInformation>())
                            {
                                var value = audioMeterInformation.GetPeakValue();

                                if (process != null)
                                {
                                    var val = audioMeterInformation.GetPeakValue();

                                    /*//打印应用音量
                                    Console.WriteLine("Pid:{0},应用: {1},播放信息:{2},音量:{3}",
                                       audioSessionControl2.ProcessID,
                                       process.ProcessName,
                                       process.MainWindowTitle,
                                       val);*/

                                    string audioInfo = string.Format("Pid:{0},应用: {1},播放信息:{2},音量:{3}",
                                       audioSessionControl2.ProcessID,
                                       process.ProcessName,
                                       process.MainWindowTitle,
                                       val);
                                    audioInfos.Add(audioInfo);
                                    if (val != 0) { hasVoice = true; }
                                }

                            }
                        }
                    }
                }
            }
            return (hasVoice, audioInfos);
        }
        private static AudioSessionManager2 GetDefaultAudioSessionManager2(DataFlow dataFlow)
        {
            using (var enumerator = new MMDeviceEnumerator())
            {
                using (var device = enumerator.GetDefaultAudioEndpoint(dataFlow, Role.Multimedia))
                {
                    Console.WriteLine("默认设备: " + device.FriendlyName);
                    var sessionManager = AudioSessionManager2.FromMMDevice(device);
                    return sessionManager;
                }
            }
        }
    }
}

效果

执行文件:

V1.1   修复隐藏到托盘再打开播放会报错的bug

天翼云盘 珍藏美好生活 家庭云|网盘|文件备份|资源分享天翼云盘是中国电信推出的云存储服务,为用户提供跨平台的文件存储、备份、同步及分享服务,是国内领先的免费网盘,安全、可靠、稳定、快速。天翼云盘为用户守护数据资产。icon-default.png?t=O83Ahttps://cloud.189.cn/t/uueyYrERJJbq(访问码:ln12)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值