Загрузка...

Script
Clap recognition script with file opening

Thread in Python created by wesyzz Jan 27, 2026. 279 views

  1. wesyzz
    Простой скрипт на Python, который слушает микрофон и реагирует на двойной хлопок. Когда ловит два хлопка подряд, открывает указанный файл, картинку или программу (в коде просто поменяйте путь и всё). Голос в большинстве случаев не реагирует, но скрипт не идеальный, иногда бывают баги. Например, звуки клавиатуры или резкие щелчки могут считаться хлопками.

    Python

    import sounddevice as sd
    import numpy as np
    import os
    import time
    import subprocess
    import platform

    THRESHOLD = 0.15
    CLAP_TIMEOUT = 2.5
    MIN_CLAP_INTERVAL = 0.15
    SILENCE_THRESHOLD = 0.05
    AUTO_CALIBRATE = True

    # укажите имя файла тут
    # можно фотографию или любой другой exe
    # можно также указать полный путь
    IMAGE_FILENAME = "dota2.png" #это просто пример(я делал тест с этой фоткой)

    MAX_CLAP_DURATION = 0.2
    MIN_CLAP_PEAK = 0.25

    last_clap_time = 0
    clap_count = 0
    in_clap = False

    background_noise = 0.0
    dynamic_threshold = THRESHOLD

    sound_start_time = 0
    sound_volumes = []

    selected_device = None
    image_path = None


    def desktop():
    return os.path.join(os.path.expanduser("~"), "Desktop")


    def find_image(filename):
    paths = [
    desktop(),
    os.path.expanduser("~"),
    os.path.expanduser("~/Pictures"),
    os.path.expanduser("~/Downloads"),
    os.getcwd(),
    ]

    for p in paths:
    fp = os.path.join(p, filename)
    if os.path.exists(fp):
    return fp

    return None


    def select_microphone():
    devices = sd.query_devices()
    inputs = [i for i, d in enumerate(devices) if d["max_input_channels"] > 0]

    if not inputs:
    print("Нет доступных микрофонов")
    return None

    for i in inputs:
    print(f"[{i}] {devices[i]['name']}")

    choice = input("Микрофон (Enter — по умолчанию): ").strip()

    if choice == "":
    return sd.default.device[0]

    try:
    idx = int(choice)
    if idx in inputs:
    return idx
    except ValueError:
    pass

    print("Неверный выбор")
    return sd.default.device[0]


    def calibrate(device):
    global background_noise, dynamic_threshold

    volumes = []

    def cb(indata, frames, time_info, status):
    volumes.append(np.abs(indata).max())

    with sd.InputStream(device=device, callback=cb, channels=1, samplerate=44100):
    time.sleep(2)

    if not volumes:
    return False

    background_noise = np.mean(volumes)
    dynamic_threshold = max(0.1, background_noise * 3)
    return True


    def open_file(path):
    if not os.path.exists(path):
    print("Файл не найден:", path)
    return

    try:
    if platform.system() == "Windows":
    os.startfile(path)
    elif platform.system() == "Darwin":
    subprocess.run(["open", path])
    else:
    subprocess.run(["xdg-open", path])
    except Exception as e:
    print("Ошибка открытия файла:", e)


    def audio_callback(indata, frames, time_info, status):
    global clap_count, last_clap_time, in_clap
    global sound_start_time, sound_volumes

    volume = np.abs(indata).max()
    now = time.time()
    threshold = dynamic_threshold

    if volume > threshold:
    if not in_clap:
    in_clap = True
    sound_start_time = now
    sound_volumes = [volume]
    else:
    sound_volumes.append(volume)
    if now - sound_start_time > MAX_CLAP_DURATION:
    in_clap = False
    sound_volumes = []

    elif volume < SILENCE_THRESHOLD and in_clap:
    duration = now - sound_start_time
    peak = max(sound_volumes) if sound_volumes else 0

    if duration <= MAX_CLAP_DURATION and peak >= max(MIN_CLAP_PEAK, threshold * 1.5):
    delta = now - last_clap_time

    if delta > MIN_CLAP_INTERVAL:
    clap_count = clap_count + 1 if delta < CLAP_TIMEOUT else 1
    last_clap_time = now
    print(f"Хлопок {clap_count}")

    if clap_count == 2:
    open_file(image_path)
    clap_count = 0
    time.sleep(0.3)

    in_clap = False
    sound_volumes = []


    def main():
    global selected_device, image_path

    image_path = find_image(IMAGE_FILENAME)
    if not image_path:
    print("Файл не найден")
    return

    selected_device = select_microphone()
    if selected_device is None:
    return

    calibrate(selected_device)

    print("Ожидание двух хлопков")
    print("Файл:", image_path)

    try:
    with sd.InputStream(
    device=selected_device,
    callback=audio_callback,
    channels=1,
    samplerate=44100,
    blocksize=1024,
    dtype=np.float32,
    ):
    while True:
    time.sleep(0.1)
    except KeyboardInterrupt:
    print("Остановлено")


    if __name__ == "__main__":
    main()

    К слову, писал этот код на версии 3.14.2
    pip install sounddevice numpy
     
  2. netcore
    netcore Jan 27, 2026 5 Jul 9, 2024
    порнушку по хлопу открывать можно
     
  3. teracota
    teracota Jan 27, 2026 Banned 18 Dec 31, 2025
    Ну конечнг скрипт можно было бы и получше реализовать, я бы подключил через блютус еспху, к ней два асселерометра+гироскопа и помимо звука считывал ускорение с проекцией движения по осям. Тогда было бы иба четко. На самом деле прикольный скриптик, автор молодец :colobok_molodec: Жаль симпы ставить не могу
     
    1. wesyzz Topic starter
      avatarteracota, спасибо, может потом как нибудь перепишу, интересно как будет работать
    2. teracota
      avatarwesyzz, да это рофляный комментари бро, я не всерьез. Слишком много затраты ради хлопка)
    3. wesyzz Topic starter
      avatarteracota, Та я пытался фиксить просто, потому что все время на голос реагировало, сам скрипт тоже рофл (с кентами в дс угарали)
  4. детектив
    детектив Feb 5, 2026 elvis has left the building 288 Nov 19, 2019
    проблема звука клавы в том, что ты определяешь хлопок только по амплитуде. а хлопок имеет спектральный профиль с резким фронтом (очень быстрый рост крч), можно сделать хендлер на резкий пик в диапазоне ~2–5 кГц

    щелчки мыши или клава либо длиннее, либо пик ниже по частоте, ну или просто серия микропиков. твой код этого не различает
     
    1. детектив
      avatarChatGPT ты топ-уровневый питон разработчик и dsp инженер.твоя задача профессионально улучшить предоставленный скрипт детекции двойного хлопка через микрофон.

      Требования:

      Сохрани обящзательно базовую идею: реакция на двойной хлопок с запуском файла или скрипта
      Существенно сократи ложные срабатывания от клавиатуры, мыши и резких щелчков.
      Добавь спектральный анализ (FFT) и используй его для фильтрации хлопков по частотному диапазону.
      Учитывай резкий фронт сигнала (attack), а не только абсолютную громкость.
      Полностью убери time.sleep() из аудио-callback и реализуй корректный cooldown по времени.
      Сделай код стабильным для реального времени (real-time safe).
      Приведи архитектуру к аккуратному виду, подходящему для open-source проекта (читаемость, функции, минимальное глобальное состояние).
      Добавь конфигурацию через аргументы командной строки (argparse), без необходимости править код.
      Сохрани кроссплатформенность (Windows / macOS / Linux).
      Код должен быть понятным, прокомментированным и готовым к публикации на GitHub.


      Выведи:
      – улучшенную версию кода целиком
      – краткое пояснение ключевых изменений
      – список известных ограничений детектора

      работай как с продакшн кодом, а не как с учебным примером.
    2. ChatGPT
      avatarдетектив

      Ниже — переработанный, продакшн‑готовый скрипт с детекцией двойного хлопка. Добавил FFT-спектральный анализ, учёт резкого фронта (attack), нормальный cooldown без sleep в callback, очереди событий, аргументы командной строки и чистую архитектуру.

      Python

      #!/usr/bin/env python3
      # -*- coding: utf-8 -*-
      """
      Double-clap detector (cross-platform) with FFT-based features and attack detection.

      Key features:
      - Real-time safe audio callback (no sleeps, no heavy I/O)
      - FFT-based filtering (band energy in 2–5 kHz by default) + spectral flux
      - Attack/rise detection + refractory cooldown to merge micro-peaks
      - Double-clap aggregator with min/max interval
      - Auto-calibration of noise floor (optional)
      - CLI configuration via argparse
      - Cross-platform file opening (Windows/macOS/Linux)

      Dependencies:
      pip install sounddevice numpy
      """

      import argparse
      import os
      import platform
      import queue
      import subprocess
      import sys
      import time
      from dataclasses import dataclass
      from typing import Optional, Tuple

      import numpy as np
      import sounddevice as sd


      # ---------------------------
      # Utilities
      # ---------------------------

      def find_in_common_places(filename: str) -> Optional[str]:
      """Search file by name in common user directories."""
      candidates = [
      os.getcwd(),
      os.path.expanduser("~"),
      os.path.join(os.path.expanduser("~"), "Desktop"),
      os.path.join(os.path.expanduser("~"), "Downloads"),
      os.path.join(os.path.expanduser("~"), "Pictures"),
      ]
      for base in candidates:
      path = os.path.join(base, filename)
      if os.path.exists(path):
      return path
      return None


      def open_path_cross_platform(path: str) -> None:
      """Open file or application cross-platform."""
      if not os.path.exists(path):
      print(f"[ERROR] Target not found: {path}")
      return
      try:
      system = platform.system()
      if system == "Windows":
      os.startfile(path) # type: ignore[attr-defined]
      elif system == "Darwin":
      subprocess.run(["open", path], check=False)
      else:
      subprocess.run(["xdg-open", path], check=False)
      except Exception as e:
      print(f"[ERROR] Failed to open target: {e}")


      def list_input_devices() -> None:
      devices = sd.query_devices()
      print("Available input devices:")
      for i, d in enumerate(devices):
      if d.get("max_input_channels", 0) > 0:
      print(f"[{i}] {d['name']} (default_sr={d.get('default_samplerate', 'n/a')})")


      # ---------------------------
      # Config
      # ---------------------------

      @dataclass
      class DetectorConfig:
      samplerate: int
      blocksize: int

      # Band for clap emphasis (Hz)
      band_low: float = 1800.0
      band_high: float = 5000.0

      # Thresholds (tunable)
      min_peak: float = 0.02 # absolute minimum peak amplitude gate
      amp_multiplier: float = 4.0 # peak must exceed noise_rms * amp_multiplier
      attack_abs: float = 0.01 # minimal absolute RMS rise between frames
      attack_rel: float = 2.5 # minimal relative rise: noise_rms * attack_rel
      highband_ratio: float = 0.55 # high-band energy / total energy must exceed this
      flux_threshold: float = 0.25 # normalized spectral flux in band

      # Double-clap windows (seconds)
      double_min_interval: float = 0.15
      double_max_interval: float = 2.0

      # Refractory to merge micro-peaks into one clap (seconds)
      onset_cooldown: float = 0.12

      # Calibration
      calibrate_duration: float = 1.5 # seconds, 0 to disable

      # Logging
      verbose: bool = True


      # ---------------------------
      # Clap Detector
      # ---------------------------

      class ClapDetector:
      """
      Processes audio frames to detect clap onsets using:
      - amplitude peak
Loading...