当前位置: 首页 > news >正文

winform实现托盘语音提醒

测试环境:

visual studio 2022

window 10

.net framework 4.6

本文实现的功能有:

1   托盘最小化

2   语音定时播放

3   检测到操作系统被客户点静音后,需要程序控制开启音量(在运行过程中,由于语音重复播放,客户很烦,就会点静音,后面搞了一个在客户点静音后,如果客户一直没处理问题,就在10分钟后重新开启音量播放音频)

4  连接sql server数据库,如果不需要可以把代码注释掉

步骤如下:

1 新增名为DrawerAudio的winfrom程序,默认带出的窗体重新命名为:DrawerAudio

2 nuget安装NAudio,版本选择1.9.0,如下图:

3 网上找一张icon的图片,重新命名为ico_audio.ico,并放到debug目录,接着网上找一个要播放的mp3音频,并重新命名为"发生药槽错误,请盘点变红的药槽.mp3"

4  App.config配置文件编辑如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration><startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" /></startup><connectionStrings><add name="Sql" connectionString="server=127.0.0.1;uid=sa;pwd=密码;database=sql server数据库名称"/></connectionStrings><appSettings><add key="IsTest" value="0" /><add key="SetAudioVolume" value="60" /><add key="MuteMinute" value="10" /></appSettings>
</configuration>

IsTest为1为测试模式,0为正式运行模式

SetAudioValume是设置音量

MuteMinute为最小音量,为了客户把音量调得过小,小于该音量后,程序自动把音量调大

5 新建名为SqlHelper的类并编辑如下(需要添加System.Configuration.dll引用):

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;namespace DrawerAudio
{// Token: 0x02000003 RID: 3internal class SqlHelper{// Token: 0x06000004 RID: 4 RVA: 0x00002124 File Offset: 0x00000324public static string GetSqlConnectionString(){return System.Configuration.ConfigurationManager.ConnectionStrings["Sql"].ConnectionString;}// Token: 0x06000005 RID: 5 RVA: 0x0000214C File Offset: 0x0000034Cpublic static IList<T> ExecuteDataTable<T>(string sqlText, params SqlParameter[] parameters) where T : class, new(){IList<T> result;using (SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(sqlText, SqlHelper.GetSqlConnectionString())){DataTable dataTable = new DataTable();sqlDataAdapter.SelectCommand.Parameters.AddRange(parameters);sqlDataAdapter.Fill(dataTable);IList<T> list = new List<T>();PropertyInfo[] properties = typeof(T).GetProperties();for (int i = 0; i < dataTable.Rows.Count; i++){T t = Activator.CreateInstance<T>();foreach (PropertyInfo propertyInfo in properties){propertyInfo.SetValue(t, dataTable.Rows[i][propertyInfo.Name], null);}list.Add(t);}result = list;}return result;}}
}

6  新建名为AudioHelper的类并编辑如下:

