GameSentenceMiner 2.14.5__tar.gz → 2.14.7__tar.gz

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.
Files changed (84) hide show
  1. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/obs.py +1 -1
  2. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ocr/owocr_helper.py +21 -5
  3. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/configuration.py +1 -1
  4. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/get_overlay_coords.py +17 -3
  5. gamesentenceminer-2.14.7/GameSentenceMiner.egg-info/PKG-INFO +169 -0
  6. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner.egg-info/SOURCES.txt +1 -0
  7. gamesentenceminer-2.14.7/PKG-INFO +169 -0
  8. gamesentenceminer-2.14.7/README.md +117 -0
  9. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/pyproject.toml +1 -1
  10. gamesentenceminer-2.14.5/GameSentenceMiner.egg-info/PKG-INFO +0 -51
  11. gamesentenceminer-2.14.5/PKG-INFO +0 -51
  12. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/__init__.py +0 -0
  13. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ai/__init__.py +0 -0
  14. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ai/ai_prompting.py +0 -0
  15. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/anki.py +0 -0
  16. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/__init__.py +0 -0
  17. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/icon.png +0 -0
  18. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/icon128.png +0 -0
  19. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/icon256.png +0 -0
  20. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/icon32.png +0 -0
  21. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/icon512.png +0 -0
  22. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/icon64.png +0 -0
  23. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/assets/pickaxe.png +0 -0
  24. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/config_gui.py +0 -0
  25. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/gametext.py +0 -0
  26. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/gsm.py +0 -0
  27. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/locales/en_us.json +0 -0
  28. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/locales/ja_jp.json +0 -0
  29. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/locales/zh_cn.json +0 -0
  30. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ocr/__init__.py +0 -0
  31. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ocr/gsm_ocr_config.py +0 -0
  32. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ocr/ocrconfig.py +0 -0
  33. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ocr/owocr_area_selector.py +0 -0
  34. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/ocr/ss_picker.py +0 -0
  35. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/__init__.py +0 -0
  36. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/__main__.py +0 -0
  37. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/config.py +0 -0
  38. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/lens_betterproto.py +0 -0
  39. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/ocr.py +0 -0
  40. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/run.py +0 -0
  41. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py +0 -0
  42. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/tools/__init__.py +0 -0
  43. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/tools/audio_offset_selector.py +0 -0
  44. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/tools/ss_selector.py +0 -0
  45. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/tools/window_transparency.py +0 -0
  46. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/__init__.py +0 -0
  47. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/communication/__init__.py +0 -0
  48. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/communication/send.py +0 -0
  49. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/communication/websocket.py +0 -0
  50. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/db.py +0 -0
  51. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/downloader/Untitled_json.py +0 -0
  52. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/downloader/__init__.py +0 -0
  53. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/downloader/download_tools.py +0 -0
  54. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/downloader/oneocr_dl.py +0 -0
  55. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/electron_config.py +0 -0
  56. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/ffmpeg.py +0 -0
  57. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/gsm_utils.py +0 -0
  58. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/model.py +0 -0
  59. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/notification.py +0 -0
  60. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/util/text_log.py +0 -0
  61. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/vad.py +0 -0
  62. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/__init__.py +0 -0
  63. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/service.py +0 -0
  64. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/__init__.py +0 -0
  65. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/apple-touch-icon.png +0 -0
  66. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/favicon-96x96.png +0 -0
  67. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/favicon.ico +0 -0
  68. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/favicon.svg +0 -0
  69. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/site.webmanifest +0 -0
  70. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/style.css +0 -0
  71. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/web-app-manifest-192x192.png +0 -0
  72. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/static/web-app-manifest-512x512.png +0 -0
  73. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/templates/__init__.py +0 -0
  74. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/templates/index.html +0 -0
  75. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/templates/text_replacements.html +0 -0
  76. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/templates/utility.html +0 -0
  77. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/web/texthooking_page.py +0 -0
  78. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner/wip/__init___.py +0 -0
  79. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner.egg-info/dependency_links.txt +0 -0
  80. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner.egg-info/entry_points.txt +0 -0
  81. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner.egg-info/requires.txt +0 -0
  82. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/GameSentenceMiner.egg-info/top_level.txt +0 -0
  83. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/LICENSE +0 -0
  84. {gamesentenceminer-2.14.5 → gamesentenceminer-2.14.7}/setup.cfg +0 -0
@@ -62,7 +62,7 @@ class OBSConnectionManager(threading.Thread):
62
62
  else:
63
63
  is_empty = extrema[0] == extrema[1]
64
64
  if is_empty:
65
- logger.info("Image is totally empty (all pixels the same), sleeping.")
65
+ return
66
66
  else:
67
67
  root = tk.Tk()
68
68
  root.attributes('-topmost', True)
