GameSentenceMiner 2.5.10__py3-none-any.whl → 2.5.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
GameSentenceMiner/anki.py CHANGED
@@ -1,22 +1,22 @@
1
+ import time
2
+
1
3
  import base64
2
4
  import subprocess
3
5
  import threading
4
- import time
5
6
  import urllib.request
6
7
  from datetime import datetime, timedelta
8
+ from requests import post
7
9
 
8
- import requests as req
9
-
10
- from GameSentenceMiner import obs, util, notification, ffmpeg, gametext
11
-
10
+ from GameSentenceMiner import obs, util, notification, ffmpeg
12
11
  from GameSentenceMiner.configuration import *
13
12
  from GameSentenceMiner.configuration import get_config
14
13
  from GameSentenceMiner.gametext import get_text_event
15
14
  from GameSentenceMiner.model import AnkiCard
16
- from GameSentenceMiner.utility_gui import utility_window, get_utility_window
15
+ from GameSentenceMiner.utility_gui import get_utility_window
17
16
  from GameSentenceMiner.obs import get_current_game
18
17
  from GameSentenceMiner.util import remove_html_and_cloze_tags, combine_dialogue
19
18
 
19
+
20
20
  audio_in_anki = None
21
21
  screenshot_in_anki = None
22
22
  prev_screenshot_in_anki = None
@@ -309,7 +309,7 @@ def monitor_anki():
309
309
 
310
310
  # Fetch recent note IDs from Anki
311
311
  def get_note_ids():
