#!/usr/bin/env python3 import argparse,json,math,sys from pathlib import Path def main(): p=argparse.ArgumentParser(description=__doc__); p.add_argument("edl"); p.add_argument("--output",default="output.mp4"); a=p.parse_args() try: d=json.loads(Path(a.edl).read_text()) except (OSError,json.JSONDecodeError) as e: print(json.dumps({"ok":False,"error":str(e)})); return 2 if not isinstance(d,dict) or d.get("schema_version")!=1: print(json.dumps({"ok":False,"error":"schema_version must be 1"})); return 2 events=d.get("events",[]) if not isinstance(events,list) or not events: print(json.dumps({"ok":False,"error":"events must be a non-empty array"})); return 2 sources=d.get("sources") if not isinstance(sources,list) or len(sources)!=1 or len(events)!=1: print(json.dumps({"ok":False,"error":"render-edl supports exactly one source and one event"})); return 2 src={x.get("asset_id"):x for x in sources if isinstance(x,dict)}; out=[]; last=-1 for i,e in enumerate(events): if not isinstance(e,dict) or e.get("asset_id") not in src: print(json.dumps({"ok":False,"error":f"invalid source at event {i}"})); return 2 x,y=e.get("in"),e.get("out"); dur=src[e["asset_id"]].get("duration") if not all(isinstance(v,(int,float)) and not isinstance(v,bool) and math.isfinite(v) for v in (x,y)) or x<0 or y<=x or xdur: print(json.dumps({"ok":False,"error":f"invalid interval at event {i}"})); return 2 last=y; out.append({"asset_id":e["asset_id"],"in":x,"out":y,"action":e.get("action","keep")}) argv=["ffmpeg","-n"] for e in out: argv += ["-ss",str(e["in"]),"-to",str(e["out"]),"-i",str(src[e["asset_id"]].get("source",e["asset_id"]))] argv += ["-map","0:v:0?","-map","0:a:0?","-c","copy",a.output] print(json.dumps({"ok":True,"executed":False,"events":out,"argv":argv,"output":a.output},indent=2)); return 0 if __name__=="__main__": sys.exit(main())