首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在windows上使用鼠标、键盘和语音检测活动

在windows上使用鼠标、键盘和语音检测活动
EN

Stack Overflow用户
提问于 2020-02-05 12:49:48
回答 1查看 387关注 0票数 4

我们在Python上有一个模块(通过win32)来检测GetLastInputInfo和GetTickCount的用户鼠标和键盘活动。如何在GetLastInputInfo中注册语音活动?

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

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

代码语言:javascript
复制
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("-")

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

代码语言:javascript
复制
# 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))
EN

回答 1

Stack Overflow用户

发布于 2020-02-12 13:30:25

如果你想在不中断用户的情况下做一些事情,你可以在threading中使用multithreading

如果您希望将某些内容保存在每个线程都可以使用的变量中,则可以使用queue

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

  1. 导入模块

代码语言:javascript
复制
import threading
import queue

  1. 创建共享变量

代码语言:javascript
复制
shared_var = queue.Queue()

  1. 创建一个检查所需内容(在本例中为audio)的函数,并编辑共享变量

编辑共享变量:shared_var.put(item)

(在这种情况下,只要检测到音频,你就可以说audio_detected.put(True)和/或current_tick_count.put(tick_count),或者类似的东西。)

check and pass >

  1. 创建一个线程并传入您创建的函数来检查

代码语言:javascript
复制
thread = threading.Thread(target=function, args=arguments)

其中,target是要在这个新的tread中调用的函数,args是需要传递给函数的参数

  1. 启动新线程

代码语言:javascript
复制
thread.start()

  1. 在主线程或新线程上,对该变量执行您想要的操作

shared_var.get()将等待,直到将某些内容添加到shared_var中,然后返回添加的内容。

示例代码:

代码语言:javascript
复制
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,但我知道 ,所以你可以使用它并添加你的代码。如果你愿意,你可以用你的代码编辑答案。

我希望这对你有帮助!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60069201

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档