from pathlib import Path
from PIL import Image
import subprocess,json
P=Path('/tmp/dance_candidate_isolated');P.mkdir(exist_ok=True)
root=Path('/workspace/scratch/5ef4087baa83')
src=root/'recovered_dance/Enterprise Activity/Dance_Of_Full_Assembly_Review_v0.12.mp4'
outfits=root/'generated_images/exec-05f1e750-67ce-4a1d-9d5d-4120bd0ef344.png'
exit_image=root/'generated_images/exec-ed4f9c0b-fb04-41d5-8d01-51eca2dae4fb.png'
luggage=root/'generated_images/exec-1386baff-066e-428a-b56c-937fa21228ac.png'
rush=Path('/tmp/dance_approved/stage2/corrections/bus_passengers_forward_v1.png')
bay=Path('/tmp/danceaudit/frame_25.jpg')
ariel=root/'recovered_dance/Enterprise Activity/Ariel Boys Dance, Royal Watches.png'
rehearsal=Path('/tmp/dance_original/dance_of_production/frames/parking_lot/024_six_panel_rehearsal_current_wardrobe_v1.png')
def run(c):
 print('RUN',c[0],flush=True);subprocess.run(c,check=True)
def clip_board(path,name,cols,rows,ys=None):
 im=Image.open(path).convert('RGB');parts=[]
 for i in range(cols*rows):
  c,r=i%cols,i//cols; w=im.width/cols;h=im.height/rows
  y0=(ys[r][0] if ys else round(r*h)+5);y1=(ys[r][1] if ys else round((r+1)*h)-5)
  piece=im.crop((round(c*w)+6,y0,round((c+1)*w)-6,y1))
  f=P/f'{name}_{i}.png';piece.save(f);parts.append(f)
 inputs=[];filt=[]
 for i,f in enumerate(parts):
  inputs+=['-loop','1','-framerate','24','-t','4','-i',str(f)]
  filt.append(f'[{i}:v]scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2:black,setsar=1,format=yuv420p,setpts=PTS-STARTPTS[v{i}]')
 filt.append(''.join(f'[v{i}]' for i in range(len(parts)))+f'concat=n={len(parts)}:v=1:a=0[v]')
 out=P/f'{name}_24s.mp4'
 run(['ffmpeg','-v','error','-y',*inputs,'-filter_complex',';'.join(filt),'-map','[v]','-an','-c:v','libx264','-preset','veryfast','-crf','20','-pix_fmt','yuv420p','-r','24','-t','24',str(out)])
 return out
aclip=clip_board(ariel,'ariel',3,2,[(5,440),(455,936)])
rclip=clip_board(rehearsal,'rehearsal',2,3)
# Picture-only continuity repairs; original checkpoint audio is copied.
images=[rush,exit_image,luggage,bay,outfits];intervals=[(23,28),(33,38),(38,43),(43,48),(225,230)]
inputargs=[];graph=[]
for i,path in enumerate(images):
 inputargs+=['-i',str(path)]
 graph.append(f'[{i+1}:v]scale=1280:720,setsar=1,format=yuv420p[p{i}]')
last='0:v'
for i,(start,end) in enumerate(intervals):
 nxt=f'o{i}';graph.append(f'[{last}][p{i}]overlay=0:0:enable=\'gte(t,{start})*lt(t,{end})\':repeatlast=1:eof_action=repeat[{nxt}]');last=nxt
patched=P/'internal_base_visual_candidates.mp4'
run(['ffmpeg','-v','error','-y','-i',str(src),*inputargs,'-filter_complex',';'.join(graph),'-map',f'[{last}]','-map','0:a:0','-t','335','-c:v','libx264','-preset','veryfast','-crf','20','-pix_fmt','yuv420p','-c:a','copy',str(patched)])
for name,at in [('ariel_audio',185),('rehearsal_audio',230)]:
 run(['ffmpeg','-v','error','-y','-ss',str(at),'-t','4','-i',str(src),'-vn','-af','afade=t=in:d=0.015,afade=t=out:st=3.985:d=0.015','-c:a','pcm_s16le','-ar','48000','-ac','2',str(P/f'{name}.wav')])
final=P/'Dance_Of_Internal_Continuity_Working_Candidate_v0.13.mp4'
args=['ffmpeg','-v','error','-y','-t','185','-i',str(patched),'-i',str(aclip),'-ss','189','-t','41','-i',str(patched),'-i',str(rclip),'-ss','234','-t','101','-i',str(patched),'-stream_loop','5','-i',str(P/'ariel_audio.wav'),'-stream_loop','5','-i',str(P/'rehearsal_audio.wav')]
filt='[0:v]setpts=PTS-STARTPTS[v0];[1:v]setpts=PTS-STARTPTS[v1];[2:v]setpts=PTS-STARTPTS[v2];[3:v]setpts=PTS-STARTPTS[v3];[4:v]setpts=PTS-STARTPTS[v4];[v0][v1][v2][v3][v4]concat=n=5:v=1:a=0[v];[0:a]atrim=duration=185,asetpts=PTS-STARTPTS[a0];[5:a]atrim=duration=24,asetpts=PTS-STARTPTS[a1];[2:a]atrim=duration=41,asetpts=PTS-STARTPTS[a2];[6:a]atrim=duration=24,asetpts=PTS-STARTPTS[a3];[4:a]atrim=duration=101,asetpts=PTS-STARTPTS[a4];[a0][a1][a2][a3][a4]concat=n=5:v=0:a=1[a]'
run(args+['-filter_complex',filt,'-map','[v]','-map','[a]','-c:v','libx264','-preset','veryfast','-crf','21','-pix_fmt','yuv420p','-r','24','-c:a','aac','-b:a','192k','-ar','48000','-movflags','+faststart',str(final)])
print('OUTPUT',final,final.stat().st_size,flush=True)