312
- response = req.post(get_config().anki.url, json={
312
+ response = post(get_config().anki.url, json={
313
313
  "action": "findNotes",
314
314
  "version": 6,
315
315
  "params": {"query": "added:1"}
@@ -835,12 +835,6 @@ class ConfigApp:
835
835
  self.add_label_and_increment_row(obs_frame, "Password for the OBS WebSocket server.", row=self.current_row,
836
836
  column=2)
837
837
 
838
- ttk.Label(obs_frame, text="Start/Stop Buffer:").grid(row=self.current_row, column=0, sticky='W')
839
- self.obs_start_buffer = tk.BooleanVar(value=self.settings.obs.start_buffer)
840
- ttk.Checkbutton(obs_frame, variable=self.obs_start_buffer).grid(row=self.current_row, column=1, sticky='W')
841
- self.add_label_and_increment_row(obs_frame, "Start and Stop the Buffer when Script runs.", row=self.current_row,
842
- column=2)
843
-
844
838
  ttk.Label(obs_frame, text="Get Game From Scene Name:").grid(row=self.current_row, column=0, sticky='W')
845
839
  self.get_game_from_scene_name = tk.BooleanVar(value=self.settings.obs.get_game_from_scene)
846
840
  ttk.Checkbutton(obs_frame, variable=self.get_game_from_scene_name).grid(row=self.current_row, column=1,
@@ -128,7 +128,6 @@ class OBS:
128
128
  host: str = "localhost"
129
129
  port: int = 4455
130
130
  password: str = "your_password"
131
- start_buffer: bool = True
132
131
  get_game_from_scene: bool = True
133
132
  minimum_replay_size: int = 0
134
133
 
GameSentenceMiner/gsm.py CHANGED
@@ -1,5 +1,6 @@
1
+
2
+ import os.path
1
3
  import signal
2
- import time
3
4
  from subprocess import Popen
4
5
 
5
6
  import keyboard
@@ -10,6 +11,8 @@ from pystray import Icon, Menu, MenuItem
10
11
  from watchdog.events import FileSystemEventHandler
11
12
  from watchdog.observers import Observer
12
13
 
14
+ import time
15
+
13
16
  from GameSentenceMiner import anki
14
17
  from GameSentenceMiner import config_gui
15
18
  from GameSentenceMiner import configuration
@@ -28,11 +31,11 @@ from GameSentenceMiner.gametext import get_text_event, get_mined_line, GameLine
28
31
  from GameSentenceMiner.obs import check_obs_folder_is_correct
29
32
  from GameSentenceMiner.util import *
30
33
  from GameSentenceMiner.utility_gui import init_utility_window, get_utility_window
31
- from GameSentenceMiner.vad import silero_trim, whisper_helper, vosk_helper
32
34
 
33
35
  if is_windows():
34
36
  import win32api
35
37
 
38
+ silero_trim, whisper_helper, vosk_helper = None, None, None
36
39
  procs_to_close = []
37
40
  settings_window: config_gui.ConfigApp = None
38
41
  obs_paused = False
@@ -41,51 +44,39 @@ menu: Menu
41
44
  root = None
42
45
 
43
46
 
47
+
44
48
  class VideoToAudioHandler(FileSystemEventHandler):
45
49
  def on_created(self, event):
46
50
  if event.is_directory or ("Replay" not in event.src_path and "GSM" not in event.src_path):
47
51
  return
48
52
  if event.src_path.endswith(".mkv") or event.src_path.endswith(".mp4"): # Adjust based on your OBS output format
49
53
  logger.info(f"MKV {event.src_path} FOUND, RUNNING LOGIC")
50
- self.wait_for_stable_file(event.src_path)
54
+ wait_for_stable_file(event.src_path)
51
55
  self.convert_to_audio(event.src_path)
52
56
 
53
- @staticmethod
54
- def wait_for_stable_file(file_path, timeout=10, check_interval=0.5):
55
- elapsed_time = 0
56
- last_size = -1
57
-
58
- while elapsed_time < timeout:
59
- try:
60
- current_size = os.path.getsize(file_path)
61
- if current_size == last_size:
62
- return True
63
- last_size = current_size
64
- time.sleep(check_interval)
65
- elapsed_time += check_interval
66
- except Exception as e:
67
- logger.warning(f"Error checking file size, will still try updating Anki Card!: {e}")
68
- return False
69
- logger.warning("File size did not stabilize within the timeout period. Continuing...")
70
- return False
71
-
72
57
  @staticmethod
73
58
  def convert_to_audio(video_path):
74
- if get_utility_window().line_for_audio:
75
- line: GameLine = get_utility_window().line_for_audio
76
- get_utility_window().line_for_audio = None
77
- if get_config().advanced.audio_player_path:
78
- audio = VideoToAudioHandler.get_audio(line, line.next.time if line.next else None, video_path, temporary=True)
79
- play_audio_in_external(audio)
59
+ try:
60
+ if get_utility_window().line_for_audio:
61
+ line: GameLine = get_utility_window().line_for_audio
62
+ get_utility_window().line_for_audio = None
63
+ if get_config().advanced.audio_player_path:
64
+ audio = VideoToAudioHandler.get_audio(line, line.next.time if line.next else None, video_path, temporary=True)
65
+ play_audio_in_external(audio)
66
+ os.remove(video_path)
67
+ elif get_config().advanced.video_player_path:
68
+ play_video_in_external(line, video_path)
69
+ return
70
+ if get_utility_window().line_for_screenshot:
71
+ line: GameLine = get_utility_window().line_for_screenshot
72
+ get_utility_window().line_for_screenshot = None
73
+ screenshot = ffmpeg.get_screenshot_for_line(video_path, line)
74
+ os.startfile(screenshot)
80
75
  os.remove(video_path)
81
- elif get_config().advanced.video_player_path:
82
- play_video_in_external(line, video_path)
83
- return
84
- if get_utility_window().line_for_screenshot:
85
- line: GameLine = get_utility_window().line_for_screenshot
86
- get_utility_window().line_for_screenshot = None
87
- screenshot = ffmpeg.get_screenshot_for_line(video_path, line)
88
- os.startfile(screenshot)
76
+ return
77
+ except Exception as e:
78
+ logger.error(f"Error Playing Audio/Video: {e}")
79
+ logger.debug(f"Error Playing Audio/Video: {e}", exc_info=True)
89
80
  os.remove(video_path)
90
81
  return
91
82
  try:
@@ -158,10 +149,11 @@ class VideoToAudioHandler(FileSystemEventHandler):
158
149
  logger.error(f"Failed Processing and/or adding to Anki: Reason {e}")
159
150
  logger.debug(f"Some error was hit catching to allow further work to be done: {e}", exc_info=True)
160
151
  notification.send_error_no_anki_update()
161
- if get_config().paths.remove_video and os.path.exists(video_path):
162
- os.remove(video_path) # Optionally remove the video after conversion
163
- if get_config().paths.remove_audio and os.path.exists(vad_trimmed_audio):
164
- os.remove(vad_trimmed_audio) # Optionally remove the screenshot after conversion
152
+ finally:
153
+ if get_config().paths.remove_video and os.path.exists(video_path):
154
+ os.remove(video_path) # Optionally remove the video after conversion
155
+ if get_config().paths.remove_audio and os.path.exists(vad_trimmed_audio):
156
+ os.remove(vad_trimmed_audio) # Optionally remove the screenshot after conversion
165
157
 
166
158
 
167
159
  @staticmethod
@@ -175,26 +167,10 @@ class VideoToAudioHandler(FileSystemEventHandler):
175
167
  f"{obs.get_current_game(sanitize=True)}.{get_config().audio.extension}"))
176
168
  should_update_audio = True
177
169
  if get_config().vad.do_vad_postprocessing:
178
- match get_config().vad.selected_vad_model:
179
- case configuration.SILERO:
180
- should_update_audio = silero_trim.process_audio_with_silero(trimmed_audio, vad_trimmed_audio)
181
- case configuration.VOSK:
182
- should_update_audio = vosk_helper.process_audio_with_vosk(trimmed_audio, vad_trimmed_audio)
183
- case configuration.WHISPER:
184
- should_update_audio = whisper_helper.process_audio_with_whisper(trimmed_audio,
185
- vad_trimmed_audio)
170
+ should_update_audio = do_vad_processing(get_config().vad.selected_vad_model, trimmed_audio, vad_trimmed_audio)
186
171
  if not should_update_audio:
187
- match get_config().vad.backup_vad_model:
188
- case configuration.OFF:
189
- pass
190
- case configuration.SILERO:
191
- should_update_audio = silero_trim.process_audio_with_silero(trimmed_audio,
192
- vad_trimmed_audio)
193
- case configuration.VOSK:
194
- should_update_audio = vosk_helper.process_audio_with_vosk(trimmed_audio, vad_trimmed_audio)
195
- case configuration.WHISPER:
196
- should_update_audio = whisper_helper.process_audio_with_whisper(trimmed_audio,
197
- vad_trimmed_audio)
172
+ should_update_audio = do_vad_processing(get_config().vad.selected_vad_model, trimmed_audio,
173
+ vad_trimmed_audio)
198
174
  if not should_update_audio and get_config().vad.add_audio_on_no_results:
199
175
  logger.info("No voice activity detected, using full audio.")
200
176
  vad_trimmed_audio = trimmed_audio
@@ -206,6 +182,22 @@ class VideoToAudioHandler(FileSystemEventHandler):
206
182
  shutil.move(vad_trimmed_audio, final_audio_output)
207
183
  return final_audio_output, should_update_audio, vad_trimmed_audio
208
184
 
185
+
186
+ def do_vad_processing(model, trimmed_audio, vad_trimmed_audio, second_pass=False):
187
+ match model:
188
+ case configuration.OFF:
189
+ pass
190
+ case configuration.SILERO:
191
+ from GameSentenceMiner.vad import silero_trim
192
+ return silero_trim.process_audio_with_silero(trimmed_audio, vad_trimmed_audio)
193
+ case configuration.VOSK:
194
+ from GameSentenceMiner.vad import vosk_helper
195
+ return vosk_helper.process_audio_with_vosk(trimmed_audio, vad_trimmed_audio)
196
+ case configuration.WHISPER:
197
+ from GameSentenceMiner.vad import whisper_helper
198
+ return whisper_helper.process_audio_with_whisper(trimmed_audio, vad_trimmed_audio)
199
+
200
+
209
201
  def play_audio_in_external(filepath):
210
202
  exe = get_config().advanced.audio_player_path
211
203
 
@@ -228,18 +220,19 @@ def play_video_in_external(line, filepath):
228
220
 
229
221
  start, _, _ = get_video_timings(filepath, line)
230
222
 
231
- print(start)
232
-
233
- if "vlc" in get_config().advanced.video_player_path:
234
- command.append("--start-time")
235
- else:
236
- command.append("--start")
223
+ if start:
224
+ if "vlc" in get_config().advanced.video_player_path:
225
+ command.append("--start-time")
226
+ else:
227
+ command.append("--start")
228
+ command.append(convert_to_vlc_seconds(start))
229
+ command.append(os.path.normpath(filepath))
237
230
 
238
- command.extend([convert_to_vlc_seconds(start), os.path.normpath(filepath)])
231
+ logger.info(" ".join(command))
239
232
 
240
233
  try:
241
234
  proc = subprocess.Popen(command)
242
- print(f"Opened {filepath} in VLC.")
235
+ print(f"Opened {filepath} in {get_config().advanced.video_player_path}.")
243
236
  threading.Thread(target=remove_video_when_closed, args=(proc, filepath)).start()
244
237
  except FileNotFoundError:
245
238
  print("VLC not found. Make sure it's installed and in your PATH.")
@@ -279,7 +272,7 @@ def register_hotkeys():
279
272
  def get_screenshot():
280
273
  try:
281
274
  image = obs.get_screenshot()
282
- time.sleep(2) # Wait for ss to save
275
+ wait_for_stable_file(image, timeout=3)
283
276
  if not image:
284
277
  raise Exception("Failed to get Screenshot from OBS")
285
278
  encoded_image = ffmpeg.process_image(image)
@@ -472,9 +465,8 @@ def cleanup():
472
465
  util.keep_running = False
473
466
 
474
467
  if get_config().obs.enabled:
475
- if get_config().obs.start_buffer:
476
- obs.stop_replay_buffer()
477
- obs.disconnect_from_obs()
468
+ obs.stop_replay_buffer()
469
+ obs.disconnect_from_obs()
478
470
  if get_config().obs.close_obs:
479
471
  close_obs()
480
472
 
@@ -514,9 +506,9 @@ def initialize(reloading=False):
514
506
  if is_windows():
515
507
  download_obs_if_needed()
516
508
  download_ffmpeg_if_needed()
517
- # if get_config().obs.enabled:
518
- # if get_config().obs.open_obs:
519
- # obs_process = obs.start_obs()
509
+ if get_config().obs.enabled:
510
+ if get_config().obs.open_obs:
511
+ obs_process = obs.start_obs()
520
512
  # obs.connect_to_obs(start_replay=True)
521
513
  # anki.start_monitoring_anki()
522
514
  # gametext.start_text_monitor()
@@ -534,27 +526,29 @@ def initialize(reloading=False):
534
526
  def initialize_async():
535
527
  tasks = [gametext.start_text_monitor, connect_websocket, run_tray]
536
528
  threads = []
537
- if get_config().obs.enabled:
538
- if get_config().obs.open_obs:
539
- tasks.append(obs.start_obs)
540
- else:
541
- tasks.append(obs.connect_to_obs)
542
- tasks.append(anki.start_monitoring_anki)
543
- if get_config().vad.do_vad_postprocessing:
544
- if VOSK in (get_config().vad.backup_vad_model, get_config().vad.selected_vad_model):
545
- tasks.append(vosk_helper.get_vosk_model)
546
- if WHISPER in (get_config().vad.backup_vad_model, get_config().vad.selected_vad_model):
547
- tasks.append(whisper_helper.initialize_whisper_model)
529
+ tasks.append(anki.start_monitoring_anki)
548
530
  for task in tasks:
549
531
  threads.append(util.run_new_thread(task))
550
532
  return threads
551
533
 
552
- def check_async_init_done(threads):
553
- while True:
554
- if all(not thread.is_alive() for thread in threads):
555
- break
556
- time.sleep(0.5)
557
- logger.info("Script Fully Initialized. Happy Mining!")
534
+
535
+ def post_init():
536
+ def do_post_init():
537
+ global silero_trim, whisper_helper, vosk_helper
538
+ logger.info("Post-Initialization started.")
539
+ if get_config().obs.enabled:
540
+ obs.connect_to_obs()
541
+ check_obs_folder_is_correct()
542
+ from GameSentenceMiner.vad import vosk_helper
543
+ from GameSentenceMiner.vad import whisper_helper
544
+ if get_config().vad.is_vosk():
545
+ vosk_helper.get_vosk_model()
546
+ if get_config().vad.is_whisper():
547
+ whisper_helper.initialize_whisper_model()
548
+ if get_config().vad.is_silero():
549
+ from GameSentenceMiner.vad import silero_trim
550
+
551
+ util.run_new_thread(do_post_init)
558
552
 
559
553
 
560
554
  def handle_websocket_message(message: Message):
@@ -574,7 +568,6 @@ def main(reloading=False):
574
568
  init_utility_window(root)
575
569
  initialize(reloading)
576
570
  initialize_async()
577
- check_obs_folder_is_correct()
578
571
  observer = Observer()
579
572
  observer.schedule(VideoToAudioHandler(), get_config().paths.folder_to_watch, recursive=False)
580
573
  observer.start()
@@ -592,6 +585,7 @@ def main(reloading=False):
592
585
  root.after(0, settings_window.show)
593
586
  if get_config().general.open_multimine_on_startup:
594
587
  root.after(0, get_utility_window().show)
588
+ root.after(0, post_init)
595
589
  settings_window.add_save_hook(update_icon)
596
590
  settings_window.on_exit = exit_program
597
591
  root.mainloop()
@@ -606,4 +600,5 @@ def main(reloading=False):
606
600
 
607
601
 
608
602
  if __name__ == "__main__":
603
+ logger.info("Starting GSM")
609
604
  main()
GameSentenceMiner/obs.py CHANGED
@@ -28,12 +28,9 @@ def start_obs():
28
28
  return None
29
29
 
30
30
  try:
31
- obs_pid = is_obs_running(obs_path)
32
- if obs_pid:
33
- return obs_pid
34
- obs_process = subprocess.Popen([obs_path, '--disable-shutdown-check', '--portable'], cwd=os.path.dirname(obs_path))
31
+ obs_process = subprocess.Popen([obs_path, '--disable-shutdown-check', '--portable', '--startreplaybuffer'], cwd=os.path.dirname(obs_path))
32
+
35
33
  logger.info("OBS launched")
36
- connect_to_obs()
37
34
  return obs_process.pid
38
35
  except Exception as e:
39
36
  logger.error(f"Error launching OBS: {e}")
@@ -48,15 +45,6 @@ def check_obs_folder_is_correct():
48
45
  get_master_config().sync_shared_fields()
49
46
  save_full_config(get_master_config())
50
47
 
51
- def is_obs_running(obs_path):
52
- obs_path = os.path.abspath(obs_path) # Normalize path
53
- for process in psutil.process_iter(['exe']):
54
- try:
55
- if process.info['exe'] and os.path.abspath(process.info['exe']) == obs_path:
56
- return process.pid
57
- except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
58
- continue
59
- return False
60
48
 
61
49
  def get_obs_websocket_config_values():
62
50
  config_path = os.path.join(get_app_directory(), 'obs-studio', 'config', 'obs-studio', 'plugin_config', 'obs-websocket', 'config.json')
@@ -92,10 +80,8 @@ def get_obs_websocket_config_values():
92
80
 
93
81
 
94
82
  def on_connect(obs):
95
- logger.info("Connected to OBS WebSocket.")
96
- time.sleep(2)
97
- if get_config().obs.start_buffer:
98
- start_replay_buffer()
83
+ logger.info("Reconnected to OBS WebSocket.")
84
+ start_replay_buffer()
99
85
 
100
86
 
101
87
  def on_disconnect(obs):
@@ -111,9 +97,6 @@ def connect_to_obs():
111
97
  password=get_config().obs.password, authreconnect=1, on_connect=on_connect,
112
98
  on_disconnect=on_disconnect)
113
99
  client.connect()
114
-
115
- if get_config().obs.start_buffer:
116
- start_replay_buffer()
117
100
  update_current_game()
118
101
 
119
102
 
@@ -135,6 +118,7 @@ def do_obs_call(request, from_dict = None, retry=10):
135
118
  return from_dict(response.datain)
136
119
  return None
137
120
  except Exception as e:
121
+ logger.error(e)
138
122
  if "socket is already closed" in str(e) or "object has no attribute" in str(e):
139
123
  if retry > 0:
140
124
  time.sleep(1)
GameSentenceMiner/util.py CHANGED
@@ -6,6 +6,7 @@ import string
6
6
  import subprocess
7
7
  import sys
8
8
  import threading
9
+ import time
9
10
  from datetime import datetime
10
11
  from sys import platform
11
12
 
@@ -178,38 +179,31 @@ def combine_dialogue(dialogue_lines, new_lines=None):
178
179
 
179
180
  return new_lines
180
181
 
181
- # def import_vad_models():
182
- # silero_trim, whisper_helper, vosk_helper = None, None, None
183
- #
184
- # def check_and_install(package_name):
185
- # try:
186
- # importlib.import_module(package_name)
187
- # return True
188
- # except ImportError:
189
- # logger.warning(f"{package_name} is not installed. Attempting to install...")
190
- # try:
191
- # python_executable = sys.executable
192
- # subprocess.check_call([python_executable, "-m", "pip", "install", package_name])
193
- # logger.info(f"{package_name} installed successfully.")
194
- # return True
195
- # except subprocess.CalledProcessError as e:
196
- # logger.error(f"Failed to install {package_name}: {e}")
197
- # return False
198
- #
199
- # if get_config().vad.is_silero():
200
- # if check_and_install("silero_vad"):
201
- # from GameSentenceMiner.vad import silero_trim
202
- # else:
203
- # logger.error("Silero VAD is enabled and silero_vad package could not be installed.")
204
- # if get_config().vad.is_whisper():
205
- # if check_and_install("stable-ts"):
206
- # from GameSentenceMiner.vad import whisper_helper
207
- # else:
208
- # logger.error("Whisper is enabled and whisper package could not be installed.")
209
- # if get_config().vad.is_vosk():
210
- # if check_and_install("vosk"):
211
- # from GameSentenceMiner.vad import vosk_helper
212
- # else:
213
- # logger.error("Vosk is enabled and vosk package could not be installed.")
214
- #
215
- # return silero_trim, whisper_helper, vosk_helper
182
+ def wait_for_stable_file(file_path, timeout=10, check_interval=0.1):
183
+ elapsed_time = 0
184
+ last_size = -1
185
+
186
+ while elapsed_time < timeout:
187
+ try:
188
+ current_size = os.path.getsize(file_path)
189
+ if current_size == last_size:
190
+ return True
191
+ last_size = current_size
192
+ time.sleep(check_interval)
193
+ elapsed_time += check_interval
194
+ except Exception as e:
195
+ logger.warning(f"Error checking file size, will still try updating Anki Card!: {e}")
196
+ return False
197
+ logger.warning("File size did not stabilize within the timeout period. Continuing...")
198
+ return False
199
+
200
+
201
+ def import_vad_models():
202
+ silero_trim, whisper_helper, vosk_helper = None, None, None
203
+ if get_config().vad.is_silero():
204
+ from GameSentenceMiner.vad import silero_trim
205
+ if get_config().vad.is_whisper():
206
+ from GameSentenceMiner.vad import whisper_helper
207
+ if get_config().vad.is_vosk():
208
+ from GameSentenceMiner.vad import vosk_helper
209
+ return silero_trim, whisper_helper, vosk_helper
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameSentenceMiner
3
- Version: 2.5.10
3
+ Version: 2.5.12
4
4
  Summary: A tool for mining sentences from games. Update: Multi-Line Mining! Fixed!
5
5
  Author-email: Beangate <bpwhelan95@gmail.com>
6
6
  License: MIT License
@@ -97,7 +97,7 @@ steps before making an issue:
97
97
 
98
98
  - Try Restarting OBS
99
99
  - Make sure your hook is the best you can find. (Preferably it gives you the text RIGHT when the voice line starts)
100
- - Try Adjusting Offset Configuration in `config.toml` to better match your situation. (i.e. if the hook is late, add a
100
+ - Try Adjusting Offset Configuration in the config to better match your situation. (i.e. if the hook is late, add a
101
101
  negative beginning offset)
102
102
  - Try using "Trim beginning" in `VAD` settings.
103
103
 
@@ -1,15 +1,15 @@
1
1
  GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- GameSentenceMiner/anki.py,sha256=xeWU1jX1ZK6tZVnDPqhBzetkCxdbPUWG1LkUy0sfHVg,13089
3
- GameSentenceMiner/config_gui.py,sha256=v4XRxGqRddqCrdv1UHu4Gnp7aMjL-CCCHBFlTy1Y2v0,61265
4
- GameSentenceMiner/configuration.py,sha256=DXlwEV4A7X3yzVV6UomY2jmmYAZx_jjMRxZeweoCtRE,20149
2
+ GameSentenceMiner/anki.py,sha256=kMl-VvBkT_VtEjfTjliIHLGZwrJhHzTT1lRQ6qCdtYw,13062
3
+ GameSentenceMiner/config_gui.py,sha256=9w7qXuGwt2lMTo4xXwuZKZyaLCoXBvzIDxSMrJzsUi8,60787
4
+ GameSentenceMiner/configuration.py,sha256=u6Jm-Ox7PSZ1Cf5_AkV6hvQInayq7jXjLduf1eMK7Rc,20119
5
5
  GameSentenceMiner/ffmpeg.py,sha256=fzOxrn-a4KqFdUY2oove164CTDOSsdPQtzqRW5f1P7c,12002
6
6
  GameSentenceMiner/gametext.py,sha256=LORVdE2WEo1CDI8gonc7qxrhbS4KFKXFQVKjhlkpLbc,7368
7
- GameSentenceMiner/gsm.py,sha256=KKlI-wrk39XWfPEa9yqAlBwiusm6b-V5aITPFZCRWUs,24707
7
+ GameSentenceMiner/gsm.py,sha256=H6kG2HerHhY37jXWGoQCLWjtzOoxAU_tAJ4RY9pAWbc,23970
8
8
  GameSentenceMiner/model.py,sha256=JdnkT4VoPOXmOpRgFdvERZ09c9wLN6tUJxdrKlGZcqo,5305
9
9
  GameSentenceMiner/notification.py,sha256=FY39ChSRK0Y8TQ6lBGsLnpZUFPtFpSy2tweeXVoV7kc,2809
10
- GameSentenceMiner/obs.py,sha256=EcgQ0VdeYXGeXCyvk8mBiHBL-HHai037BoCXomH9ge4,8239
10
+ GameSentenceMiner/obs.py,sha256=MlxRToq5wALPI1XrD8rxEU-N8mWII91cNJWY7rUa5uI,7642
11
11
  GameSentenceMiner/package.py,sha256=YlS6QRMuVlm6mdXx0rlXv9_3erTGS21jaP3PNNWfAH0,1250
12
- GameSentenceMiner/util.py,sha256=tkaoU1bj8iPMTNwUCWUzFLAnT44Ot92D1tYwQMEnARw,7336
12
+ GameSentenceMiner/util.py,sha256=Awhy57vX4NgQzygqKaGQn2EJ75T0uiXlhmINFOWlQkU,6825
13
13
  GameSentenceMiner/utility_gui.py,sha256=H4aOddlsrVR768RwbMzYScCziuOz1JeySUigNrPlaac,7692
14
14
  GameSentenceMiner/communication/__init__.py,sha256=_jGn9PJxtOAOPtJ2rI-Qu9hEHVZVpIvWlxKvqk91_zI,638
15
15
  GameSentenceMiner/communication/send.py,sha256=oOJdCS6-LNX90amkRn5FL2xqx6THGm56zHR2ntVIFTE,229
@@ -21,9 +21,9 @@ GameSentenceMiner/vad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
21
21
  GameSentenceMiner/vad/silero_trim.py,sha256=-thDIZLuTLra3YBj7WR16Z6JeDgSpge2YuahprBvD8I,1585
22
22
  GameSentenceMiner/vad/vosk_helper.py,sha256=BI_mg_qyrjNbuEJjXSUDoV0FWEtQtEOAPmrrNixnZ_8,5974
23
23
  GameSentenceMiner/vad/whisper_helper.py,sha256=OF4J8TPPoKPJR1uFwrWAZ2Q7v0HJkVvNGmF8l1tACX0,3447
24
- gamesentenceminer-2.5.10.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
25
- gamesentenceminer-2.5.10.dist-info/METADATA,sha256=foslJf1hVD8xY5LLltn7GUYapOOXXszAJyxfXS1bqIM,5436
26
- gamesentenceminer-2.5.10.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
27
- gamesentenceminer-2.5.10.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
28
- gamesentenceminer-2.5.10.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
29
- gamesentenceminer-2.5.10.dist-info/RECORD,,
24
+ gamesentenceminer-2.5.12.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
25
+ gamesentenceminer-2.5.12.dist-info/METADATA,sha256=iibLRrqHFjwy-4U4_j1JhHB3USB-W8CR0AMpW_JneF0,5433
26
+ gamesentenceminer-2.5.12.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
27
+ gamesentenceminer-2.5.12.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
28
+ gamesentenceminer-2.5.12.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
29
+ gamesentenceminer-2.5.12.dist-info/RECORD,,