入门分享:win10监听声音,并向公众号发出提醒,Python从零实现

起因:有一台设备需要监听某软件的消息,并及时回复,如果只有一个人办公时,难免有走开的情况,如何在不走远的情况下能监听到这个软件的消息,并给我提醒呢。

设计了一个最简单的方案:电脑麦克风监听声音,如果有声音发出,就向微信公众号发出一条消息

环境:Windows 10

语言:Python

应用程序:IEDA

参考文档:

python获取电脑扬声器是否在发出声音_mob649e81597922的技术博客_51CTO博客

【精选】python3 实现公众号自动发消息_python对接微信发订阅消息_XMYX-0的博客-CSDN博客

微信公众平台

Python PyInstaller 模块使用详解(将Python程序制作成可直接运行的 EXE 程序)

一.预览

先给大家看看最后的成品:

功能很简单,代码也很简单,可以调整监听的声音阈值,超过阈值就会发消息提醒

二.配置Python环境

第一步:

打开IDEA,安装Python插件

第二步:

新建python项目

这里的Virtualenv就是虚拟环境的意思,这里的python环境与本机安装的是隔离的,方便可以使用不同的python版本和环境,所以第三方的库也需要重新安装

第三步:

安装第三方库:

启动终端,使用pip安装就可以

因为国内网络环境原因,第三方库经常下载超时,需要更换源

blog.csdn.net/m0_52537869...

python程序中文件顶部有 import 方式导入第三方库,如果缺失,请使用 pip install 先安装

例如安装网络请求库 requests:pip install requests

第四步:

编写程序

右键创建python文件就可以开始编写了。

三.公众号准备

1.获取测试公众号

直接使用测试公众号,进入微信公众平台,微信扫码登录后,就可获取到测试公众号的相关信息和相关的接口文档。

2.关注测试公众号并创建消息模板

使用自己的微信关注测试公众号,可以获取到已关注的微信好的id

编辑消息模板也非常简单,有一点需要注意,模板中需要展示自定义的参数的话,需要以".DATA"结尾:

因为我这里只展示消息的时间,则定义内容是{{time.DATA}}

页面下面有模板消息的文档,可以参考官方样式

我的消息格式是这样的:

lua 复制代码
{
  "touser": touser,
  "template_id": self.template_id,
  "topcolor": "#FF0000",
  "data": {
    "time": {
      "value": time,
      "color": "#173177"
    }
  }
}

四.微信发送消息程序

新建Python文件SendMsg.py

微信公众号实现消息发送功能

直接贴代码

python 复制代码
# encoding: utf-8
import json

import requests


class AccessToken(object):
    # 微信公众测试号账号(填写自己的)
    APPID = "wx..........."
    # 微信公众测试号密钥(填写自己的)
    APPSECRET = "2e........"

    def __init__(self, app_id=APPID, app_secret=APPSECRET) -> None:
        self.app_id = app_id
        self.app_secret = app_secret

    def get_access_token(self) -> str:
        """
        获取access_token凭证
        :return: access_token
        """
        url = f"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={self.app_id}&secret={self.app_secret}"
        resp = requests.get(url)
        result = resp.json()
        if 'access_token' in result:
            return result["access_token"]
        else:
            print(result)


class SendMessage(object):
    # 消息接收者
    TROUSER = 'od1.........', 'od1.........'
    # 消息模板id
    TEMPLATE_ID = '_BG..........'

    def __init__(self, touser=TROUSER, template_id=TEMPLATE_ID) -> None:
        """
        构造函数
        :param touser: 消息接收者
        :param template_id: 消息模板id
        """
        self.access_token = AccessToken().get_access_token()
        self.trouser = touser
        self.template_id = template_id

    def send_message(self, time) -> None:
        """
        发送消息
        :param time: 时间
        :return:
        """
        # 模板消息请求地址
        url = f"https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={self.access_token}"
        for Recipient in self.trouser:
            if Recipient != '':
                data = json.dumps(self.get_send_data(time, Recipient))
                response = requests.post(url, data=data)
                print(response.text)

    def get_send_data(self, time, touser) -> object:
        """
        获取发送消息data
        :param time: 时间
        :return: 发送的消息体
        """
        return {
            "touser": touser,
            "template_id": self.template_id,
            "topcolor": "#FF0000",
            # json数据对应模板
            "data": {
                "time": {
                    "value": time,
                    "color": "#173177"
                }
            }
        }

流程大概就是:初始化的时候,使用appID和appsecret获取获取accessToken;然后使用accessToke和用户的微信号发送消息。

有以下四个地方需要改成自己的内容

