import os import time import logging import requests import speech_recognition as sr import pygame from ctypes import * # smart_mic.py 맨 위 import 아래 추가 import os # 불필요한 로그 억제 os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = "hide" from ctypes import * def py_error_handler(filename, line, function, err, fmt): pass ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p) c_error_handler = ERROR_HANDLER_FUNC(py_error_handler) try: asound = cdll.LoadLibrary('libasound.so.2') asound.snd_lib_error_set_handler(c_error_handler) except: pass # ALSA 에러 로그 숨기기 ERROR_HANDLER_FUNC = CFUNCTYPE(None, c_char_p, c_int, c_char_p, c_int, c_char_p) def py_error_handler(filename, line, function, err, fmt): pass c_error_handler = ERROR_HANDLER_FUNC(py_error_handler) try: asound = cdll.LoadLibrary('libasound.so.2') asound.snd_lib_error_set_handler(c_error_handler) except: pass logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s') logger = logging.getLogger(__name__) # [환경 설정] # VM_IP 자리에 오픈클로 VM의 실제 IP를 넣으세요. OPENCLAW_API_URL = "http://192.168.0.149:18789/api/v1/chat" WAKE_WORD = "애미나이" MIC_INDEX = 3 # 현재 확인된 장치 번호 def send_to_openclaw(audio_data): """녹음된 명령어를 오픈클로로 슛!""" try: # 파일 저장 확인을 위해 ls -al 에서 보일 이름을 고정합니다. filename = "cmd.wav" with open(filename, "wb") as f: f.write(audio_data.get_wav_data()) logger.info(f">>> {filename} 생성 완료! 오픈클로 전송 시작...") with open(filename, "rb") as f: files = {'file': (filename, f, 'audio/wav')} response = requests.post(OPENCLAW_API_URL, files=files, timeout=20) logger.info(f"오픈클로 서버 응답: {response.status_code}") except Exception as e: logger.error(f"전송 실패: {e}") def main(): recognizer = sr.Recognizer() recognizer.energy_threshold = 400 recognizer.pause_threshold = 1.0 # 말이 끝날 때까지 조금 더 넉넉히 기다림 mic = sr.Microphone(device_index=MIC_INDEX) logger.info(f"==== '{WAKE_WORD}' 대기 중 (포트 18789) ====") while True: try: with mic as source: # 호출어 인식 단계 audio = recognizer.listen(source, timeout=None, phrase_time_limit=3) try: text = recognizer.recognize_google(audio, language='ko-KR') # "에미나이", "애미나이" 모두 대응 if "미나이" in text: logger.info(f"[{text}] 감지됨! 명령을 말씀하세요...") # 스피커로 "네" 출력 (연결된 스피커가 있다면) # play_feedback("네") with mic as source: logger.info("명령 녹음 중 (5초)...") # 호출어 감지 후 5초간 집중 녹음 cmd_audio = recognizer.listen(source, timeout=5, phrase_time_limit=10) # 녹음 끝나면 바로 전송 및 파일 생성 send_to_openclaw(cmd_audio) except sr.UnknownValueError: continue except Exception as e: logger.error(f"루프 오류: {e}") time.sleep(1) if __name__ == "__main__": main()