"""기존 실행기의 정식 승인·해시·디코드 검사로 요청을 실제 렌더한다.""" import argparse import json from pathlib import Path import subprocess import sys import time sys.path.insert(0,str(Path(__file__).resolve().parent)) from production_requests import REFERENCE_PLAN ROOT=Path(__file__).resolve().parents[3] PROJECT=Path('projects/water-hydrogen-bond-surface-tension') PYTHON='C:/Users/baram/anaconda3/python.exe' BLENDER='C:/Program Files/Blender Foundation/Blender 5.2/blender.exe' COMPOSITOR=Path('C:/git/ShortVideoGenerator/projects/water-hydrogen-bond-surface-tension/renderer/node_modules/@remotion/compositor-win32-x64-msvc') parser=argparse.ArgumentParser() parser.add_argument('--stage',choices=['10-references','11-images','12-motion'],required=True) args=parser.parse_args() BASE=PROJECT/'stages'/args.stage/'r2' artifact_path=BASE/'artifact.json' artifact=json.loads((ROOT/artifact_path).read_text(encoding='utf-8')) records_path=ROOT/BASE/'cli-commands.json' records=json.loads(records_path.read_text(encoding='utf-8')) if records_path.exists() else [] def execute(command): started=time.monotonic() value=subprocess.run(command,cwd=ROOT,capture_output=True,text=True,encoding='utf-8') records.append(dict(command=command,exit_code=value.returncode,elapsed_seconds=round(time.monotonic()-started,3))) if value.returncode: records[-1]['error']=value.stderr[-2500:]+value.stdout[-2500:] records_path.write_text(json.dumps(records,ensure_ascii=False,indent=2)+'\n',encoding='utf-8') assert value.returncode==0,(value.stdout,value.stderr) result=json.loads(value.stdout) if result.get('media'): records[-1]['evidence_path']=(Path(result['media']['path']).parent/'evidence.json').as_posix() records[-1]['source_sha256']=result['scene_file']['sha256'] records_path.write_text(json.dumps(records,ensure_ascii=False,indent=2)+'\n',encoding='utf-8') return result def save(): (ROOT/artifact_path).write_text(json.dumps(artifact,ensure_ascii=False,indent=2)+'\n',encoding='utf-8') common=[PYTHON,'-B','-X','utf8','tools/blender/run.py'] source=(BASE/'generated-source/references.blend').as_posix() if args.stage=='10-references' else artifact['payload']['request']['scene_path'] if args.stage!='12-motion' and not artifact['payload']['result']: first_scene='BondPair' inspected=execute(common+['inspect','--source',source,'--scene',first_scene,'--require-object','PairA','--blender',BLENDER]) artifact['payload']['result']=dict(scene_file=inspected['scene_file'],**({'items':[]} if args.stage=='10-references' else {'frames':[]})) save() if args.stage=='12-motion' and not artifact['payload']['result']: artifact['payload']['result']=dict(clips=[]) save() if args.stage=='10-references': jobs=[dict(id=id,scene=scene,obj=obj,options=['--reference-id',id,'--frame',str(frame)]) for id,kind,entity,scene,obj,frame in REFERENCE_PLAN] key,id_key='items','reference_id' elif args.stage=='11-images': jobs=[dict(id=f['id'],scene=f['scene_name'],obj='StudioAssets',frame=f['frame_index'],options=['--frame-id',f['id'],'--frame',str(f['frame_index'])]) for f in artifact['payload']['request']['frames']] key,id_key='frames','frame_id' else: jobs=[dict(id=c['cut_id'],scene=c['scene_name'],obj='StudioAssets',options=['--cut-id',c['cut_id'],'--start',str(c['start_frame']),'--end',str(c['end_frame'])]) for c in artifact['payload']['request']['clips']] key,id_key='clips','cut_id' for job in jobs: if any(item[id_key]==job['id'] for item in artifact['payload']['result'][key]): continue shared=None if args.stage=='11-images': request={f['id']:f for f in artifact['payload']['request']['frames']} shared=next((item['media'] for item in artifact['payload']['result']['frames'] if (request[item['frame_id']]['scene_name'],request[item['frame_id']]['frame_index'])==(job['scene'],job['frame'])),None) if shared: media=shared else: command=common+['render','--mode','production','--project',(PROJECT/'project.json').as_posix(),'--artifact',artifact_path.as_posix(),'--output-revision','2','--source',source,'--scene',job['scene'],'--require-object',job['obj'],'--blender',BLENDER,'--ffmpeg',str(COMPOSITOR/'ffmpeg.exe'),'--ffprobe',str(COMPOSITOR/'ffprobe.exe')]+job['options'] evidence=execute(command) media=evidence['media'] item={id_key:job['id'],'media':media} if args.stage=='10-references': item['object_name']=job['obj'] artifact['payload']['result'][key].append(item) save() print('실제 결과',args.stage,job['id'],media['path'],flush=True) print('전체 요청 렌더 완료',args.stage,flush=True)