using NAudio.CoreAudioApi;
using NAudio.Wave;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace DrawerAudio
{public class AudioHelper{private static bool IsPlaying = false;private static WaveOut waveOut;private static Mp3FileReader reader;private static string audioName;private static object lockobj = new object();public static bool Init(string audioName){AudioHelper.audioName = audioName;AudioHelper.IsPlaying = true;return true;}public static bool GetIsPalying(){    return IsPlaying;}public static bool CheckCanStart(){if (waveOut!=null&&waveOut.PlaybackState == PlaybackState.Playing){return false;}return true;}public static void PlayAudio(){try{lock (lockobj){using (var ms = File.OpenRead(audioName)){using (reader = new Mp3FileReader(ms))using (var wavStream = WaveFormatConversionStream.CreatePcmStream(reader))using (var baStream = new BlockAlignReductionStream(wavStream))using (waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback())){waveOut.Init(baStream);waveOut.Play();while (waveOut.PlaybackState == PlaybackState.Playing&& AudioHelper.GetIsPalying()){Thread.Sleep(100);}}}}}catch (Exception ex){Console.WriteLine("异常信息:"+ex.Message);}}public static bool StopPlay(){try{if (waveOut != null){IsPlaying = false;waveOut.Stop();}}catch (Exception ex){Console.WriteLine("停止错误:"+ex.Message);}return true;}/// <summary>/// 获取当前音量/// </summary>/// <returns></returns>public  static int GetCurrentSpeakerVolume(){int volume = 0;var enumerator = new MMDeviceEnumerator();//获取音频输出设备IEnumerable<MMDevice> speakDevices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active).ToArray();if (speakDevices.Count() > 0){MMDevice mMDevice = speakDevices.ToList()[0];volume = Convert.ToInt16(mMDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100);}return volume;}public static void  SetCurrentSpeakerVolume(int volume){var enumerator = new MMDeviceEnumerator();IEnumerable<MMDevice> speakDevices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active).ToArray();if (speakDevices.Count() > 0){MMDevice mMDevice = speakDevices.ToList()[0];mMDevice.AudioEndpointVolume.MasterVolumeLevelScalar = volume / 100.0f;}}/// <summary>/// 检测是否是静音/// </summary>/// <returns></returns>public static bool CheckIsNoNoise(){var enumerator = new MMDeviceEnumerator();IEnumerable<MMDevice> speakDevices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active).ToArray();MMDevice mMDevice = speakDevices.ToList()[0];return mMDevice.AudioEndpointVolume.Mute;}/// <summary>/// 关闭静音/// </summary>public static void CloseNoNoise(){var enumerator = new MMDeviceEnumerator();IEnumerable<MMDevice> speakDevices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active).ToArray();MMDevice mMDevice = speakDevices.ToList()[0];mMDevice.AudioEndpointVolume.Mute = false;}}
}

7  新建Model目录,并新建名为DrawerModel的类,并编辑如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace DrawerAudio.Model
{// Token: 0x02000004 RID: 4public class DrawerModel{// Token: 0x17000001 RID: 1// (get) Token: 0x06000007 RID: 7 RVA: 0x00002245 File Offset: 0x00000445// (set) Token: 0x06000006 RID: 6 RVA: 0x0000223C File Offset: 0x0000043Cpublic int IdDrawer { get; set; }// Token: 0x17000002 RID: 2// (get) Token: 0x06000009 RID: 9 RVA: 0x00002256 File Offset: 0x00000456// (set) Token: 0x06000008 RID: 8 RVA: 0x0000224D File Offset: 0x0000044Dpublic int IdProduct { get; set; }}
}

8 编辑FrmMain如下:

