GameSentenceMiner 2.18.4__py3-none-any.whl → 2.18.6__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/obs.py CHANGED
@@ -132,11 +132,14 @@ class OBSConnectionManager(threading.Thread):
132
132
 
133
133
  def check_replay_buffer_enabled(self):
134
134
  if not self.should_check_output:
135
- return True, ""
136
- output = get_replay_buffer_output()
137
- if not output:
138
- return False, "Replay Buffer output not found in OBS. Please enable Replay Buffer In OBS Settings -> Output -> Replay Buffer. I recommend 300 seconds (5 minutes) or higher."
139
- return True, ""
135
+ return 300, ""
136
+ buffer_seconds = get_replay_buffer_max_time_seconds()
137
+ if not buffer_seconds:
138
+ replay_output = get_replay_buffer_output()
139
+ if not replay_output:
140
+ return 0, "Replay Buffer output not found in OBS. Please enable Replay Buffer In OBS Settings -> Output -> Replay Buffer. I recommend 300 seconds (5 minutes) or higher."
141
+ return 300, ""
142
+ return buffer_seconds, ""
140
143
 
141
144
  def _manage_replay_buffer_and_utils(self):
142
145
  errors = []
@@ -150,12 +153,14 @@ class OBSConnectionManager(threading.Thread):
150
153
  errors.append("Automatic Replay Buffer management is disabled in GSM settings.")
151
154
  return errors
152
155
 
153
- replay_buffer_enabled, error_message = self.check_replay_buffer_enabled()
156
+ buffer_seconds, error_message = self.check_replay_buffer_enabled()
154
157
 
155
- if not replay_buffer_enabled:
158
+ if not buffer_seconds:
156
159
  errors.append(error_message)
157
160
  return errors
158
161
 
162
+ self.NO_OUTPUT_SHUTDOWN_SECONDS = min(max(300, buffer_seconds * 1.10), 1800) # At least 5 minutes or 10% more than buffer, but no more than 30 minutes
163
+
159
164
  current_status = get_replay_buffer_status()
160
165
 
161
166
  if self.last_replay_buffer_status is None:
@@ -167,10 +172,10 @@ class OBSConnectionManager(threading.Thread):
167
172
  self.no_output_timestamp = None
168
173
  return errors
169
174
 
170
- img = get_screenshot_PIL(compression=100, img_format='jpg', width=1280, height=720)
171
- has_changed = self.has_image_changed(img) if img else True
175
+ img = get_screenshot_PIL(compression=75, img_format='jpg', width=1280, height=720)
176
+ is_empty = self.is_image_empty(img) if img else True
172
177
 
173
- if not has_changed:
178
+ if not is_empty:
174
179
  self.no_output_timestamp = None
175
180
  if not current_status:
176
181
  start_replay_buffer()
@@ -184,20 +189,18 @@ class OBSConnectionManager(threading.Thread):
184
189
  self.last_replay_buffer_status = False
185
190
  self.no_output_timestamp = None
186
191
 
187
- def has_image_changed(self, img):
188
- if self.previous_image is None:
189
- self.previous_image = np.array(img)
190
- return True
192
+ def is_image_empty(self, img):
191
193
  try:
192
- img1_np = np.array(img) if not isinstance(img, np.ndarray) else img
193
- img2_np = self.previous_image
194
- self.previous_image = img1_np
194
+ extrema = img.getextrema()
195
+ if isinstance(extrema[0], tuple):
196
+ is_empty = all(e[0] == e[1] for e in extrema)
197
+ else:
198
+ is_empty = extrema[0] == extrema[1]
199
+ return is_empty
195
200
  except Exception:
196
- logger.warning("Failed to convert images to numpy arrays for comparison.")
201
+ logger.warning("Failed to check image extrema for emptiness.")
197
202
  return False
198
203
 
199
- return (img1_np.shape == img2_np.shape) and np.array_equal(img1_np, img2_np)
200
-
201
204
  def run(self):
202
205
  time.sleep(5) # Initial delay to allow OBS to start
203
206
  while self.running:
@@ -551,8 +554,6 @@ def get_replay_buffer_max_time_seconds():
551
554
  # For v5, we get settings for the 'replay_buffer' output
552
555
  response = client.get_output_settings(name='Replay Buffer')
553
556
 
554
- print(response.output_settings)
555
-
556
557
  # The response object contains a dict of the actual settings
557
558
  if response:
558
559
  # The key for replay buffer length in seconds is 'max_time_sec'
@@ -566,7 +567,7 @@ def get_replay_buffer_max_time_seconds():
566
567
  logger.warning(f"get_output_settings for replay_buffer failed: {response.status}")
567
568
  return 0
568
569
  except Exception as e:
569
- logger.error(f"Exception while fetching replay buffer settings: {e}")
570
+ # logger.error(f"Exception while fetching replay buffer settings: {e}")
570
571
  return 0
571
572
 
572
573
  def enable_replay_buffer():
@@ -805,7 +806,24 @@ def set_fit_to_screen_for_scene_items(scene_name: str):
805
806
  except obs.error.OBSSDKError as e:
806
807
  logger.error(f"An OBS error occurred: {e}")
