33from stashapi .stashapp import StashInterface , StashVersion
44import stashapi .log as log
55import config
6- import cv2
6+ import imageio
77
88tagid_cache = {}
99
@@ -39,7 +39,7 @@ def initialize(connection):
3939 vr_tag_id = stash .find_tag (vr_tag_name )["id" ]
4040
4141 stash_version = get_stash_version ()
42- end_second_support_beyond = StashVersion ("v0.27.2" )
42+ end_second_support_beyond = StashVersion ("v0.27.2-76648 " )
4343 end_seconds_support = stash_version > end_second_support_beyond
4444
4545def get_stash_version ():
@@ -68,7 +68,7 @@ def get_tag_id(tag_name, create=False):
6868
6969def get_ai_tags ():
7070 if len (ai_tag_ids_cache ) == 0 :
71- ai_tags = [item ['id' ] for item in stash .find_tags (f = {"parents" : {"value" :1410 , "modifier" :"INCLUDES" }}, fragment = "id" )]
71+ ai_tags = [item ['id' ] for item in stash .find_tags (f = {"parents" : {"value" :ai_base_tag_id , "modifier" :"INCLUDES" }}, fragment = "id" )]
7272 ai_tag_ids_cache .update (ai_tags )
7373 else :
7474 ai_tags = list (ai_tag_ids_cache )
@@ -203,25 +203,29 @@ def get_scene_markers(video_id):
203203 return stash .get_scene_markers (video_id , fragment = "id primary_tag {id} seconds end_seconds" )
204204
205205def write_scene_marker_to_file (marker , scene_file , output_folder ):
206+
206207 start = marker .get ("seconds" , None )
207208 end = marker .get ("end_seconds" , None )
208209 try :
209- cap = cv2 .VideoCapture (scene_file )
210- if not cap .isOpened ():
211- log .error (f"Failed to open video { scene_file } " )
210+ reader = imageio .get_reader (scene_file , "ffmpeg" )
211+ meta = reader .get_meta_data ()
212+ fps = meta .get ("fps" , 30 ) # default fallback
213+
214+ if start is None :
215+ log .error ("No start time provided." )
212216 return
213-
217+
214218 timestamps = []
215219 if end is None :
216220 timestamps .append (start )
217221 else :
218222 duration = end - start
219- if duration > 4 and duration < 30 :
223+ if 4 < duration < 30 :
220224 timestamps .append (start + 4 )
221- elif duration >= 30 and duration < 60 :
225+ elif 30 <= duration < 60 :
222226 timestamps .append (start + 4 )
223227 timestamps .append (start + 20 )
224- elif duration >= 60 and duration < 120 :
228+ elif 60 <= duration < 120 :
225229 timestamps .append (start + 4 )
226230 timestamps .append (start + 20 )
227231 timestamps .append (start + 50 )
@@ -232,15 +236,17 @@ def write_scene_marker_to_file(marker, scene_file, output_folder):
232236 timestamps .append (start + 100 )
233237
234238 for timestamp in timestamps :
235- cap .set (cv2 .CAP_PROP_POS_MSEC , timestamp * 1000 )
236- ret , frame = cap .read ()
237- if not ret :
238- log .error (f"Failed to read frame at { timestamp } seconds from { scene_file } " )
239+ frame_idx = int (timestamp * fps )
240+ try :
241+ frame = reader .get_data (frame_idx )
242+ output_path = os .path .join (output_folder , f"{ marker .get ('id' )} _{ timestamp } .jpg" )
243+ imageio .imwrite (output_path , frame )
244+ except Exception as e :
245+ log .error (f"Failed to extract frame at { timestamp } s: { e } " )
239246 return
240- output_path = os .path .join (output_folder , f"{ marker .get ('id' )} _{ timestamp } .jpg" )
241- cv2 .imwrite (output_path , frame )
247+
242248 except Exception as e :
243- log .error (f"Failed to write scene marker to file : { e } " )
249+ log .error (f"Failed to process video { scene_file } with imageio-ffmpeg : { e } " )
244250
245251def delete_markers (markers ):
246252 for scene_marker in markers :
0 commit comments