
    4Aj!                        d Z ddlmZ ddlZddlZddlmZ ddlmZ ddl	m
Z
mZmZmZmZmZmZmZ  G d de
          ZdS )	zScene detection tool wrapping PySceneDetect.

Detects scene boundaries and shot changes in video. Falls back to
FFmpeg-based detection if PySceneDetect is not installed.
    )annotationsN)Path)Any)BaseToolDeterminismExecutionModeResourceProfile
ToolResultToolStability
ToolStatusToolTierc            	         e Zd ZdZdZej        ZdZdZ	e
j        Zej        Zej        ZdgZdZdgZg dZdd	gd
didg dddddddddddddddZ edddd          Zg dZdgZdgZd0d"Zd1d&Zd2d(Zd2d)Z d3d.Z!d/S )4SceneDetectscene_detectz0.1.0analysisffmpegz
cmd:ffmpegz_FFmpeg is required. For better detection install PySceneDetect:
pip install scenedetect[opencv])detect_scenesdetect_content_changesdetect_thresholdobject
input_pathtypestring)content	thresholdadaptiver   )r   enumdefaultnumberz&Detection threshold (method-dependent))r   descriptiong?      ?)r   minimumr   zPath for scene list JSON)r   methodr   min_scene_length_secondsoutput_path)r   required
properties   i   r   d   )	cpu_coresram_mbvram_mbdisk_mb)r   r#   r   z%writes scene list JSON to output_pathz6Spot-check detected scene boundaries against the videoreturnboolc                2    	 dd l }dS # t          $ r Y dS w xY w)Nr   TF)scenedetectImportError)selfr1   s     J/app/working/workspaces/default/OpenMontage/tools/analysis/scene_detect.py_has_pyscenedetectzSceneDetect._has_pyscenedetectO   s:    	4 	 	 	55	s    
inputsdict[str, Any]r
   c           
     ,   t          |d                   }|                                st          dd|           S t          j                    }|                                 r|                     |          }n|                     |          }t          j                    |z
  }t          |                    dt          |	                    d                                        }|j
                            dd           |                    t          j        d	|id
          d           t          dt          |          ||                                 rdndt          |          dt          |          gt!          |d
                    S )Nr   FzInput not found: )successerrorr%   z.scenes.jsonT)parentsexist_okscenesr(   )indentzutf-8)encodingpyscenedetectr   )scene_countr=   r#   output)r9   data	artifactsduration_seconds)r   existsr
   timer5   _detect_pyscenedetect_detect_ffmpeggetstrwith_suffixparentmkdir
write_textjsondumpslenround)r3   r6   r   startr=   elapsedr%   s          r4   executezSceneDetect.executeV   s   &.//
  "" 	Ue3Sz3S3STTTT	""$$ 	1//77FF((00F)++% JJ}c**@*@*P*P&Q&QRR
 
 	   ===tz8V*<QGGGRYZZZ"6{{ -1-D-D-F-FT//Hk**	  ;''("7A..

 

 

 
	
    
list[dict]c                   ddl m}m} ddlm}m}m} t          |d                   }|                    dd          }|                    d          }	|                    dd	          }
 ||          } |            }|dk    r% ||	pd
