我们在 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 。
这将在不同的线程中运行您需要运行的任何内容,并保存在共享变量上。
- 导入模块
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,但我知道threading和 queue所以你可以使用它并添加你的代码。如果您愿意,可以使用其中的代码编辑答案。
我希望这有帮助!
关于python - 在 Windows 上使用鼠标、键盘和语音检测事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60069201/