using DrawerAudio.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;namespace DrawerAudio
{public partial class FrmMain : Form{bool isTest = ConfigurationManager.AppSettings["IsTest"].Equals("1");int audioVolume = Convert.ToInt32(ConfigurationManager.AppSettings["SetAudioVolume"]);//静音的分钟数int muteMinute= Convert.ToInt32(ConfigurationManager.AppSettings["MuteMinute"]);const int WM_SYSCOMMAND = 0x112;const int SC_MINIMIZE = 0xF020;Thread audioThread = null;int secondCount = 0;public FrmMain(){InitializeComponent();this.WindowState = FormWindowState.Minimized;this.ShowInTaskbar = false;this.Load += FrmMain_Load;audioThread = new Thread(StartAudio);audioThread.IsBackground=true;AudioHelper.Init("发生药槽错误,请盘点变红的药槽.mp3");audioThread.Start();System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();timer.Interval = 1000;timer.Tick += Timer_Tick;timer.Start();}private const int CP_NOCLOSE_BUTTON = 0x200;protected override CreateParams CreateParams{get{CreateParams myCp = base.CreateParams;myCp.ClassStyle = myCp.ClassStyle | CP_NOCLOSE_BUTTON;return myCp;}}private void Timer_Tick(object sender, EventArgs e){int currentVlume=AudioHelper.GetCurrentSpeakerVolume();if (currentVlume < 20){AudioHelper.SetCurrentSpeakerVolume(audioVolume);}if (AudioHelper.CheckIsNoNoise()){secondCount++;if (secondCount > (60 * muteMinute)){secondCount = 0;AudioHelper.CloseNoNoise();}}else{secondCount = 0;}}protected override void WndProc(ref Message m){if (m.Msg == WM_SYSCOMMAND){if (m.WParam.ToInt32() == SC_MINIMIZE){this.ShowInTaskbar = false;this.WindowState= FormWindowState.Minimized;}}base.WndProc(ref m);}private void FrmMain_Load(object sender, EventArgs e){//实例化一个NotifyIcon对象NotifyIcon notifyIcon = new NotifyIcon();//设置图标notifyIcon.Icon = new Icon("ico_audio.ico");//设置提示文本notifyIcon.Text = "药槽错误语音提醒";//设置双击托盘图标后显示窗体notifyIcon.DoubleClick += NotifyIcon_DoubleClick;//显示托盘notifyIcon.Visible = true;}private void NotifyIcon_DoubleClick(object sender, EventArgs e){this.WindowState = FormWindowState.Normal;this.ShowInTaskbar = true;this.Activate();}private void btnStart_Click(object sender, EventArgs e){AudioHelper.Init("发生药槽错误,请盘点变红的药槽.mp3");if (audioThread.ThreadState == (ThreadState.Background|ThreadState.Suspended)){audioThread.Resume();}else if(audioThread.ThreadState==(ThreadState.Background|ThreadState.Unstarted)){audioThread.Start();}MessageBox.Show("开始成功");}private void StartAudio(){while (true){Thread.Sleep(500);if (!isTest){if (GetDrawerError()){if (AudioHelper.GetIsPalying() && AudioHelper.CheckCanStart()){AudioHelper.PlayAudio();}}}else{if (AudioHelper.GetIsPalying() && AudioHelper.CheckCanStart()){AudioHelper.PlayAudio();}}}}private bool GetDrawerError(){string sqlText = "select IdDrawer,IdProduct from 表名 where 条件";try{IList<DrawerModel> list = SqlHelper.ExecuteDataTable<DrawerModel>(sqlText, Array.Empty<SqlParameter>());if (list.Count > 0){return true;}}catch (Exception ex){Console.WriteLine("查询失败,错误信息:" + ex.Message);}return false;}/// <summary>/// 停止按钮的逻辑,根据需要进行加入/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void btnStop_Click(object sender, EventArgs e){audioThread.Suspend();AudioHelper.StopPlay();}}
}

要上班了,代码就不解释了


http://www.mrgr.cn/news/46889.html

相关文章:

  • 当自动包布机遇上Profinet转ModbusTCP网关,“妙啊”,工业智能“前景无限
  • JS宏进阶:函数、对象和类(三)
  • Python AI教程之十五:监督学习之决策树(6)高级算法C5.0决策树算法介绍
  • Python脚本自动发送电子邮件
  • springboot vue uniapp 仿小红书 1:1 还原 (含源码演示)
  • 数据集-目标检测系列- 石榴 检测数据集 pomegranate >> DataBall
  • 【测试】用例篇——测试用例的概念
  • ROS理论与实践学习笔记——4 ROS的常用组件之rosbag
  • SpringMVC框架:深入注解开发实践与基础案例优化解析
  • Plant Monster Pack PBR - Fantasy RPG 植物怪物包
  • Android Serializable和Parcelable的区别及其使用
  • 【JS】Object.create方法以及借助此实现继承
  • 全国上市公司企业绿色管理创新数据与绿色管理创新完整数据-含代码(2008-2023年)
  • 数据库管理平台应该具备哪些功能
  • Android SELinux——工作模式(二)
  • Yocto构建教程:在SDK中添加Qt5并生成带有Qt5的SDK
  • 小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(中级)
  • 【玩转动态规划专题】746. 使用最小花费爬楼梯【简单】
  • 【计算机网络】网络相关技术介绍
  • LVGL仪表盘逆时针
  • 飞腾CPU技术发展分析
  • 2024最新分别利用sklearn和Numpy实现c均值对鸢尾花数据集进行聚类(附完整代码和注释)
  • Linux平台Kafka高可用集群部署全攻略
  • C++学习笔记----8、掌握类与对象(六)---- 操作符重载(3)
  • 计算机视觉算法--原理、技术、应用、发展
  • 开源 AI 智能名片 O2O 商城小程序源码助力企业实现三层式个性化体验