t          |
|j
        z                      }n`|dk    r% ||	pdt          |
|j
        z                      }n5|dk    r% ||	pdt          |
|j
        z                      }n
 |            }|                    |           |                    |           |                                }g }t          |          D ]\  }\  }}|                    |t!          |                                d          t!          |                                d          t!          |                                |                                z
  d          d           |S )z&Use PySceneDetect for scene detection.r   )
open_videoSceneManager)ContentDetectorThresholdDetectorAdaptiveDetectorr   r#   r   r   r$   r!   g      ;@)r   min_scene_leng      (@r   g      @)adaptive_thresholdr_      indexstart_secondsend_secondsrE   )r1   rZ   r[   scenedetect.detectorsr\   r]   r^   rK   rJ   int
frame_rateadd_detectorr   get_scene_list	enumerateappendrS   get_seconds)r3   r6   rZ   r[   r\   r]   r^   r   r#   r   r_   videoscene_managerdetector
scene_listr=   iscene_start	scene_ends                      r4   rH   z!SceneDetect._detect_pyscenedetectw   sZ   88888888^^^^^^^^^^-..
Hi00JJ{++	

#=sCC
:&&$Y&#+t!-%2B"BCC  HH {""((#+t!-%2B"BCC  HH z!!''#,#3!-%2B"BCC  HH
 '((H""8,,,##E***"1133
+4Z+@+@ 	 	'A'YMM!&{'>'>'@'@!!D!D$Y%:%:%<%<a@@$)))++k.E.E.G.GG% %	      rW   c                x   t          |d                   }|                    dd          }|                    dd          }dddd	d
ddddd|                    t          d          d                              dt          d          dz              d| dg
}	 |                     |d          }t          j        |j                  }n'# t          $ r | 	                    |||          cY S w xY wdg}|                    dg           D ]I}	t          |	                    dd                    }
|
|d         z
  |k    r|                    |
           Jdddd	ddd|g}|                     |          }t          t          j        |j                  d         d                   }|                    |           g }t          t          |          dz
            D ]\}||         }||dz            }|                    |t          |d           t          |d           t          ||z
  d           d!           ]|S )"z)Fallback: use FFmpeg scene change filter.r   r   g333333?r$   r!   ffprobe-vquiet-show_entrieszframe=pts_time-ofrP   -flavfizmovie='\   /:z',select='gt(scene,z)'x   timeout        framespts_timer   format=durationformatduration   ra   rb   )rK   rJ   replacechrrun_commandrP   loadsstdout	Exception_detect_ffmpeg_simplefloatrl   rangerR   rS   )r3   r6   r   r   r_   cmdresultrC   change_pointsframetsdur_cmd
dur_result	total_durr=   rr   rT   ends                     r4   rI   zSceneDetect._detect_ffmpeg   s}   -..
JJ{C00	

#=sCC '-6'rj((R#66>>sCGGCKPPrrenrrr
	T%%c3%77F:fm,,DD 	T 	T 	T--j)]SSSSS	T XXh++ 	) 	)EuyyQ//00BM"%%66$$R((( tW.6:

 %%g..
$*Z%677A*MNN	Y'''s=))A-.. 	 	A!!$EA&CMM!&ua$S!}}$)#+q$9$9	      s   0C !C0/C0rK   r   r   r_   c           
        ddddddd|g}|                      |          }t          t          j        |j                  d         d	                   }d
d|dd| ddddg}	 |                      |d          }|j        }	n# t          $ r d}	Y nw xY wddl}
dg}|
                    d|	          D ]H}t          |	                    d                    }||d         z
  |k    r|
                    |           I|
                    |           g }t          t          |          dz
            D ]\}||         }||dz            }|
                    |t          |d          t          |d          t          ||z
  d          d           ]|S )z/Simplest fallback: split into uniform segments.rv   rw   rx   ry   r   rz   rP   r   r   r   z-iz-vfzselect='gt(scene,z)',showinfor{   null-r   r    r   Nr   zpts_time:(\d+\.?\d*)r   r   ra   rb   )r   r   rP   r   r   stderrr   refinditergrouprl   r   rR   rS   )r3   r   r   r_   r   r   r   r   r   rB   r   r   matchr   r=   rr   rT   r   s                     r4   r   z!SceneDetect._detect_ffmpeg_simple   s   
 tW.6:

 %%g..
$*Z%677A*MNN	 *=y===&#	
	%%c3%77F]FF 	 	 	FFF	 				[[!8&AA 	) 	)Eu{{1~~&&BM"%%66$$R(((Y'''s=))A-.. 	 	A!!$EA&CMM!&ua$S!}}$)#+q$9$9	      s   !B   BBN)r.   r/   )r6   r7   r.   r
   )r6   r7   r.   rX   )r   rK   r   r   r_   r   r.   rX   )"__name__
__module____qualname__nameversionr   COREtier
capabilityproviderr   EXPERIMENTAL	stabilityr   SYNCexecution_moder   DETERMINISTICdeterminismdependenciesinstall_instructionsagent_skillscapabilitiesinput_schemar	   resource_profileidempotency_key_fieldsside_effectsuser_visible_verificationr5   rV   rH   rI   r    rW   r4   r   r      s       DG=DJH*I"'N+K >L	*  :L  L !N!8, <<<$  !G 
 !) )
 %-=WXX!
 
 L. '4TWXXXBBB;<L@!   
 
 
 
B. . . .`1 1 1 1f, , , , , ,rW   r   )__doc__
__future__r   rP   rG   pathlibr   typingr   tools.base_toolr   r   r   r	   r
   r   r   r   r   r   rW   r4   <module>r      s     # " " " " "              	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	l l l l l( l l l l lrW   