#!/usr/bin/env python3
"""Create a silent, normalized video draft. Requires FFmpeg on PATH.
Run: python build_video.py --config shots.example.json
Inputs are preserved; choose a new output name for each revision.
"""
import argparse, json, shutil, subprocess, tempfile
from pathlib import Path

def main():
    parser=argparse.ArgumentParser(description=__doc__)
    parser.add_argument('--config',type=Path,required=True)
    parser.add_argument('--output',type=Path)
    args=parser.parse_args()
    if not shutil.which('ffmpeg'):
        parser.error('Install FFmpeg and make it available on PATH first.')
    config=args.config.resolve();data=json.loads(config.read_text(encoding='utf-8'))
    base=config.parent
    clips=[(base/value).resolve() for value in data['clips']]
    if not clips or any(not p.is_file() for p in clips):
        parser.error('Every input clip must exist; paths are relative to the config file.')
    w,h,fps=int(data['width']),int(data['height']),float(data['fps'])
    if w<=0 or h<=0 or w%2 or h%2 or not 0<fps<=120:
        parser.error('Use positive, even dimensions and an fps between 0 and 120.')
    seconds=float(data.get('clipSeconds',15))
    if seconds<=0:parser.error('clipSeconds must be positive.')
    output=(args.output or base/data['output']).resolve()
    if output in clips or output.exists():
        parser.error('Choose a new output filename; existing files are preserved.')
    output.parent.mkdir(parents=True,exist_ok=True)
    def run(argv):subprocess.run(argv,check=True)
    vf=f'scale={w}:{h}:force_original_aspect_ratio=decrease,pad={w}:{h}:(ow-iw)/2:(oh-ih)/2,fps={fps},setsar=1,format=yuv420p'
    with tempfile.TemporaryDirectory(prefix='video-draft-') as scratch:
        stage=Path(scratch)
        for i,clip in enumerate(clips):
            run(['ffmpeg','-hide_banner','-loglevel','error','-n','-i',str(clip),'-map','0:v:0','-t',str(seconds),'-vf',vf,'-an','-c:v','libx264','-preset','fast','-crf','20',str(stage/f'{i:04d}.mp4')])
        listing=stage/'concat.txt';listing.write_text(''.join(f"file '{i:04d}.mp4'\n" for i in range(len(clips))))
        run(['ffmpeg','-hide_banner','-loglevel','error','-n','-f','concat','-safe','1','-i',str(listing),'-c','copy','-movflags','+faststart',str(output)])
    print(output)
if __name__=='__main__':main()
