app
AI Flow: Reverse Engineering
Public Made by Adomby adom
Photos of a PCB to a tagged KiCad copy: parts placed, copper and nets with their evidence, a schematic, a measured confidence score, bench tests and a video of the run.
main
Caleb
Version 0.3.0: new copper reader, dome via filter, every layer read from the photos, net evidence, measured confidence;…
e874d7d
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
import json,subprocess,imageio_ffmpeg,re
F=imageio_ffmpeg.get_ffmpeg_exe()
T=json.load(open('vo/timing.json'));D={d['id']:d['d'] for d in json.load(open('clips/durs.json'))}
INTRO,VOIN,LEAD,OUTRO=5.0,1.8,.1,12.0
# timeline
t=INTRO;starts={};vo={}
for s in T:
i=s['id'];starts[i]=t
vo[i]=VOIN if i=='board' else t+LEAD
t+=D[i]
outro=t;total=t+OUTRO
# concat video
for n,o in(('dark-intro-16x9','intro'),('dark-outro-16x9','outro')):
subprocess.run([F,'-y','-v','error','-i',f'brand/media/{n}.mp4','-an','-c:v','libx264','-preset','medium','-crf','14','-pix_fmt','yuv420p','-r','30',f'clips/_{o}.mp4'],check=True)
open('clips/_list.txt','w').write("file '_intro.mp4'\n"+''.join(f"file '{s['id']}.mp4'\n" for s in T)+"file '_outro.mp4'\n")
subprocess.run([F,'-y','-v','error','-f','concat','-safe','0','-i','clips/_list.txt','-c','copy','clips/_video.mp4'],check=True)
# audio: voice bus normalized as one take, stings as issued
inp=[];fl=[]
for k,s in enumerate(T):
inp+=['-i',f"vo/{s['id']}.wav"];fl.append(f"[{k}:a]aresample=48000,aformat=channel_layouts=mono,adelay={int(vo[s['id']]*1000)}:all=1[v{k}]")
n=len(T);fl.append(''.join(f'[v{k}]' for k in range(n))+f"amix=inputs={n}:normalize=0:dropout_transition=0,loudnorm=I=-16:TP=-1.5:LRA=11,aresample=48000,aformat=channel_layouts=stereo[vo]")
inp+=['-i','brand/media/dark-intro-16x9.mp4','-i','brand/media/dark-outro-16x9.mp4']
fl.append(f"[{n}:a]aresample=48000,volume=0.8[si]");fl.append(f"[{n+1}:a]aresample=48000,volume=0.8,adelay={int(outro*1000)}:all=1[so]")
fl.append("[vo][si][so]amix=inputs=3:normalize=0:dropout_transition=0,alimiter=limit=0.95[a]")
subprocess.run([F,'-y','-v','error',*inp,'-filter_complex',';'.join(fl),'-map','[a]','-t',f'{total:.3f}','-ar','48000','-c:a','pcm_s16le','clips/_audio.wav'],check=True)
# chapters
meta=';FFMETADATA1\ntitle=AI Flow: Reverse Engineering, the full flow on the Driver board\n'
ch=[(s['title'],starts[s['id']]) for s in T]
for k,(ti,st) in enumerate(ch):
en=ch[k+1][1] if k+1<len(ch) else total
meta+=f"[CHAPTER]\nTIMEBASE=1/1000\nSTART={int((0 if k==0 else st)*1000)}\nEND={int(en*1000)}\ntitle={ti}\n"
open('clips/_meta.txt','w').write(meta)
subprocess.run([F,'-y','-v','error','-i','clips/_video.mp4','-i','clips/_audio.wav','-i','clips/_meta.txt','-map','0:v','-map','1:a','-map_metadata','2','-c:v','copy','-c:a','aac','-b:a','192k','-movflags','+faststart','clips/final-master.mp4'],check=True)
# captions, cued to the final audio
def fmt(x,sep):
h=int(x//3600);m=int(x%3600//60);s=x%60;return f"{h:02}:{m:02}:{s:06.3f}".replace('.',sep)
cues=[]
for s in T:
lines=s['written'];off=vo[s['id']]
for i,l in enumerate(lines):
a=off+s['starts'][i];b=off+(s['starts'][i+1] if i+1<len(lines) else s['speech'][1])
# split long sentences on phrase boundaries, time by character share
parts=[];cur=''
for w in l.split(' '):
if len(cur)+len(w)+1>78 and cur:parts.append(cur);cur=w
else:cur=(cur+' '+w).strip()
parts.append(cur);tot=sum(map(len,parts));p=a
for q in parts:
e=p+(b-a)*len(q)/tot;cues.append((p,e-.02,q));p=e
vtt='WEBVTT\n\n'+''.join(f"{fmt(a,'.')} --> {fmt(b,'.')}\n{q}\n\n" for a,b,q in cues)
srt=''.join(f"{k+1}\n{fmt(a,',')} --> {fmt(b,',')}\n{q}\n\n" for k,(a,b,q) in enumerate(cues))
open('clips/final.vtt','w').write(vtt);open('clips/final.srt','w').write(srt)
open('clips/final-chapters.txt','w').write(''.join(f"{int(st//60)}:{int(st%60):02} {ti}\n" for ti,st in [('Intro',0)]+ch))
json.dump(dict(total=total,outro=outro,starts=starts,vo=vo,cues=len(cues)),open('clips/_tl.json','w'),indent=1)
print('total',round(total,2),'outro at',round(outro,2),'cues',len(cues))