@@ -378,8 +378,16 @@ def text_callback(text, orig_text, time, img=None, came_from_ss=False, filtering
378
378
  previous_orig_text = orig_text_string
379
379
  previous_ocr1_result = previous_text
380
380
  if crop_coords and get_ocr_optimize_second_scan():
381
+ x1, y1, x2, y2 = crop_coords
382
+ x1 = max(0, min(x1, img.width))
383
+ y1 = max(0, min(y1, img.height))
384
+ x2 = max(x1, min(x2, img.width))
385
+ y2 = max(y1, min(y2, img.height))
381
386
  previous_img_local.save(os.path.join(get_temporary_directory(), "pre_oneocrcrop.png"))
382
- previous_img_local = previous_img_local.crop(crop_coords)
387
+ try:
388
+ previous_img_local = previous_img_local.crop((x1, y1, x2, y2))
389
+ except ValueError:
390
+ logger.warning("Error cropping image, using original image")
383
391
  second_ocr_queue.put((previous_text, stable_time, previous_img_local, filtering, pre_crop_image))
384
392
  # threading.Thread(target=do_second_ocr, args=(previous_text, stable_time, previous_img_local, filtering), daemon=True).start()
385
393
  previous_img = None
@@ -468,8 +476,6 @@ def add_ss_hotkey(ss_hotkey="ctrl+shift+g"):
468
476
  img = run.apply_ocr_config_to_image(img, ocr_config, is_secondary=True)
469
477
  do_second_ocr("", datetime.now(), img, TextFiltering(lang=get_ocr_language()), ignore_furigana_filter=True, ignore_previous_result=True)
470
478
 
471
- if not manual:
472
- keyboard.add_hotkey(get_ocr_manual_ocr_hotkey().lower(), ocr_secondary_rectangles)
473
479
  secret_ss_hotkey = "F14"
474
480
  filtering = TextFiltering(lang=get_ocr_language())
475
481
  cropper = ScreenCropper()
@@ -487,19 +493,29 @@ def add_ss_hotkey(ss_hotkey="ctrl+shift+g"):
487
493
  hotkey_reg = None
488
494
  try:
489
495
  hotkey_reg = keyboard.add_hotkey(ss_hotkey, capture)
496
+ if not manual:
497
+ secondary_hotkey_reg = keyboard.add_hotkey(get_ocr_manual_ocr_hotkey().lower(), ocr_secondary_rectangles)
490
498
  if "f13" in ss_hotkey.lower():
491
- keyboard.add_hotkey(secret_ss_hotkey, capture_main_monitor)
499
+ secret_hotkey_reg = keyboard.add_hotkey(secret_ss_hotkey, capture_main_monitor)
492
500
  print(f"Press {ss_hotkey} to take a screenshot.")
493
501
  except Exception as e:
494
502
  if hotkey_reg:
495
503
  keyboard.remove_hotkey(hotkey_reg)
504
+ if secondary_hotkey_reg:
505
+ keyboard.remove_hotkey(secondary_hotkey_reg)
506
+ if secret_hotkey_reg:
507
+ keyboard.remove_hotkey(secret_hotkey_reg)
496
508
  logger.error(f"Error setting up screenshot hotkey with keyboard, Attempting Backup: {e}")
497
509
  logger.debug(e)
498
510
  pynput_hotkey = ss_hotkey.replace("ctrl", "<ctrl>").replace("shift", "<shift>").replace("alt", "<alt>")
511
+ secret_ss_hotkey = secret_hotkey_reg.replace("ctrl", "<ctrl>").replace("shift", "<shift>").replace("alt", "<alt>")
512
+ secondary_ss_hotkey = secondary_hotkey_reg.replace("ctrl", "<ctrl>").replace("shift", "<shift>").replace("alt", "<alt>")
499
513
  try:
500
514
  from pynput import keyboard as pynput_keyboard
501
515
  listener = pynput_keyboard.GlobalHotKeys({
502
- pynput_hotkey: capture
516
+ pynput_hotkey: capture,
517
+ secondary_ss_hotkey: ocr_secondary_rectangles,
518
+ secret_ss_hotkey: capture_main_monitor
503
519
  })
504
520
  listener.start()
505
521
  print(f"Press {pynput_hotkey} to take a screenshot.")
@@ -17,7 +17,6 @@ from dataclasses_json import dataclass_json
17
17
 
18
18
  from importlib import metadata
19
19
 
20
- import requests
21
20
 
22
21
 
23
22
  OFF = 'OFF'
@@ -361,6 +360,7 @@ def get_current_version():
361
360
 
362
361
  def get_latest_version():
363
362
  try:
363
+ import requests
364
364
  response = requests.get(f"https://pypi.org/pypi/{PACKAGE_NAME}/json")
365
365
  latest_version = response.json()["info"]["version"]
366
366
  return latest_version
@@ -134,10 +134,24 @@ class OverlayProcessor:
134
134
  composite_img = Image.new("RGBA", (monitor_width, monitor_height), (0, 0, 0, 0))
135
135
 
136
136
  for crop_coords in crop_coords_list:
137
- cropped_image = full_screenshot.crop(crop_coords)
137
+ # Ensure crop coordinates are within image bounds
138
+ x1, y1, x2, y2 = crop_coords
139
+ x1 = max(0, min(x1, full_screenshot.width))
140
+ y1 = max(0, min(y1, full_screenshot.height))
141
+ x2 = max(x1, min(x2, full_screenshot.width))
142
+ y2 = max(y1, min(y2, full_screenshot.height))
143
+
144
+ # Skip if the coordinates result in an invalid box
145
+ if x1 >= x2 or y1 >= y2:
146
+ continue
147
+ try:
148
+ cropped_image = full_screenshot.crop((x1, y1, x2, y2))
149
+ except ValueError:
150
+ logger.warning("Error cropping image, using original image")
151
+ return full_screenshot
138
152
  # Paste the cropped image onto the canvas at its original location
139
- paste_x = math.floor(crop_coords[0])
140
- paste_y = math.floor(crop_coords[1])
153
+ paste_x = math.floor(x1)
154
+ paste_y = math.floor(y1)
141
155
  composite_img.paste(cropped_image, (paste_x, paste_y))
142
156
 
143
157
  return composite_img
@@ -0,0 +1,169 @@
1
+ Metadata-Version: 2.4
2
+ Name: GameSentenceMiner
3
+ Version: 2.14.7
4
+ Summary: A tool for mining sentences from games. Update: Overlay?
5
+ Author-email: Beangate <bpwhelan95@gmail.com>
6
+ License: MIT License
7
+ Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
8
+ Project-URL: Repository, https://github.com/bpwhelan/GameSentenceMiner
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: requests~=2.32.3
16
+ Requires-Dist: watchdog~=5.0.2
17
+ Requires-Dist: DateTime~=5.5
18
+ Requires-Dist: pyperclip~=1.9.0
19
+ Requires-Dist: soundfile~=0.12.1
20
+ Requires-Dist: toml~=0.10.2
21
+ Requires-Dist: psutil~=6.0.0
22
+ Requires-Dist: rapidfuzz~=3.9.7
23
+ Requires-Dist: plyer~=2.1.0
24
+ Requires-Dist: keyboard~=0.13.5
25
+ Requires-Dist: websockets~=15.0.1
26
+ Requires-Dist: openai-whisper==20240930; sys_platform == "win32"
27
+ Requires-Dist: openai-whisper; sys_platform != "win32"
28
+ Requires-Dist: stable-ts-whisperless
29
+ Requires-Dist: silero-vad~=5.1.2
30
+ Requires-Dist: ttkbootstrap~=1.10.1
31
+ Requires-Dist: dataclasses_json~=0.6.7
32
+ Requires-Dist: win10toast; sys_platform == "win32"
33
+ Requires-Dist: numpy==2.2.6
34
+ Requires-Dist: pystray
35
+ Requires-Dist: pywin32; sys_platform == "win32"
36
+ Requires-Dist: pygetwindow; sys_platform == "win32"
37
+ Requires-Dist: flask
38
+ Requires-Dist: groq
39
+ Requires-Dist: matplotlib
40
+ Requires-Dist: sounddevice
41
+ Requires-Dist: google-genai
42
+ Requires-Dist: owocr
43
+ Requires-Dist: oneocr
44
+ Requires-Dist: openai
45
+ Requires-Dist: scikit-image
46
+ Requires-Dist: opencv-python
47
+ Requires-Dist: betterproto==2.0.0b7
48
+ Requires-Dist: obsws-python~=1.7.2
49
+ Requires-Dist: numpy==2.2.6
50
+ Requires-Dist: regex
51
+ Dynamic: license-file
52
+
53
+ # GSM - An Immersion toolkit for Games.
54
+
55
+ ### English | [日本語](../docs/ja/README.md) | [简体中文](../docs/zh/README.md).
56
+
57
+ An application designed to assist with language learning through games.
58
+
59
+ Short Demo (Watch this first): https://www.youtube.com/watch?v=FeFBL7py6HY
60
+
61
+ Installation: https://youtu.be/h5ksXallc-o
62
+
63
+ Discord: https://discord.gg/yP8Qse6bb8
64
+
65
+ ## Features
66
+
67
+ ### Anki Card Enhancement
68
+
69
+ GSM significantly enhances your Anki cards with rich contextual information:
70
+
71
+ * **Automated Audio Capture**: Automatically records the voice line associated with the text.
72
+
73
+ * **Automatic Trim**: Some simple math around the time that the text event came in, in combination with a "Voice Activation Detection" (VAD) library gives us neatly cut audio.
74
+ * **Manual Trim**: If Automatic voiceline trim is not perfect, it's possible to [open the audio in an external program](https://youtu.be/LKFQFy2Qm64) for trimming.
75
+
76
+ * **Screenshot**: Captures a screenshot of the game at the moment the voice line is spoken.
77
+
78
+ * **Multi-Line**: It's possible to capture multiple lines at once with sentence audio with GSM's very own Texthooker.
79
+
80
+ * **AI Translation**: Integrates AI to provide quick translations of the captured sentence. Custom Prompts also supported. (Optional, Bring your own Key)
81
+
82
+
83
+ #### Game Example (Has Audio)
84
+
85
+ https://github.com/user-attachments/assets/df6bc38e-d74d-423e-b270-8a82eec2394c
86
+
87
+ ---
88
+
89
+ #### VN Example (Has Audio)
90
+
91
+ https://github.com/user-attachments/assets/ee670fda-1a8b-4dec-b9e6-072264155c6e
92
+
93
+ ### OCR
94
+
95
+ GSM runs a fork of [OwOCR](https://github.com/AuroraWright/owocr/) to provide accurate text capture from games that do not have a hook. Here are some improvements GSM makes on stock OwOCR:
96
+
97
+ * **Easier Setup**: With GSM's managed Python install, setup is only a matter of clicking a few buttons.
98
+
99
+ * **Exclusion Zones**: Instead of choosing an area to OCR, you can choose an area to exclude from OCR. Useful if you have a static interface in your game and text appears randomly throughout.
100
+
101
+ * **Two-Pass OCR**: To cut down on API calls and keep output clean, GSM features a "Two-Pass" OCR System. A Local OCR will be constantly running, and when the text on screen stabilizes, it will run a second, more accurate scan that gets sent to clipboard/WebSocket.
102
+
103
+ * **Consistent Audio Timing**: With the two-pass system, we can still get accurate audio recorded and into Anki without the use of crazy offsets or hacks.
104
+
105
+ * **More Language Support**: Stock OwOCR is hard-coded to Japanese, while in GSM you can use a variety of languages.
106
+
107
+
108
+ https://github.com/user-attachments/assets/07240472-831a-40e6-be22-c64b880b0d66
109
+
110
+
111
+
112
+ ### Game Launcher Capabilities (WIP)
113
+
114
+ This is probably the feature I care least about, but if you are lazy like me, you may find this helpful.
115
+
116
+ * **Launch**: GSM can launch your games directly, simplifying the setup process.
117
+
118
+ * **Hook**: Streamlines the process of hooking your games (Agent).
119
+
120
+ This feature simplifies the process of launching games and (potentially) hooking them, making the entire workflow more efficient.
121
+
122
+ <img width="2560" height="1392" alt="GameSentenceMiner_1zuov0R9xK" src="https://github.com/user-attachments/assets/205769bb-3dd2-493b-9383-2d6e2ca05c2d" />
123
+
124
+ ## Basic Requirements
125
+
126
+ * **Anki card creation tool**: [Yomitan](https://github.com/yomidevs/yomitan), [JL](https://github.com/rampaa/JL), etc.
127
+
128
+ * **A method of getting text from the game**: [Agent](https://github.com/0xDC00/agent), [Textractor](https://github.com/Artikash/Textractor), [LunaTranslator](https://github.com/HIllya51/LunaTranslator), GSM's OCR, etc.
129
+
130
+ * **A game :)**
131
+
132
+ ## Documentation
133
+
134
+ For help with installation, setup, and other information, please visit the project's [Wiki](https://github.com/bpwhelan/GameSentenceMiner/wiki).
135
+
136
+ ## FAQ
137
+
138
+ ### How Does It Work?
139
+
140
+ This is a common question, and understanding this process will help clarify any issues you might encounter while using GSM.
141
+
142
+ 1. The beginning of the voice line is marked by a text event. This usually comes from Textractor, Agent, or another texthooker. GSM can listen for a clipboard copy and/or a WebSocket server (configurable in GSM).
143
+
144
+ 2. The end of the voice line is detected using a Voice Activity Detection (VAD) library running locally. ([Example](https://github.com/snakers4/silero-vad))
145
+
146
+ In essence, GSM relies on accurately timed text events to capture the corresponding audio.
147
+
148
+ GSM provides settings to accommodate less-than-ideal hooks. However, if you experience significant audio inconsistencies, they likely stem from a poorly timed hook, loud background music, or other external factors, rather than GSM itself. The core audio trimming logic has been stable and effective for many users across various games.
149
+
150
+ ## Contact
151
+
152
+ If you encounter issues, please ask for help in my [Discord](https://discord.gg/yP8Qse6bb8) or create an issue here.
153
+
154
+ ## Acknowledgements
155
+
156
+ * [OwOCR](https://github.com/AuroraWright/owocr) for their outstanding OCR implementation, which I've integrated into GSM.
157
+
158
+ * [chaiNNer](https://github.com/chaiNNer-org/chaiNNer) for the idea of installing Python within an Electron app.
159
+
160
+ * [OBS](https://obsproject.com/) and [FFMPEG](https://ffmpeg.org/), without which GSM would not be possible.
161
+
162
+ * [Renji's Texthooker](https://github.com/Renji-XD/texthooker-ui)
163
+
164
+ * https://github.com/Saplling/transparent-texthooker-overlay
165
+
166
+ ## Donations
167
+
168
+ If you've found this or any of my other projects helpful, please consider supporting my work through [GitHub Sponsors](https://github.com/sponsors/bpwhelan), or [Ko-fi](https://ko-fi.com/beangate).
169
+
@@ -1,4 +1,5 @@
1
1
  LICENSE
2
+ README.md
2
3
  pyproject.toml
3
4
  GameSentenceMiner/__init__.py
4
5
  GameSentenceMiner/anki.py
@@ -0,0 +1,169 @@
1
+ Metadata-Version: 2.4
2
+ Name: GameSentenceMiner
3
+ Version: 2.14.7
4
+ Summary: A tool for mining sentences from games. Update: Overlay?
5
+ Author-email: Beangate <bpwhelan95@gmail.com>
6
+ License: MIT License
7
+ Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
8
+ Project-URL: Repository, https://github.com/bpwhelan/GameSentenceMiner
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.10
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: requests~=2.32.3
16
+ Requires-Dist: watchdog~=5.0.2
17
+ Requires-Dist: DateTime~=5.5
18
+ Requires-Dist: pyperclip~=1.9.0
19
+ Requires-Dist: soundfile~=0.12.1
20
+ Requires-Dist: toml~=0.10.2
21
+ Requires-Dist: psutil~=6.0.0
22
+ Requires-Dist: rapidfuzz~=3.9.7
23
+ Requires-Dist: plyer~=2.1.0
24
+ Requires-Dist: keyboard~=0.13.5
25
+ Requires-Dist: websockets~=15.0.1
26
+ Requires-Dist: openai-whisper==20240930; sys_platform == "win32"
27
+ Requires-Dist: openai-whisper; sys_platform != "win32"
28
+ Requires-Dist: stable-ts-whisperless
29
+ Requires-Dist: silero-vad~=5.1.2
30
+ Requires-Dist: ttkbootstrap~=1.10.1
31
+ Requires-Dist: dataclasses_json~=0.6.7
32
+ Requires-Dist: win10toast; sys_platform == "win32"
33
+ Requires-Dist: numpy==2.2.6
34
+ Requires-Dist: pystray
35
+ Requires-Dist: pywin32; sys_platform == "win32"
36
+ Requires-Dist: pygetwindow; sys_platform == "win32"
37
+ Requires-Dist: flask
38
+ Requires-Dist: groq
39
+ Requires-Dist: matplotlib
40
+ Requires-Dist: sounddevice
41
+ Requires-Dist: google-genai
42
+ Requires-Dist: owocr
43
+ Requires-Dist: oneocr
44
+ Requires-Dist: openai
45
+ Requires-Dist: scikit-image
46
+ Requires-Dist: opencv-python
47
+ Requires-Dist: betterproto==2.0.0b7
48
+ Requires-Dist: obsws-python~=1.7.2
49
+ Requires-Dist: numpy==2.2.6
50
+ Requires-Dist: regex
51
+ Dynamic: license-file
52
+
53
+ # GSM - An Immersion toolkit for Games.
54
+
55
+ ### English | [日本語](../docs/ja/README.md) | [简体中文](../docs/zh/README.md).
56
+
57
+ An application designed to assist with language learning through games.
58
+
59
+ Short Demo (Watch this first): https://www.youtube.com/watch?v=FeFBL7py6HY
60
+
61
+ Installation: https://youtu.be/h5ksXallc-o
62
+
63
+ Discord: https://discord.gg/yP8Qse6bb8
64
+
65
+ ## Features
66
+
67
+ ### Anki Card Enhancement
68
+
69
+ GSM significantly enhances your Anki cards with rich contextual information:
70
+
71
+ * **Automated Audio Capture**: Automatically records the voice line associated with the text.
72
+
73
+ * **Automatic Trim**: Some simple math around the time that the text event came in, in combination with a "Voice Activation Detection" (VAD) library gives us neatly cut audio.
74
+ * **Manual Trim**: If Automatic voiceline trim is not perfect, it's possible to [open the audio in an external program](https://youtu.be/LKFQFy2Qm64) for trimming.
75
+
76
+ * **Screenshot**: Captures a screenshot of the game at the moment the voice line is spoken.
77
+
78
+ * **Multi-Line**: It's possible to capture multiple lines at once with sentence audio with GSM's very own Texthooker.
79
+
80
+ * **AI Translation**: Integrates AI to provide quick translations of the captured sentence. Custom Prompts also supported. (Optional, Bring your own Key)
81
+
82
+
83
+ #### Game Example (Has Audio)
84
+
85
+ https://github.com/user-attachments/assets/df6bc38e-d74d-423e-b270-8a82eec2394c
86
+
87
+ ---
88
+
89
+ #### VN Example (Has Audio)
90
+
91
+ https://github.com/user-attachments/assets/ee670fda-1a8b-4dec-b9e6-072264155c6e
92
+
93
+ ### OCR
94
+
95
+ GSM runs a fork of [OwOCR](https://github.com/AuroraWright/owocr/) to provide accurate text capture from games that do not have a hook. Here are some improvements GSM makes on stock OwOCR:
96
+
97
+ * **Easier Setup**: With GSM's managed Python install, setup is only a matter of clicking a few buttons.
98
+
99
+ * **Exclusion Zones**: Instead of choosing an area to OCR, you can choose an area to exclude from OCR. Useful if you have a static interface in your game and text appears randomly throughout.
100
+
101
+ * **Two-Pass OCR**: To cut down on API calls and keep output clean, GSM features a "Two-Pass" OCR System. A Local OCR will be constantly running, and when the text on screen stabilizes, it will run a second, more accurate scan that gets sent to clipboard/WebSocket.
102
+
103
+ * **Consistent Audio Timing**: With the two-pass system, we can still get accurate audio recorded and into Anki without the use of crazy offsets or hacks.
104
+
105
+ * **More Language Support**: Stock OwOCR is hard-coded to Japanese, while in GSM you can use a variety of languages.
106
+
107
+
108
+ https://github.com/user-attachments/assets/07240472-831a-40e6-be22-c64b880b0d66
109
+
110
+
111
+
112
+ ### Game Launcher Capabilities (WIP)
113
+
114
+ This is probably the feature I care least about, but if you are lazy like me, you may find this helpful.
115
+
116
+ * **Launch**: GSM can launch your games directly, simplifying the setup process.
117
+
118
+ * **Hook**: Streamlines the process of hooking your games (Agent).
119
+
120
+ This feature simplifies the process of launching games and (potentially) hooking them, making the entire workflow more efficient.
121
+
122
+ <img width="2560" height="1392" alt="GameSentenceMiner_1zuov0R9xK" src="https://github.com/user-attachments/assets/205769bb-3dd2-493b-9383-2d6e2ca05c2d" />
123
+
124
+ ## Basic Requirements
125
+
126
+ * **Anki card creation tool**: [Yomitan](https://github.com/yomidevs/yomitan), [JL](https://github.com/rampaa/JL), etc.
127
+
128
+ * **A method of getting text from the game**: [Agent](https://github.com/0xDC00/agent), [Textractor](https://github.com/Artikash/Textractor), [LunaTranslator](https://github.com/HIllya51/LunaTranslator), GSM's OCR, etc.
129
+
130
+ * **A game :)**
131
+
132
+ ## Documentation
133
+
134
+ For help with installation, setup, and other information, please visit the project's [Wiki](https://github.com/bpwhelan/GameSentenceMiner/wiki).
135
+
136
+ ## FAQ
137
+
138
+ ### How Does It Work?
139
+
140
+ This is a common question, and understanding this process will help clarify any issues you might encounter while using GSM.
141
+
142
+ 1. The beginning of the voice line is marked by a text event. This usually comes from Textractor, Agent, or another texthooker. GSM can listen for a clipboard copy and/or a WebSocket server (configurable in GSM).
143
+
144
+ 2. The end of the voice line is detected using a Voice Activity Detection (VAD) library running locally. ([Example](https://github.com/snakers4/silero-vad))
145
+
146
+ In essence, GSM relies on accurately timed text events to capture the corresponding audio.
147
+
148
+ GSM provides settings to accommodate less-than-ideal hooks. However, if you experience significant audio inconsistencies, they likely stem from a poorly timed hook, loud background music, or other external factors, rather than GSM itself. The core audio trimming logic has been stable and effective for many users across various games.
149
+
150
+ ## Contact
151
+
152
+ If you encounter issues, please ask for help in my [Discord](https://discord.gg/yP8Qse6bb8) or create an issue here.
153
+
154
+ ## Acknowledgements
155
+
156
+ * [OwOCR](https://github.com/AuroraWright/owocr) for their outstanding OCR implementation, which I've integrated into GSM.
157
+
158
+ * [chaiNNer](https://github.com/chaiNNer-org/chaiNNer) for the idea of installing Python within an Electron app.
159
+
160
+ * [OBS](https://obsproject.com/) and [FFMPEG](https://ffmpeg.org/), without which GSM would not be possible.
161
+
162
+ * [Renji's Texthooker](https://github.com/Renji-XD/texthooker-ui)
163
+
164
+ * https://github.com/Saplling/transparent-texthooker-overlay
165
+
166
+ ## Donations
167
+
168
+ If you've found this or any of my other projects helpful, please consider supporting my work through [GitHub Sponsors](https://github.com/sponsors/bpwhelan), or [Ko-fi](https://ko-fi.com/beangate).
169
+
@@ -0,0 +1,117 @@
1
+ # GSM - An Immersion toolkit for Games.
2
+
3
+ ### English | [日本語](../docs/ja/README.md) | [简体中文](../docs/zh/README.md).
4
+
5
+ An application designed to assist with language learning through games.
6
+
7
+ Short Demo (Watch this first): https://www.youtube.com/watch?v=FeFBL7py6HY
8
+
9
+ Installation: https://youtu.be/h5ksXallc-o
10
+
11
+ Discord: https://discord.gg/yP8Qse6bb8
12
+
13
+ ## Features
14
+
15
+ ### Anki Card Enhancement
16
+
17
+ GSM significantly enhances your Anki cards with rich contextual information:
18
+
19
+ * **Automated Audio Capture**: Automatically records the voice line associated with the text.
20
+
21
+ * **Automatic Trim**: Some simple math around the time that the text event came in, in combination with a "Voice Activation Detection" (VAD) library gives us neatly cut audio.
22
+ * **Manual Trim**: If Automatic voiceline trim is not perfect, it's possible to [open the audio in an external program](https://youtu.be/LKFQFy2Qm64) for trimming.
23
+
24
+ * **Screenshot**: Captures a screenshot of the game at the moment the voice line is spoken.
25
+
26
+ * **Multi-Line**: It's possible to capture multiple lines at once with sentence audio with GSM's very own Texthooker.
27
+
28
+ * **AI Translation**: Integrates AI to provide quick translations of the captured sentence. Custom Prompts also supported. (Optional, Bring your own Key)
29
+
30
+
31
+ #### Game Example (Has Audio)
32
+
33
+ https://github.com/user-attachments/assets/df6bc38e-d74d-423e-b270-8a82eec2394c
34
+
35
+ ---
36
+
37
+ #### VN Example (Has Audio)
38
+
39
+ https://github.com/user-attachments/assets/ee670fda-1a8b-4dec-b9e6-072264155c6e
40
+
41
+ ### OCR
42
+
43
+ GSM runs a fork of [OwOCR](https://github.com/AuroraWright/owocr/) to provide accurate text capture from games that do not have a hook. Here are some improvements GSM makes on stock OwOCR:
44
+
45
+ * **Easier Setup**: With GSM's managed Python install, setup is only a matter of clicking a few buttons.
46
+
47
+ * **Exclusion Zones**: Instead of choosing an area to OCR, you can choose an area to exclude from OCR. Useful if you have a static interface in your game and text appears randomly throughout.
48
+
49
+ * **Two-Pass OCR**: To cut down on API calls and keep output clean, GSM features a "Two-Pass" OCR System. A Local OCR will be constantly running, and when the text on screen stabilizes, it will run a second, more accurate scan that gets sent to clipboard/WebSocket.
50
+
51
+ * **Consistent Audio Timing**: With the two-pass system, we can still get accurate audio recorded and into Anki without the use of crazy offsets or hacks.
52
+
53
+ * **More Language Support**: Stock OwOCR is hard-coded to Japanese, while in GSM you can use a variety of languages.
54
+
55
+
56
+ https://github.com/user-attachments/assets/07240472-831a-40e6-be22-c64b880b0d66
57
+
58
+
59
+
60
+ ### Game Launcher Capabilities (WIP)
61
+
62
+ This is probably the feature I care least about, but if you are lazy like me, you may find this helpful.
63
+
64
+ * **Launch**: GSM can launch your games directly, simplifying the setup process.
65
+
66
+ * **Hook**: Streamlines the process of hooking your games (Agent).
67
+
68
+ This feature simplifies the process of launching games and (potentially) hooking them, making the entire workflow more efficient.
69
+
70
+ <img width="2560" height="1392" alt="GameSentenceMiner_1zuov0R9xK" src="https://github.com/user-attachments/assets/205769bb-3dd2-493b-9383-2d6e2ca05c2d" />
71
+
72
+ ## Basic Requirements
73
+
74
+ * **Anki card creation tool**: [Yomitan](https://github.com/yomidevs/yomitan), [JL](https://github.com/rampaa/JL), etc.
75
+
76
+ * **A method of getting text from the game**: [Agent](https://github.com/0xDC00/agent), [Textractor](https://github.com/Artikash/Textractor), [LunaTranslator](https://github.com/HIllya51/LunaTranslator), GSM's OCR, etc.
77
+
78
+ * **A game :)**
79
+
80
+ ## Documentation
81
+
82
+ For help with installation, setup, and other information, please visit the project's [Wiki](https://github.com/bpwhelan/GameSentenceMiner/wiki).
83
+
84
+ ## FAQ
85
+
86
+ ### How Does It Work?
87
+
88
+ This is a common question, and understanding this process will help clarify any issues you might encounter while using GSM.
89
+
90
+ 1. The beginning of the voice line is marked by a text event. This usually comes from Textractor, Agent, or another texthooker. GSM can listen for a clipboard copy and/or a WebSocket server (configurable in GSM).
91
+
92
+ 2. The end of the voice line is detected using a Voice Activity Detection (VAD) library running locally. ([Example](https://github.com/snakers4/silero-vad))
93
+
94
+ In essence, GSM relies on accurately timed text events to capture the corresponding audio.
95
+
96
+ GSM provides settings to accommodate less-than-ideal hooks. However, if you experience significant audio inconsistencies, they likely stem from a poorly timed hook, loud background music, or other external factors, rather than GSM itself. The core audio trimming logic has been stable and effective for many users across various games.
97
+
98
+ ## Contact
99
+
100
+ If you encounter issues, please ask for help in my [Discord](https://discord.gg/yP8Qse6bb8) or create an issue here.
101
+
102
+ ## Acknowledgements
103
+
104
+ * [OwOCR](https://github.com/AuroraWright/owocr) for their outstanding OCR implementation, which I've integrated into GSM.
105
+
106
+ * [chaiNNer](https://github.com/chaiNNer-org/chaiNNer) for the idea of installing Python within an Electron app.
107
+
108
+ * [OBS](https://obsproject.com/) and [FFMPEG](https://ffmpeg.org/), without which GSM would not be possible.
109
+
110
+ * [Renji's Texthooker](https://github.com/Renji-XD/texthooker-ui)
111
+
112
+ * https://github.com/Saplling/transparent-texthooker-overlay
113
+
114
+ ## Donations
115
+
116
+ If you've found this or any of my other projects helpful, please consider supporting my work through [GitHub Sponsors](https://github.com/sponsors/bpwhelan), or [Ko-fi](https://ko-fi.com/beangate).
117
+
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "GameSentenceMiner"
10
- version = "2.14.5"
10
+ version = "2.14.7"
11
11
  description = "A tool for mining sentences from games. Update: Overlay?"
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.10"
@@ -1,51 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: GameSentenceMiner
3
- Version: 2.14.5
4
- Summary: A tool for mining sentences from games. Update: Overlay?
5
- Author-email: Beangate <bpwhelan95@gmail.com>
6
- License: MIT License
7
- Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
8
- Project-URL: Repository, https://github.com/bpwhelan/GameSentenceMiner
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
- Requires-Python: >=3.10
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
- Requires-Dist: requests~=2.32.3
16
- Requires-Dist: watchdog~=5.0.2
17
- Requires-Dist: DateTime~=5.5
18
- Requires-Dist: pyperclip~=1.9.0
19
- Requires-Dist: soundfile~=0.12.1
20
- Requires-Dist: toml~=0.10.2
21
- Requires-Dist: psutil~=6.0.0
22
- Requires-Dist: rapidfuzz~=3.9.7
23
- Requires-Dist: plyer~=2.1.0
24
- Requires-Dist: keyboard~=0.13.5
25
- Requires-Dist: websockets~=15.0.1
26
- Requires-Dist: openai-whisper==20240930; sys_platform == "win32"
27
- Requires-Dist: openai-whisper; sys_platform != "win32"
28
- Requires-Dist: stable-ts-whisperless
29
- Requires-Dist: silero-vad~=5.1.2
30
- Requires-Dist: ttkbootstrap~=1.10.1
31
- Requires-Dist: dataclasses_json~=0.6.7
32
- Requires-Dist: win10toast; sys_platform == "win32"
33
- Requires-Dist: numpy==2.2.6
34
- Requires-Dist: pystray
35
- Requires-Dist: pywin32; sys_platform == "win32"
36
- Requires-Dist: pygetwindow; sys_platform == "win32"
37
- Requires-Dist: flask
38
- Requires-Dist: groq
39
- Requires-Dist: matplotlib
40
- Requires-Dist: sounddevice
41
- Requires-Dist: google-genai
42
- Requires-Dist: owocr
43
- Requires-Dist: oneocr
44
- Requires-Dist: openai
45
- Requires-Dist: scikit-image
46
- Requires-Dist: opencv-python
47
- Requires-Dist: betterproto==2.0.0b7
48
- Requires-Dist: obsws-python~=1.7.2
49
- Requires-Dist: numpy==2.2.6
50
- Requires-Dist: regex
51
- Dynamic: license-file
@@ -1,51 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: GameSentenceMiner
3
- Version: 2.14.5
4
- Summary: A tool for mining sentences from games. Update: Overlay?
5
- Author-email: Beangate <bpwhelan95@gmail.com>
6
- License: MIT License
7
- Project-URL: Homepage, https://github.com/bpwhelan/GameSentenceMiner
8
- Project-URL: Repository, https://github.com/bpwhelan/GameSentenceMiner
9
- Classifier: Programming Language :: Python :: 3
10
- Classifier: License :: OSI Approved :: MIT License
11
- Classifier: Operating System :: OS Independent
12
- Requires-Python: >=3.10
13
- Description-Content-Type: text/markdown
14
- License-File: LICENSE
15
- Requires-Dist: requests~=2.32.3
16
- Requires-Dist: watchdog~=5.0.2
17
- Requires-Dist: DateTime~=5.5
18
- Requires-Dist: pyperclip~=1.9.0
19
- Requires-Dist: soundfile~=0.12.1
20
- Requires-Dist: toml~=0.10.2
21
- Requires-Dist: psutil~=6.0.0
22
- Requires-Dist: rapidfuzz~=3.9.7
23
- Requires-Dist: plyer~=2.1.0
24
- Requires-Dist: keyboard~=0.13.5
25
- Requires-Dist: websockets~=15.0.1
26
- Requires-Dist: openai-whisper==20240930; sys_platform == "win32"
27
- Requires-Dist: openai-whisper; sys_platform != "win32"
28
- Requires-Dist: stable-ts-whisperless
29
- Requires-Dist: silero-vad~=5.1.2
30
- Requires-Dist: ttkbootstrap~=1.10.1
31
- Requires-Dist: dataclasses_json~=0.6.7
32
- Requires-Dist: win10toast; sys_platform == "win32"
33
- Requires-Dist: numpy==2.2.6
34
- Requires-Dist: pystray
35
- Requires-Dist: pywin32; sys_platform == "win32"
36
- Requires-Dist: pygetwindow; sys_platform == "win32"
37
- Requires-Dist: flask
38
- Requires-Dist: groq
39
- Requires-Dist: matplotlib
40
- Requires-Dist: sounddevice
41
- Requires-Dist: google-genai
42
- Requires-Dist: owocr
43
- Requires-Dist: oneocr
44
- Requires-Dist: openai
45
- Requires-Dist: scikit-image
46
- Requires-Dist: opencv-python
47
- Requires-Dist: betterproto==2.0.0b7
48
- Requires-Dist: obsws-python~=1.7.2
49
- Requires-Dist: numpy==2.2.6
50
- Requires-Dist: regex
51
- Dynamic: license-file