807
808
  except Exception as e:
808
- logger.error(f"An unexpected error occurred: {e}")
809
+ logger.error(f"An unexpected error occurred: {e}")
810
+
811
+ def get_current_source_input_settings():
812
+ with connection_pool.get_client() as client:
813
+ client: obs.ReqClient
814
+ current_scene = get_current_scene()
815
+ if not current_scene:
816
+ return None
817
+ scene_items_response = client.get_scene_item_list(name=current_scene)
818
+ items = scene_items_response.scene_items if scene_items_response and scene_items_response.scene_items else []
819
+ if not items:
820
+ return None
821
+ first_item = items[0]
822
+ source_name = first_item.get('sourceName')
823
+ if not source_name:
824
+ return None
825
+ input_settings_response = client.get_input_settings(name=source_name)
826
+ return input_settings_response.input_settings if input_settings_response else None
809
827
 
810
828
 
811
829
  def main():
@@ -867,17 +885,23 @@ if __name__ == '__main__':
867
885
  logging.basicConfig(level=logging.INFO)
868
886
  connect_to_obs_sync()
869
887
 
870
- save_replay_buffer()
888
+ # outputs = get_output_list()
889
+ # print(outputs)
890
+
891
+ # output = get_replay_buffer_output()
892
+ # print(output)
893
+
894
+ # save_replay_buffer()
871
895
  # img = get_screenshot_PIL(source_name='Display Capture 2', compression=100, img_format='jpg', width=2560, height=1440)
872
896
  # img.show()
873
- # output_list = get_output_list()
874
- # print(output_list)
897
+ # source = get_current_source_input_settings()
898
+ # print(source)
875
899
 
876
900
  # response = enable_replay_buffer()
877
901
  # print(response)
878
902
 
879
903
  # response = get_replay_buffer_max_time_seconds()
880
- # # response is dataclass with attributes, print attributes
904
+ # response is dataclass with attributes, print attributes
881
905
  # print(response)
882
906
 
883
907
  # response = enable_replay_buffer()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameSentenceMiner
3
- Version: 2.18.4
3
+ Version: 2.18.6
4
4
  Summary: A tool for mining sentences from games. Update: Overlay?
5
5
  Author-email: Beangate <bpwhelan95@gmail.com>
6
6
  License: MIT License
@@ -2,7 +2,7 @@ GameSentenceMiner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
2
2
  GameSentenceMiner/anki.py,sha256=TgLJIGZq6qPfmXV378BzG_SEnL6KvHK74u4ztTggzbM,31139
3
3
  GameSentenceMiner/gametext.py,sha256=FBL3kgJ71hCg5Nczuo9dAEi_sLGdVIGgvc62bT5KhCc,10691
4
4
  GameSentenceMiner/gsm.py,sha256=0hEpEBDbI9FtiKtHeyrSLKV1nys-mKTKfxLY0Dk7mOQ,36387
5
- GameSentenceMiner/obs.py,sha256=R2Rsq2rMnWIoIb4tArTY7oAFIsyxfp1Nf-XnX_E95io,35858
5
+ GameSentenceMiner/obs.py,sha256=tyiZhVTGxWUsc_L1A5PmmSxHuWILx-B_QnW5TKbcf4A,36873
6
6
  GameSentenceMiner/vad.py,sha256=dhZpbTsVI4scqXZ0M701BenUur0EzYM96tnyGXo8iI0,21021
7
7
  GameSentenceMiner/ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  GameSentenceMiner/ai/ai_prompting.py,sha256=mq9Odv_FpohXagU-OoSZbLWttdrEl1M1NiqnodeUpD8,29126
@@ -124,9 +124,9 @@ GameSentenceMiner/web/templates/components/kanji_grid/thousand_character_classic
124
124
  GameSentenceMiner/web/templates/components/kanji_grid/wanikani_levels.json,sha256=8wjnnaYQqmho6t5tMxrIAc03512A2tYhQh5dfsQnfAM,11372
125
125
  GameSentenceMiner/web/templates/components/kanji_grid/words_hk_frequency_list.json,sha256=wRkqZNPzz6DT9OTPHpXwfqW96Qb96stCQNNgOL-ZdKk,17535
126
126
  GameSentenceMiner/wip/__init___.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
127
- gamesentenceminer-2.18.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
128
- gamesentenceminer-2.18.4.dist-info/METADATA,sha256=SXw7P4busY00L4EwV-Avnt2C29HYJGLoePm5WBEgIo8,7487
129
- gamesentenceminer-2.18.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
130
- gamesentenceminer-2.18.4.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
131
- gamesentenceminer-2.18.4.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
132
- gamesentenceminer-2.18.4.dist-info/RECORD,,
127
+ gamesentenceminer-2.18.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
128
+ gamesentenceminer-2.18.6.dist-info/METADATA,sha256=_wS71dKRpI114wDcNIOsAnBW7oHVbj6XrcYyeshaXxA,7487
129
+ gamesentenceminer-2.18.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
130
+ gamesentenceminer-2.18.6.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
131
+ gamesentenceminer-2.18.6.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
132
+ gamesentenceminer-2.18.6.dist-info/RECORD,,