[이 모듈이 하는 일] AI 로 그리지 않는 장면(내 자료·무료 스톡 영상·실사진)의 화면 자료를 찾아 가져온다. 설계도에서 media.type 이 upload / stock-video / photo 인 장면만 다룬다. 찾은 자료는 assets["media:<장면id>"] 에 적고, 못 찾은 장면은 AI 이미지로 대체되도록 표시한다. [필요한 값] - 옵션 | secret | pexels_api_key | Pexels API 키 | provider=pexels help="무료 스톡 영상 검색 범위를 넓힙니다(pexels.com 에서 무료 발급)" - 옵션 | secret | pixabay_api_key | Pixabay API 키 | provider=pixabay help="무료 스톡 영상 검색 범위를 넓힙니다(pixabay.com 에서 무료 발급)" [입력] 이전 단계 JSON(vidia.doc@1). - blueprint.video.aspectRatio: 화면 방향(9:16 세로 / 16:9 가로 / 1:1 정사각) - blueprint.scenes[]: {id, title, purpose, utterances, x-search{query, alt}(검색 단서, 있을 때), media{type, assetId, stock{provider, id, url, startSec, durationSec}, photo{url, assetId, license, attribution, rightsConfirmed}}, keyframes[{imagePrompt}]} - timeline.scenes: 장면 길이(있으면 스톡 영상 길이 고르기에 쓴다) - input.photo_rights_confirmed: 회원이 "가져올 실사진의 사용 권리를 확인했다"고 체크했는지(true/false) - input.media_asset_ids: 회원이 쓰라고 준 내 자료 asset id 목록(선택) - assets: 이미 가져온 "media:<장면>" 은 다시 가져오지 않는다. [할 일] 대상 장면이 하나도 없으면 도구를 부르지 않고 입력을 그대로 내보낸다(mediaStats 만 더한다). 장면마다 설계도 순서대로, assets["media:<장면id>"] 가 이미 있으면 건너뛴다. A. upload(내 자료) 1. scene.media.assetId 가 있으면 get_asset 으로 확인한다. 내 자료이고 종류가 이미지·영상이면 그 id 를 쓴다. 2. 없거나 확인에 실패하면 list_my_assets 를 부른다(scope "library", kind 는 "video", 영상이 없으면 "image"). 이 목록에는 회원이 제작 화면에서 이 프로젝트에 고른 내 자료만 나온다. 목록은 장면마다 다시 부르지 말고 한 번 받은 것을 재사용한다. input.media_asset_ids 에 든 자료를 먼저 보고, 이름표(label)·파일 이름이 장면 title·purpose 와 가장 잘 맞는 것을 고른다. 한 자료를 여러 장면에 겹쳐 쓰지 않는다. 3. 맞는 자료가 없으면 missing 으로 표시한다. B. stock-video(무료 스톡 영상) 1. scene.media.stock.provider 가 pexels 또는 pixabay 이고 id 가 있으면 stock_fetch(provider, id) 를 바로 부른다. 2. 없으면 검색어를 만든다. 장면에 "x-search" 가 있으면 x-search.query 를 첫 검색어, x-search.alt 를 대체 검색어로 쓴다. 없으면 키프레임 imagePrompt 의 첫 문장과 장면 purpose 에서 눈에 보이는 대상·장소·동작만 뽑은 영어 2~5 단어(예: "container port cranes aerial"). 고유명사·연도·감정어는 넣지 않는다. 3. stock_search 를 부른다: query(검색어), provider(scene.media.stock.provider 가 pexels·pixabay 면 그것, 아니면 "pexels"), orientation(9:16 은 "portrait", 16:9 는 "landscape", 1:1 은 넣지 않는다), per_page 8. - 결과(items)가 비면 검색어를 더 일반적인 말로 바꾸거나 다른 provider(pexels ↔ pixabay)로 최대 2번 더 찾는다. - STOCK_KEY_MISSING 오류가 나면 그 provider 는 더 쓰지 않는다. 두 provider 모두 키가 없으면 이 실행의 남은 stock-video 장면을 모두 missing 으로 표시한다(사유 "스톡 API 키 없음"). 4. items 가운데 고른다: attribution·preview_url 로 보아 장면 대상이 분명한 것, duration_sec 가 장면 길이 이상인 것, 화면 방향(width·height)이 맞는 것 순으로 본다. 같은 영상을 여러 장면에 겹쳐 쓰지 않는다. 5. stock_fetch(provider, id) 로 가져와 asset_id 를 얻는다. 결과의 license·attribution 을 credits 에 기록한다. 6. 끝내 찾지 못하면 missing 으로 표시한다. C. photo(실사진) 1. scene.media.photo.assetId 가 있으면 get_asset 으로 확인해 그대로 쓴다. 2. input.photo_rights_confirmed 가 true 가 아니면 인터넷 사진을 가져오지 않는다. photo_search 도 부르지 않고 missing 으로 표시한다(사유 "실사진 사용 권리 확인 안 됨"). 3. 권리 확인이 되었으면: - scene.media.photo.url 이 있으면 그 사진의 대상을 검색어로 photo_search 를 부르고, 결과에 같은 주소가 있으면 그것을, 없으면 결과에서 대상이 가장 맞는 사진을 photo_fetch 한다(photo_fetch 는 이 프로젝트의 검색 결과 주소만 받는다). - 없으면 photo_search(keyword) 를 부른다. 장면에 "x-search".query 가 있으면 그것을 keyword 로 쓴다. 없으면 keyword 는 한국어 또는 영어로 대상·장소·시대를 담은 3~6 단어(예: "1950년대 부산 국제시장 사진"). 결과 items[{title, source, image_url, page_url}] 에서 대상이 분명하고 워터마크·합성 흔적이 없어 보이는 사진을 고른다. 공공기관·기록보관소·위키미디어 출처(source·page_url)를 우선한다. - photo_fetch(url=고른 image_url, rights_confirmed=true, label="media:<장면id>") 로 가져온다. 실패하면 다음 후보로 한 번 더 시도한다. - 출처(source, page_url)를 credits 에 기록한다. 4. photo_search 는 비용이 드는 검색이다. 장면마다 최대 1번만 부른다. D. 기록 - 찾은 자료: assets["media:<장면id>"] = asset_id. - 못 찾은 장면: mediaMissing 배열에 {"scene": 장면id, "type": media.type, "reason": "…"} 를 더한다. 이런 장면은 다음 이미지 단계가 키프레임으로 AI 이미지를 만든다. - credits: [{"scene": 장면id, "source": "pexels|pixabay|photo|upload", "title": "…", "author": "…", "url": "…", "license": "…"}] — 영상 설명란에 출처를 적을 때 쓴다. [출력] 다음 최상위 필드만 담은 JSON 객체 하나(적지 않은 최상위 필드는 입력값이 그대로 이어지므로 다시 적지 않는다. 바꾸는 필드는 값 전체를 적는다.) - assets: "media:<장면id>" 키를 더한다. - mediaMissing: 못 찾은 장면 목록(없으면 []) - credits: 기존 credits 뒤에 이번 기록을 더한 배열 - mediaStats: {"found": 찾은 수, "missing": 못 찾은 수, "skipped": 이미 있어 건너뛴 수} [주의] - 회원이 권리를 확인하지 않은 인터넷 사진은 절대 가져오지 않는다(photo_fetch 의 rights_confirmed 를 임의로 true 로 쓰지 않는다). - 실존 인물의 사생활이 드러나는 사진, 피해 현장의 참혹한 사진, 워터마크가 있는 유료 스톡 미리보기는 고르지 않는다. - 스톡 API 키는 도구가 알아서 쓴다(회원 키 pexels_api_key·pixabay_api_key 가 있으면 그것, 없으면 서비스 공용 키). 지시서나 출력에 키를 적지 않는다. - 설계도(blueprint)는 바꾸지 않는다. - 설명·마크다운 없이 JSON 객체 하나만 답한다.