run.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. #!/usr/bin/env python3
  2. import json, pyaudio
  3. from vosk import Model, KaldiRecognizer
  4. import subprocess
  5. import pathlib
  6. import hashlib
  7. from multiprocessing import Process
  8. import logging
  9. import os
  10. logging.basicConfig()
  11. log = logging.getLogger("vosk")
  12. log_level = os.getenv("VOSK_LOG_LEVEL", "WARNING")
  13. log.info(f"{log_level}: log_level")
  14. log.setLevel(log_level)
  15. model = Model("/home/oleg/.local/share/chezmoi/vosk/small_model")
  16. rec = KaldiRecognizer(model, 16000)
  17. p = pyaudio.PyAudio()
  18. stream = p.open(
  19. format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=8000
  20. )
  21. stream.start_stream()
  22. def listen():
  23. while True:
  24. data = stream.read(4000, exception_on_overflow=True)
  25. if (rec.AcceptWaveform(data)) and (len(data) > 0):
  26. answer = json.loads(rec.Result())
  27. if answer["text"]:
  28. yield answer["text"]
  29. vosk_tts_cache_directory = pathlib.Path.home().joinpath(".cache", "vosk-tts")
  30. if not vosk_tts_cache_directory.is_dir():
  31. os.mkdir(vosk_tts_cache_directory)
  32. def mpv(cache_file_string, cache_preserve=True):
  33. log.debug(f"cache_file: {cache_file_string}")
  34. subprocess.run(["mpv", "--keep-open=no", cache_file_string])
  35. cache_file = pathlib.Path(cache_file_string)
  36. if not cache_preserve:
  37. cache_file.unlink(missing_ok=True)
  38. def tts(string, cache_preserve=True):
  39. cache_file = vosk_tts_cache_directory.joinpath(hashlib.sha256(string.encode()).hexdigest() + ".wav")
  40. if not cache_file.is_file():
  41. subprocess.run(
  42. [
  43. "/nix/store/y73im0yiraa1g3zk6ycks6gjxbqxy5p1-vosk-tts-0.3.54/bin/vosk-tts",
  44. "-n",
  45. "vosk-model-tts-ru-0.6-multi",
  46. "--input",
  47. string,
  48. "-o",
  49. cache_file,
  50. ]
  51. )
  52. cache_file_string = cache_file._str
  53. process = Process(target=mpv, args=(cache_file_string,cache_preserve,), daemon=True)
  54. process.start()
  55. def main():
  56. for text in listen():
  57. if "компьютер" in text and "вкл" in text:
  58. if "корич" in text and "шум" in text:
  59. tts("коричневый шум включен")
  60. subprocess.run(
  61. [
  62. "mpv",
  63. "--no-resume-playback",
  64. "--loop",
  65. "/srv/video/metube/Smoothed Brown Noise.webm",
  66. ]
  67. )
  68. if "монитор":
  69. tts("монитор включен")
  70. subprocess.run(
  71. [
  72. "swaymsg", "output DP-1 dpms on"
  73. ]
  74. )
  75. if "компьютер" in text and "выкл" in text:
  76. if "монитор":
  77. tts("монитор выключен")
  78. subprocess.run(
  79. [
  80. "swaymsg", "output DP-1 dpms off"
  81. ]
  82. )
  83. if (
  84. "компьютер" in text
  85. and "открой" in text
  86. and "поиск" in text
  87. and "кластер" in text
  88. ):
  89. subprocess.run(["firefox", "https://opensearch-dashboards.corp1.majordomo.ru/"])
  90. if "компьютер" in text and "перекл" in text and "звук" in text:
  91. tts("звук переключен")
  92. subprocess.run(
  93. [
  94. "pactl",
  95. "set-sink-mute",
  96. "alsa_output.pci-0000_30_00.6.analog-stereo",
  97. "toggle",
  98. ]
  99. )
  100. if "компьютер" in text and "тиш" in text and "звук" in text:
  101. tts("тише звук")
  102. subprocess.run(
  103. [
  104. "pactl",
  105. "set-sink-volume",
  106. "alsa_output.pci-0000_30_00.6.analog-stereo",
  107. "-5%",
  108. ]
  109. )
  110. if "компьютер" in text and "гром" in text and "звук" in text:
  111. tts("громче звук")
  112. subprocess.run(
  113. [
  114. "pactl",
  115. "set-sink-volume",
  116. "alsa_output.pci-0000_30_00.6.analog-stereo",
  117. "+5%",
  118. ]
  119. )
  120. if "компьютер" in text and "умен" in text and "яркость" in text:
  121. tts("умешить яркость")
  122. subprocess.run(
  123. [
  124. "brightness", "decrease", "5"
  125. ]
  126. )
  127. if "компьютер" in text and "увел" in text and "яркость" in text:
  128. tts("увеличить яркость")
  129. subprocess.run(
  130. [
  131. "brightness", "increase", "5"
  132. ]
  133. )
  134. if "компьютер" in text and "напиш" in text:
  135. tts("пишу текст")
  136. subprocess.run(
  137. [
  138. "wtype", " ".join(text.split(" ")[2:])
  139. ]
  140. )
  141. if "компьютер" in text and "нажми" in text:
  142. tts("нажимаю")
  143. if "пробел" in text:
  144. subprocess.run(
  145. [
  146. "wtype", "-k", "space"
  147. ]
  148. )
  149. if "компьютер" in text and "сотри" in text:
  150. tts("стираю текст")
  151. subprocess.run(
  152. [
  153. "wtype", "-M", "ctrl", "a", "-m", "ctrl"
  154. ]
  155. )
  156. subprocess.run(
  157. [
  158. "wtype", "-k", "Delete"
  159. ]
  160. )
  161. if "компьютер" in text and "полный" in text and "кран" in text:
  162. tts("полный экран")
  163. subprocess.run(
  164. [
  165. "wtype", "-M", "win", "f", "-m", "win"
  166. ]
  167. )
  168. if "компьютер" in text and "курсор" in text and "лев" in text:
  169. tts("курсор влево")
  170. subprocess.run(
  171. [
  172. "wtype", "-M", "win", "h", "-m", "win"
  173. ]
  174. )
  175. if "компьютер" in text and "курсор" in text and "прав" in text:
  176. tts("курсор вправо")
  177. subprocess.run(
  178. [
  179. "wtype", "-M", "win", "l", "-m", "win"
  180. ]
  181. )
  182. log.info(text)
  183. if __name__ == '__main__':
  184. main()