python - 在 Windows 上使用鼠标、键盘和语音检测事件

标签 python windows win32com pyaudio

我们在 Python 上有一个模块(通过 win32),可以通过 GetLastInputInfo 和 GetTickCount 检测用户鼠标和键盘事件。我们如何在 GetLastInputInfo 中注册 Voice 事件?

或者我们可以添加一个合成输入来在每次麦克风检测到语音输入时更新 GetLastInputInfo 吗?但我们可以在不打扰用户的情况下做到这一点吗?

Pyaudio 上按音量检测用户语音的示例代码:

audio = pyaudio.PyAudio()
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
CHUNK = 1024

# recording prerequisites
stream = audio.open(format=FORMAT, channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

while True:
   data = stream.read(CHUNK)
   data_chunk = array('h', data)
   vol = max(data_chunk)
   if vol >= 500:
      # voice detected from mic
      print("talking - {}".format(vol))
   else:
      print("-")

检测用户输入的示例代码:

# code to get inactivity
class LastInputInfo(Structure):
    _fields_ = [
        ("cbSize", UINT),
        ("dwTime", DWORD)
    ]


def _getLastInputTick() -> int:
    """
    retrieves the last input action
        :return: int
    """
    prototype = WINFUNCTYPE(BOOL, POINTER(LastInputInfo))
    paramflags = ((1, "lastinputinfo"), )
    # type: ignore
    c_GetLastInputInfo = prototype(("GetLastInputInfo", ctypes.windll.user32), paramflags)  

    l = LastInputInfo()
    l.cbSize = ctypes.sizeof(LastInputInfo)
    assert 0 != c_GetLastInputInfo(l)
    return l.dwTime


def _getTickCount() -> int:
    """
    :return: int
        tick count
    """
    prototype = WINFUNCTYPE(DWORD)
    paramflags = ()
    c_GetTickCount = prototype(("GetTickCount", ctypes.windll.kernel32), paramflags)  # type: ignore
    return c_GetTickCount()


def seconds_since_last_input():
    """
    :return: float
        the time of user input
    """
    seconds_since_input = (_getTickCount() - _getLastInputTick()) / 1000
    return seconds_since_input

# inactivity in N seconds
seconds_since_input = seconds_since_last_input()
inactive_seconds = 10
while True:
    # Becomes active
    if afk and seconds_since_input < inactive_seconds:
        afk = False

    #becomes afk
    elif not afk and seconds_since_input >= inactive_seconds:
        afk = True

    print("afk status: {}, seconds since last input :{}".format(seconds_since_input))

最佳答案

如果您想在不打扰用户的情况下执行某些操作,可以使用 threading多线程 .
如果你想在每个线程都可以使用的变量中保存一些内容,你可以使用 queue

这将在不同的线程中运行您需要运行的任何内容,并保存在共享变量上。

  1. 导入模块
import threading
import queue
  • 创建共享变量
  • shared_var = queue.Queue()
    
  • 创建一个函数来检查您想要的内容(在本例中为音频),并编辑共享变量
  • 编辑共享变量:shared_var.put(item)
    (在这种情况下,每当检测到音频时,您都可以说 audio_detected.put(True) 和/或 current_tick_count.put(tick_count),或类似的内容`)

  • 创建一个线程并传入您要检查的函数
  • thread = threading.Thread(target=function, args=arguments)
    

    其中 target 是您要在此新步骤中调用的函数,args 是您需要传递到函数中的参数

  • 启动新线程
  • thread.start()
    
  • 在主线程或新线程上,使用该变量执行您想要的操作
    shared_var.get() 将等待,直到向 shared_var 添加内容,然后返回添加的内容。
  • 示例代码:

    import threading
    import queue
    import time
    
    text = queue.Queue()
    
    def change(text):
        time.sleep(3)
        text.put("hello world")
    
    
    
    thread = threading.Thread(target=change, args=(text,))
    #                                                  ^ IMPORTANT! (,)
    thread.start()
    
    
    def display(text):
        text = text.get() # This will wait till text has somthing inside and then returns it
        print(text)
    
    
    thread2 = threading.Thread(target=display, args=(text,))
    #                                                    ^ IMPORTANT! (,)
    thread2.start()
    
    input() # To show it won't interrupt the user until the text has something
    

    如果这个答案不太清楚,我很抱歉。我不熟悉pyaudio和win32,但我知道threadingqueue所以你可以使用它并添加你的代码。如果您愿意,可以使用其中的代码编辑答案。

    我希望这有帮助!

    关于python - 在 Windows 上使用鼠标、键盘和语音检测事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60069201/

    相关文章:

    python - 是否可以在机器上没有 Microsoft Office 的情况下运行 win32com 脚本

    python - python字典中的求和

    python - 如何在Python中显示变量名称?

    python - 获取目录中所有文件名的列表及其原始文件夹顺序

    java - 为什么我每次尝试运行 android studio 应用程序时都会遇到相同的错误?

    c++ - 如何在未安装 Visual Studio 的计算机上查看给定线程中正在运行哪个 DLL?

    Python 选择具有相似名称的列

    python - DataFrame eval 在表达式中使用函数名称

    C 串行通信。 WriteFile 成功,但我的设备仅处理第一个字符

    python - .doc 到 pdf 使用 python