Обнаружение активности с помощью мыши, клавиатуры и голоса на windows - PullRequest
4 голосов
/ 05 февраля 2020

У нас есть модуль на Python (через win32) для определения активности мыши и клавиатуры пользователя с помощью GetLastInputInfo и GetTickCount. Как мы можем зарегистрировать активность Voice в GetLastInputInfo?

Или, может быть, мы можем добавить синтезированный вход для обновления GetLastInputInfo каждый раз, когда mi c обнаруживает голосовой ввод? но можем ли мы сделать это, не прерывая пользователя?

Пример кода на 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))

1 Ответ

0 голосов
/ 12 февраля 2020

Если вы хотите что-то сделать, не прерывая пользователя, вы можете использовать многопоточность с многопоточностью .
Если вы хотите сохранить что-то в переменной, которую может сделать каждый поток использовать, вы можете использовать очередь .

Это будет запускать все, что вам нужно, в другом потоке и сохранять в общей переменной.

  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, но я знаю threading и queue , так что вы можете просто поработать с этим и добавить свой код. Если вы хотите, вы можете отредактировать ответ со своим кодом.

Надеюсь, это поможет!

...