도입
4편에서는 음성과 자막을, 3편에서는 씬 구조를 만들었습니다.
한국어 AI 목소리 무료로 쓰기: edge-tts 연동하기 (Shorts 자동화 4편)
도입3편까지는 captionWords(자막이 무슨 단어이고 몇 프레임에 나오는지)를 사람이 직접 손으로 적었습니다. 대본만 바꾸면 영상이 바뀐다: Remotion 데이터 주입 구조 만들기 (Shorts 자동화 3편)도입2
blog.jdevy.com
이번 편에서는 마지막 조각인 이미지를 자동으로 만들고, 지금까지 만든 스크립트들을 이어붙여서 처음으로 "대본 텍스트만 넣으면 완성된 mp4가 나오는" 흐름을 완주해봅니다.

GPT Image 2로 이미지 자동 생성하기
generate_images.py는 별도 세션에서 이미 작성해둔 스크립트로, OpenAI GPT Image 2 API에 프롬프트를 보내 이미지를 받아옵니다. 이번에는 출력 경로만 Remotion의 public 폴더로 바꿔줍니다.
# 변경 전
OUTPUT_DIR = Path("output_images")
# 변경 후
OUTPUT_DIR = Path("public")
이렇게 하면 이미지가 생성되자마자 Remotion이 staticFile()로 바로 불러올 수 있는 위치에 저장됩니다.
주의: GPT Image 2 API는 호출할 때마다 비용이 발생합니다(장당 몇 센트 수준, 해상도·품질에 따라 다름). 테스트할 때는 이미지 개수를 최소로 유지하는 걸 권장합니다.
build_scene.py — 음성·자막·이미지를 하나로 조립하기
4편의 tts_captions.py는 {이름}.mp3와 {이름}-captions.json을 만들고, generate_images.py는 {이름}.png를 만듭니다. 이 세 가지를 하나의 scene-props.json으로 합쳐주는 스크립트입니다.
#!/usr/bin/env python3
"""
정데비의 작업실 - 대본 → scene-props.json 조립 스크립트
tts_captions.py와 generate_images.py의 결과물을 하나의 Remotion props로 합칩니다.
"""
import json
import sys
from pathlib import Path
def build(scene_names: list[str], output_path: str = "scene-props.json"):
scenes = []
for name in scene_names:
captions_file = Path(f"{name}-captions.json")
if not captions_file.exists():
print(f"경고: {captions_file} 없음 — tts_captions.py를 먼저 실행하세요")
continue
data = json.loads(captions_file.read_text(encoding="utf-8"))
image_file = f"{name}.png"
if not Path("public", image_file).exists():
print(f"경고: public/{image_file} 없음 — generate_images.py를 먼저 실행하세요")
scenes.append({
"audioPath": f"{name}.mp3",
"imagePath": image_file,
"durationInFrames": data["durationInFrames"],
"captionWords": data["captionWords"],
})
Path(output_path).write_text(
json.dumps({"scenes": scenes}, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(f"{output_path} 생성 완료 — 씬 {len(scenes)}개")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("사용법: python build_scene.py scene1 scene2 scene3 ...")
sys.exit(1)
build(sys.argv[1:])
각 씬 이름을 넣어주면, 미리 만들어둔 캡션 파일을 읽어서 이미지·오디오 경로와 함께 scene-props.json 하나로 묶어줍니다. 파일이 빠져 있으면 경고만 찍고 넘어가니, 실행 후 경고 메시지를 꼭 확인하세요.
이슈 — pip 설치 시 externally-managed-environment 에러
pip3 install openai
# → error: externally-managed-environment
4편에서 edge-tts를 설치할 때와 같은 이유(Homebrew Python의 PEP 668 제한)입니다. 해결도 동일합니다.
pip3 install openai --break-system-packages
전체 실행 — 첫 엔드투엔드 완주
지금까지 준비한 걸 순서대로 실행하면 됩니다.
# 1) 이미지 생성용 프롬프트 작성
cat > prompts.json << 'EOF'
[
{
"filename": "scene1.png",
"prompt": "따뜻한 조명의 홈 오피스, 노트북 화면에 코드가 떠있는 모습, 플랫 일러스트 스타일",
"size": "shorts_9_16",
"quality": "medium"
},
{
"filename": "scene2.png",
"prompt": "안드로이드 로봇 캐릭터가 자막 자동화 화면을 보는 모습, 플랫 일러스트 스타일",
"size": "shorts_9_16",
"quality": "medium"
}
]
EOF
# 2) 이미지 생성 (비용 발생)
python3 generate_images.py prompts.json
# 3) 씬별 TTS + 자막 타이밍 생성
python3 tts_captions.py "안녕하세요, 정데비의 작업실입니다." scene1
python3 tts_captions.py "오늘은 Remotion 자동화 테스트를 진행합니다." scene2
# 4) 씬 데이터 조립
python3 build_scene.py scene1 scene2
# 5) 최종 렌더링
npx remotion render SceneVideo --props=scene-props.json out/full-pipeline-test.mp4
prompts.json의 각 항목은 파일명·프롬프트·크기·품질을 담고 있습니다. size의 "shorts_9_16"은 세로 Shorts 비율용 규격이고, quality "medium"은 초안 확인용으로 적당한 수준입니다.
검증 결과
렌더링이 끝난 mp4를 실제로 열어서 확인한 결과, 씬1(98프레임)과 씬2(108프레임)를 합친 총 206프레임이 정확히 나왔고, 영상 길이도 오디오 길이와 완벽히 일치했습니다. 50프레임 지점(씬1, scene1.png 배경)과 150프레임 지점(씬2, scene2.png 배경)을 각각 캡처해서 씬 전환 시 이미지가 정상적으로 바뀌는 것도 확인했습니다. 대본 텍스트와 이미지 프롬프트만 준비하면 완성된 Shorts mp4가 나오는 흐름이 처음으로 완성된 순간입니다.
주의사항 / 흔한 실수
- GPT Image 2 호출은 비용이 발생하므로, 테스트 단계에서는 씬 2~3개 정도로 최소화하는 걸 권장합니다.
- build_scene.py 실행 시 나오는 경고 메시지(파일 없음)를 무시하고 넘어가면, 렌더링 단계에서 더 알아보기 어려운 에러로 나타날 수 있습니다.
- prompts.json의 filename과 tts_captions.py에 넣는 씬 이름(scene1, scene2 등)이 서로 일치해야 build_scene.py가 정상적으로 파일을 찾습니다.
마무리
이번 편에서 이미지·음성·자막 세 조각을 처음으로 하나의 mp4로 합쳐봤습니다. 지금은 다섯 개 명령어를 손으로 순서대로 실행했는데, 다음 편에서는 이 로컬 파이프라인을 Oracle A1 서버로 옮겨서 언제 어디서든 돌아가게 만들어보겠습니다.
[핵심요약] GPT Image 2로 이미지까지 연결해서 첫 자동 Shorts 완성
'실전 자동화 튜토리얼' 카테고리의 다른 글
| 한국어 AI 목소리 무료로 쓰기: edge-tts 연동하기 (Shorts 자동화 4편) (1) | 2026.07.18 |
|---|---|
| 대본만 바꾸면 영상이 바뀐다: Remotion 데이터 주입 구조 만들기 (Shorts 자동화 3편) (0) | 2026.07.18 |
| 코딩 몰라도 따라하는 Remotion 첫걸음 (Shorts 자동화 2편) (0) | 2026.07.18 |
| Shorts 자동화 툴을 Vrew에서 Remotion으로 바꾸면서 생긴 일들 (0) | 2026.07.18 |
| 돈 한푼 안 쓰고 백엔드 만들기: Cloudflare+Supabase 실전 구조 (0) | 2026.07.17 |