
    4Aj&                        d Z ddlmZ ddl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  G d de          ZdS )	zFrame sampler tool wrapping FFmpeg.

Extracts representative frames from video for AI analysis, thumbnails,
or quality inspection. Supports interval-based, count-based, and
timestamp-based extraction strategies.
    )annotationsN)Path)Any)BaseToolDeterminismExecutionModeResourceProfile
ToolResultToolStabilityToolTierc                  h   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	d
gddidg dddddddddddddiddddddiddidddddddddddiddd g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dDd2ZdEd;ZdEd<ZdEd=Z dEd>Z!dFd@Z"dGdBZ#dCS )HFrameSamplerframe_samplerz0.1.0analysisffmpegz
cmd:ffmpegz0Install FFmpeg: https://ffmpeg.org/download.html)extract_frames_intervalextract_frames_countextract_frames_timestampsextract_frames_scene_guidedobject
input_pathstrategytypestring)intervalcount
timestampsscene_guided)r   enumnumber皙?z.Seconds between frames (for interval strategy))r   minimumdescriptioninteger   z,Total frames to extract (for count strategy)arrayz8Specific timestamps in seconds (for timestamps strategy))r   itemsr#   )start_secondsend_seconds)r   
propertiesz/Scene boundary list (for scene_guided strategy)   z1Max frames to extract (for scene_guided strategy))r   r"   defaultr#   pngjpg)r   r   r,         )r   r"   maximumr,   )
r   r   interval_secondsr   r   scene_boundaries
max_frames
output_dirformatquality)r   requiredr*   i   r   i  )	cpu_coresram_mbvram_mbdisk_mb)r   r   r2   r   z!writes frame images to output_dirz4Inspect extracted frames for representative coverageinputsdict[str, Any]returnr
   c           	        t          |d                   }|                                st          dd|           S |d         }|                    dd          }|                    dd	          }t          |                    d
|j        dz                      }|                    dd           t          j                    }	 |dk    r|                     |||||          }nt|dk    r|                     |||||          }nT|dk    r| 	                    |||||          }n4|dk    r| 
                    |||||          }nt          dd|           S n5# t          $ r(}	t          dt          |	                    cY d }	~	S d }	~	ww xY wt          j                    |z
  }
t          d|t          |          |t          |          dt          |          gt          |
d	                    S )Nr   FzInput not found: )successerrorr   r6   r.   r7   r0   r5   framesT)parentsexist_okr   r   r   r   zUnknown strategy: )r   frame_countrC   r5   )rA   data	artifactsduration_seconds)r   existsr
   getparentmkdirtime_extract_interval_extract_count_extract_timestamps_extract_scene_guided	Exceptionstrlenround)selfr=   r   r   fmtr7   r5   startrC   eelapseds              K/app/working/workspaces/default/OpenMontage/tools/analysis/frame_sampler.pyexecutezFrameSampler.executef   s3   &.//
  "" 	Ue3Sz3S3STTTT*%jj5))**Y**&**\:3Dx3OPPQQ