注:Python这个类有个__init__方法,这个方法会在对象初始化时候调用。

五.声音监听程序

python 复制代码
import time
from datetime import datetime

import numpy as np
import pyaudio

from SendMsg import SendMessage


class SoundListener:

    def __init__(self):
        self.sm = SendMessage()
        self.destroy = True
        self.display = False
        self.max = 500

    def startCheck(self):
        self.sound_listener()

    def isDestroy(self):
        return self.destroy

    def setAudioMax(self, maxValue):
        self.max = maxValue
        print("修改阈值:" + str(maxValue))

    def sound_listener(self):
        self.destroy = False
        CHUNK = 1024  # 每个音频块的大小
        FORMAT = pyaudio.paInt16  # 音频格式
        CHANNELS = 1  # 声道数量
        RATE = 44100  # 采样率

        p = pyaudio.PyAudio()

        stream = p.open(format=FORMAT,
                        channels=CHANNELS,
                        rate=RATE,
                        input=True,
                        frames_per_buffer=CHUNK)

        while True:
            if self.destroy:
                break
            data = np.frombuffer(stream.read(CHUNK), dtype=np.int16)
            if np.abs(data).mean() > self.max:  # 设置声音阈值
                print("声音正在发出!")
                # 在这里编写声音发出时需要执行的代码
                if not self.display:
                    self.display = True
                    # 发送消息
                    now_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    self.sm.send_message(now_time)
                else:
                    time.sleep(1)
            else:
                if self.display:
                    self.display = False
                    print("声音结束了!")

        stream.stop_stream()
        stream.close()
        p.terminate()

    def stop(self):
        self.destroy = True
        self.display = False

这里使用了Python的三方库pyaudio,打开麦克风录音,并通过录音数据判断是否有声音。

六.创建UI交互

python 复制代码
import threading
import tkinter as tk

from SoundListener import SoundListener

class CheckAudio:
    def __init__(self):
        self.sl = SoundListener()
        self.root = tk.Tk()

    def button_clicked(self):
        if not self.sl.isDestroy():
            self.root.label.config(text="未监听!")
            self.root.button.config(text="开始监听")
            threading.Thread(target=self.stopLis).start()
        else:
            self.root.label.config(text="监听中!")
            self.root.button.config(text="结束监听")
            threading.Thread(target=self.startLis).start()

    def stopLis(self):
        self.sl.stop()

    def startLis(self):
        self.sl.startCheck()

    def setAudioMax(self,v):
        self.sl.setAudioMax(float(v))

    def close_window(self):
        self.sl.stop()
        self.root.destroy()

    def start(self):
        # 创建主窗口
        root = self.root
        root.title("声音监听小程序")  # 设置窗口标题
        root.geometry("400x300")  # 设置窗口大小
        self.root.label = tk.Label(root, text="欢迎使用声音监听程序!", font=("Helvetica", 16))  # 创建标签控件
        self.root.label.pack(pady=20)
        # 创建按钮控件和回调函数
        self.root.button = tk.Button(root, text='开始监听', command=self.button_clicked)
        self.root.button.pack()

        # 添加一个 Scale 控件,默认垂直方向,步长设置为 100,长度为10000,滑动块的大小为 100,最后使用label参数文本
        sc = tk.Scale(root, from_=500, to=10000, orient=tk.HORIZONTAL, resolution=100, length=10000, sliderlength=100,
                      label="音量阈值控制", command=self.setAudioMax)
        sc.pack()

        #窗口关闭监听回调
        root.protocol("WM_DELETE_WINDOW", self.close_window)

        root.mainloop()


if __name__ == '__main__':
    CheckAudio().start()

这里使用了Python的UI库tkinter;使用threading创建子线程,防止主线程卡死。

写好似乎就可以运行了,点击IDEA顶部的运行按钮试试看

附:打包exe

调试运行可以,但是给别人使用,最好windows下打包成exe文件。

这里使用 PyInstaller

安装PyInstaller :

pip install pyinstaller

终端运行打包代码:

r 复制代码
pyinstaller -F -w checkAudio.py

生成的exe在以下路径中,也分享给需要的小伙伴使用吧!

相关推荐
极客代码2 分钟前
【Python TensorFlow】入门到精通
开发语言·人工智能·python·深度学习·tensorflow
义小深4 分钟前
TensorFlow|咖啡豆识别
人工智能·python·tensorflow
疯一样的码农8 分钟前
Python 正则表达式(RegEx)
开发语言·python·正则表达式
光影少年10 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_12 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891114 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾15 分钟前
前端基础-html-注册界面
前端·算法·html
Dragon Wu17 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym22 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫23 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js