GameSentenceMiner 2.10.5__py3-none-any.whl → 2.10.7__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.
@@ -271,9 +271,10 @@ class ConfigApp:
271
271
  video_player_path=self.video_player_path.get(),
272
272
  multi_line_line_break=self.multi_line_line_break.get(),
273
273
  multi_line_sentence_storage_field=self.multi_line_sentence_storage_field.get(),
274
- use_anki_note_creation_time=self.use_anki_note_creation_time.get(),
274
+ # use_anki_note_creation_time=self.use_anki_note_creation_time.get(),
275
275
  ocr_websocket_port=int(self.ocr_websocket_port.get()),
276
276
  texthooker_communication_websocket_port=int(self.texthooker_communication_websocket_port.get()),
277
+ plaintext_websocket_port=int(self.plaintext_websocket_export_port.get()),
277
278
  ),
278
279
  ai=Ai(
279
280
  enabled=self.ai_enabled.get(),
@@ -1329,14 +1330,23 @@ class ConfigApp:
1329
1330
  self.texthooker_communication_websocket_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
1330
1331
  self.current_row += 1
1331
1332
 
1332
- HoverInfoLabelWidget(advanced_frame, text="Use Anki Creation Date for Audio Timing:",
1333
- tooltip="Use the Anki note creation date for audio timing instead of the OBS replay time.",
1333
+ HoverInfoLabelWidget(advanced_frame, text="Plaintext Websocket Export Port:",
1334
+ tooltip="Port for GSM Plaintext WebSocket Export communication. Does nothing right now, hardcoded to 55002",
1334
1335
  row=self.current_row, column=0)
1335
- self.use_anki_note_creation_time = tk.BooleanVar(value=self.settings.advanced.use_anki_note_creation_time)
1336
- ttk.Checkbutton(advanced_frame, variable=self.use_anki_note_creation_time, bootstyle="round-toggle").grid(
1337
- row=self.current_row, column=1, sticky='W', pady=2)
1336
+ self.plaintext_websocket_export_port = ttk.Entry(advanced_frame)
1337
+ self.plaintext_websocket_export_port.insert(0, str(self.settings.advanced.plaintext_websocket_port))
1338
+ self.plaintext_websocket_export_port.grid(row=self.current_row, column=1, sticky='EW', pady=2)
1338
1339
  self.current_row += 1
1339
1340
 
1341
+
1342
+ # HoverInfoLabelWidget(advanced_frame, text="Use Anki Creation Date for Audio Timing:",
1343
+ # tooltip="Use the Anki note creation date for audio timing instead of the OBS replay time.",
1344
+ # row=self.current_row, column=0)
1345
+ # self.use_anki_note_creation_time = tk.BooleanVar(value=self.settings.advanced.use_anki_note_creation_time)
1346
+ # ttk.Checkbutton(advanced_frame, variable=self.use_anki_note_creation_time, bootstyle="round-toggle").grid(
1347
+ # row=self.current_row, column=1, sticky='W', pady=2)
1348
+ # self.current_row += 1
1349
+
1340
1350
  HoverInfoLabelWidget(advanced_frame, text="Reset Line Hotkey:",
1341
1351
  tooltip="Hotkey to reset the current line of dialogue.", row=self.current_row, column=0)
1342
1352
  self.reset_line_hotkey = ttk.Entry(advanced_frame)
GameSentenceMiner/gsm.py CHANGED
@@ -198,6 +198,7 @@ class VideoToAudioHandler(FileSystemEventHandler):
198
198
  vad_result = vad_processor.trim_audio_with_vad(trimmed_audio, vad_trimmed_audio, game_line)
199
199
  if timing_only:
200
200
  return vad_result
201
+ vad_trimmed_audio = vad_result.output_audio
201
202
  if get_config().audio.ffmpeg_reencode_options_to_use and os.path.exists(vad_trimmed_audio):
202
203
  ffmpeg.reencode_file_with_user_config(vad_trimmed_audio, final_audio_output,
203
204
  get_config().audio.ffmpeg_reencode_options_to_use)
GameSentenceMiner/obs.py CHANGED
@@ -334,7 +334,7 @@ def get_screenshot(compression=-1):
334
334
  logger.error(f"Error getting screenshot: {e}")
335
335
  return None
336
336
 
337
- def get_screenshot_base64():
337
+ def get_screenshot_base64(compression=0, width=None, height=None):
338
338
  try:
339
339
  # update_current_game()
340
340
  current_game = get_current_game()
@@ -346,10 +346,8 @@ def get_screenshot_base64():
346
346
  if not current_source_name:
347
347
  logger.error("No active source found in the current scene.")
348
348
  return None
349
- response = client.get_source_screenshot(name=current_source_name, img_format='png', quality=0, width=None, height=None)
349
+ response = client.get_source_screenshot(name=current_source_name, img_format='png', quality=compression, width=width, height=height)
350
350
  if response and response.image_data:
351
- with open('screenshot_response.txt', 'wb') as f:
352
- f.write(str(response).encode())
353
351
  return response.image_data
354
352
  else:
355
353
  logger.error(f"Error getting base64 screenshot: {response}")
@@ -91,7 +91,7 @@ def get_window(title):
91
91
  import pygetwindow as gw
92
92
  all_windows = gw.getWindowsWithTitle(title)
93
93
  if not all_windows:
94
- raise ValueError(f"No windows found with title '{title}'.")
94
+ return None
95
95
 
96
96
  filtered_windows = []
97
97
  for window in all_windows:
@@ -101,7 +101,7 @@ def get_window(title):
101
101
  filtered_windows.append(window)
102
102
 
103
103
  if not filtered_windows:
104
- raise ValueError(f"No non-cmd.exe windows found with title '{title}'.")
104
+ return None
105
105
 
106
106
  ret = None
107
107
  for window in filtered_windows:
@@ -182,11 +182,11 @@ all_cords = None
182
182
  rectangles = None
183
183
  last_ocr2_result = ""
184
184
 
185
- def do_second_ocr(ocr1_text, time, img, filtering):
185
+ def do_second_ocr(ocr1_text, time, img, filtering, ignore_furigana_filter=False):
186
186
  global twopassocr, ocr2, last_ocr2_result
187
187
  try:
188
188
  orig_text, text = run.process_and_write_results(img, None, last_ocr2_result, filtering, None,
189
- engine=ocr2, furigana_filter_sensitivity=furigana_filter_sensitivity)
189
+ engine=ocr2, furigana_filter_sensitivity=furigana_filter_sensitivity if not ignore_furigana_filter else 0)
190
190
  if fuzz.ratio(last_ocr2_result, orig_text) >= 90:
191
191
  logger.info("Seems like the same text from previous ocr2 result, not sending")
192
192
  return
@@ -313,7 +313,7 @@ def run_oneocr(ocr_config: OCRConfig, rectangles):
313
313
 
314
314
  run.init_config(False)
315
315
  try:
316
- run.run(read_from="screencapture",
316
+ run.run(read_from="screencapture" if window else "",
317
317
  read_from_secondary="clipboard" if ss_clipboard else None,
318
318
  write_to="callback",
319
319
  screen_capture_area=screen_area,
@@ -345,14 +345,14 @@ def add_ss_hotkey(ss_hotkey="ctrl+shift+g"):
345
345
  def capture():
346
346
  print("Taking screenshot...")
347
347
  img = cropper.run()
348
- do_second_ocr("", datetime.now(), img, filtering)
348
+ do_second_ocr("", datetime.now(), img, filtering, ignore_furigana_filter=True)
349
349
  def capture_main_monitor():
350
350
  print("Taking screenshot of main monitor...")
351
351
  with mss.mss() as sct:
352
352
  main_monitor = sct.monitors[1] if len(sct.monitors) > 1 else sct.monitors[0]
353
353
  img = sct.grab(main_monitor)
354
354
  img_bytes = mss.tools.to_png(img.rgb, img.size)
355
- do_second_ocr("", datetime.now(), img_bytes, filtering)
355
+ do_second_ocr("", datetime.now(), img_bytes, filtering, ignore_furigana_filter=True)
356
356
  hotkey_reg = None
357
357
  try:
358
358
  hotkey_reg = keyboard.add_hotkey(ss_hotkey, capture)
@@ -389,7 +389,7 @@ def set_force_stable_hotkey():
389
389
  print("Press Ctrl+Shift+F to toggle force stable mode.")
390
390
 
391
391
  if __name__ == "__main__":
392
- global ocr1, ocr2, twopassocr, language, ss_clipboard, ss, ocr_config, furigana_filter_sensitivity, area_select_ocr_hotkey
392
+ global ocr1, ocr2, twopassocr, language, ss_clipboard, ss, ocr_config, furigana_filter_sensitivity, area_select_ocr_hotkey, window
393
393
  import sys
394
394
 
395
395
  import argparse
@@ -428,7 +428,8 @@ if __name__ == "__main__":
428
428
  if ocr_config.window:
429
429
  start_time = time.time()
430
430
  while time.time() - start_time < 30:
431
- if get_window(ocr_config.window):
431
+ window = get_window(ocr_config.window)
432
+ if window or manual:
432
433
  break
433
434
  logger.info(f"Window: {ocr_config.window} Could not be found, retrying in 1 second...")
434
435
  time.sleep(1)
@@ -406,7 +406,8 @@ class TextFiltering:
406
406
  break
407
407
  else:
408
408
  for block in new_blocks:
409
- if lang not in ["ja", "zh"] or self.classify(block)[0] == lang:
409
+ # This only filters out NON JA/ZH from text when lang is JA/ZH
410
+ if lang not in ["ja", "zh"] or self.classify(block)[0] in ['ja', 'zh']:
410
411
  final_blocks.append(block)
411
412
 
412
413
  text = '\n'.join(final_blocks)
@@ -243,6 +243,7 @@ class VAD:
243
243
  @dataclass_json
244
244
  @dataclass
245
245
  class Advanced:
246
+ plaintext_websocket_port: int = -1
246
247
  audio_player_path: str = ''
247
248
  video_player_path: str = ''
248
249
  show_screenshot_buttons: bool = False
@@ -252,6 +253,11 @@ class Advanced:
252
253
  texthooker_communication_websocket_port: int = 55001
253
254
  use_anki_note_creation_time: bool = True
254
255
 
256
+ def __post_init__(self):
257
+ if self.plaintext_websocket_port == -1:
258
+ self.plaintext_websocket_port = self.texthooker_communication_websocket_port + 1
259
+
260
+
255
261
  @dataclass_json
256
262
  @dataclass
257
263
  class Ai:
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import time
2
3
  import zipfile
3
4
  import shutil
4
5
  from os.path import expanduser
@@ -61,12 +62,13 @@ class Downloader:
61
62
  Main function to attempt download and extraction.
62
63
  Tries official source first, then a fallback URL.
63
64
  """
64
- # if checkdir(self.oneocr_dir):
65
- # print("Files already exist in cache.")
66
- # return True
65
+ if checkdir(self.oneocr_dir):
66
+ print("Files already exist in cache.")
67
+ return True
67
68
 
68
69
  try:
69
70
  print("Attempting to download from official source...")
71
+ # raise Exception("")
70
72
  self.downloadofficial()
71
73
  print("Download and extraction from official source successful.")
72
74
  return True
@@ -184,7 +184,7 @@ class VADResult:
184
184
  self.end = end
185
185
  self.model = model
186
186
  self.segments = segments if segments is not None else []
187
- self.output_audio = None
187
+ self.output_audio = output_audio
188
188
 
189
189
  def __repr__(self):
190
190
  return f"VADResult(success={self.success}, start={self.start}, end={self.end}, model={self.model}, output_audio={self.output_audio})"