555		;:%%//
JWV\]]W$$,,ZS'SYZZ\))11*j#wX^__^++33J
CQXZ`aa!%7VH7V7VWWWW 	; 	; 	;e3q66:::::::::	; )++%$"6{{ !*oo	  :'"7A..

 

 

 
	
s   BE 
F'F
F
Fr   r5   rX   rT   r7   intdict
list[dict]c                ^   |                     dd          }t          |d| z            }dddt          |          dd| g}|d	k    r$|                    d
t          |          g           |                    |           |                     |           |                     |||          S )Nr2   g      @frame_%04d.r   -y-i-vffps=1/r.   	-qscale:v)rK   rT   extendappendrun_command_collect_frames)	rW   r   r5   rX   r7   r=   r   output_patterncmds	            r\   rO   zFrameSampler._extract_interval   s     ::0#66Z*=*=*==>> d#j//&H&&

 %<<JJS\\2333

>"""##JX>>>    c           
        |                     dd          }|                     |          }|dk    rg S ||z  }t          |d| z            }	dddt          |          dd	| d
t          |          g}
|dk    r$|
                    dt          |          g           |
                    |	           |                     |
           |                     |||          S )Nr   
   r   rb   r   rc   rd   re   rf   	-frames:vr.   rg   )rK   _get_durationrT   rh   ri   rj   rk   )rW   r   r5   rX   r7   r=   r   durationr   rl   rm   s              r\   rP   zFrameSampler._extract_count   s     

7B''%%j11q==Ie#Z*=*=*==>> d#j//&H&&U	
 %<<JJS\\2333

>"""##JX>>>rn   c           	        |                     dg           }g }t          |          D ]\  }}	|d|dd| z  }
dddt          |	          dt          |          d	d
g}|dk    r$|                    dt          |          g           |                    t          |
                     |                     |           |
                                r&|                    t          |
          |	|d           |S )Nr   frame_04d.r   rc   z-ssrd   rq   1r.   rg   pathtimestamp_secondsindex)rK   	enumeraterT   rh   ri   rj   rJ   )rW   r   r5   rX   r7   r=   r   rC   itsoutput_filerm   s               r\   rQ   z FrameSampler._extract_timestamps   s    ZZb11
z** 	 	EAr$'='='='='='==K$s2wwc*ooS	C e||

KW6777JJs;''(((S!!!!!## ,,)+     rn   c                   |                     dg           }|                     dd          }|s)|                     ||||dt          |d          i          S g |D ]l}|                     dd          }	|                     dd          }
|
|	z
  }                    |	d	z              |d
k    r                    |	|dz  z              mt	          t          d D                                 t                    |k    r.t                    |z  fdt          |          D             |                     ||||di          S )u"  Extract keyframes guided by scene boundaries.

        Extracts the first frame of each scene plus a midpoint frame for scenes
        longer than 3 seconds. This captures all visual transitions with a
        bounded, predictable number of frames — much better than uniform FPS.
        r3   r4   r+   r      r(   r   r)   r!   g      @r0   c              3  6   K   | ]}t          |d           V  dS )   N)rV   ).0ts     r\   	<genexpr>z5FrameSampler._extract_scene_guided.<locals>.<genexpr>  s*      @@a@@@@@@rn   c                @    g | ]}t          |z                     S  )r^   )r   r~   stepr   s     r\   
<listcomp>z6FrameSampler._extract_scene_guided.<locals>.<listcomp>  s(    OOO*ST]]3OOOrn   r   )	rK   rP   minri   sortedsetrU   rangerQ   )rW   r   r5   rX   r7   r=   r3   r4   scenerY   endrs   r   r   s               @@r\   rR   z"FrameSampler._extract_scene_guided   s    "::&8"==ZZb11
 	&&z:sGZ,,N   
 
% 
	8 
	8EIIoq11E))M1--CU{H eck*** #~~!!%(Q,"6777 C@@Z@@@@@AA
z??Z''z??Z/DOOOOOU:=N=NOOOJ ''
C<2L
 
 	
rn   floatc           
         dddddddt          |          g}|                     |          }t          j        |j                  }t          |                    di                               d	d
                    S )z*Get video duration in seconds via ffprobe.ffprobez-vquietz-show_entrieszformat=durationz-ofjsonr6   rs   r   )rT   rj   r   loadsstdoutr   rK   )rW   r   rm   resultrG   s        r\   rr   zFrameSampler._get_duration  sy     '.6
OO
 !!#&&z&-((TXXh++//
A>>???rn   r   c                    g }d| }t          t          |                    |                              D ]<\  }}|                    t	          |          t          ||z  d          |d           =|S )z1Collect extracted frame files and build metadata.zframe_*.r   ry   )r}   r   globri   rT   rV   )rW   r5   rX   r   rC   patternr~   rz   s           r\   rk   zFrameSampler._collect_frames$  s     "S"" 
(@(@!A!ABB 	 	GAtMMD		%*1x<%;%;     
 rn   N)r=   r>   r?   r
   )r   r   r5   r   rX   rT   r7   r^   r=   r_   r?   r`   )r   r   r?   r   )r5   r   rX   rT   r   r   r?   r`   )$__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_verificationr]   rO   rP   rQ   rR   rr   rk   r   rn   r\   r   r      sB       DG=DJH*I"'N+K >L:  :L  L !:.!8, KKK 
 !O! ! "M    (+Y   $*0();(.'9# #   Q
! 
! "R	  "8,'%ERR )aBSTUUQ)
 )
- -L^ '3SVWWWTTT78L!W X'
 '
 '
 '
R? ? ? ?0? ? ? ?<       D.
 .
 .
 .
`@ @ @ @     rn   r   )__doc__
__future__r   r   rerN   pathlibr   typingr   tools.base_toolr   r   r   r	   r
   r   r   r   r   rn   r\   <module>r      s     # " " " " "  				                              U U U U U8 U U U U Urn   