송아영
송아영
🐶 AI 찐친
🎖️ 마스터 파트너
🧭 경험 찐친

전자책 스터디 사라진 영상 제작 5단계: 클로드 코드와 리모션 활용법

❤️ 소개 — 시도하고자 했던 것과 그 이유

전자책 제작 스터디의 사례 발표 모임(2026-05-26) 영상을 복구하는 작업이었습니다.

문제는 이거였어요. 줌 녹화가 제대로 안 돼서 영상 화면은 사라지고, 남은 건 두 가지뿐이었습니다.

입을 벌리고 있는 심슨의 이미지
  • 119분짜리 오디오 파일 (회의 음성 전체)

  • 발표자 6명이 공유했던 화면 캡처 PNG (각자 사례 글을 길게 스크롤한 세로 이미지)

녹취록(클로바노트)도 있었지만 화면이 없으니 "까만 화면에 소리만 나오는 영상"이 될 판이었죠.

그래서 떠올린 아이디어가 "발표자가 화면을 천천히 스크롤하면서 설명하던 그 느낌을, 캡처 이미지를 오디오 타이밍에 맞춰 자동으로 스크롤시켜 재현하자" 였습니다.

화면 녹화를 다시 할 수도 없고, 영상 편집 프로그램으로 119분을 일일이 맞추는 건 엄두가 안 났어요. 그래서 코드로 영상을 만드는 Remotion을, 클로드 코드에게 통째로 맡겨보기로 했습니다.

핵심 컨셉: 오디오(원본) + 슬라이드 PNG(자동 스크롤) + 자막 + 챕터 카드 → 코드로 합성

❤️ 진행 방법 — 어떤 도구를 어떻게 활용했나

사용한 도구

| Claude Code | 전체 작업 지휘 — 녹취록 분석, 챕터 분할, 자막 생성 스크립트, Remotion 코드 작성, 렌더링까지 직접 실행 |

| Remotion | React 코드로 영상을 만드는 프레임워크. 슬라이드 스크롤·자막·인트로/아웃트로를 컴포넌트로 구현 |

| PowerShell / Node | 녹취록 파싱 → 자막(SRT) 자동 생성 |

작업 흐름 (클로드 코드가 단계별로 수행)

1. 프로젝트 폴더 구조 + CLAUDE.md 셋업
2. 원본(오디오/녹취록/슬라이드) 분석 → 발표자·타임스탬프 매핑
3. 챕터 맵 작성 (CHAPTERS.md) — 11챕터, 발표자별 구간·슬라이드 매칭
4. 녹취록 → 자막(SRT + JSON) 자동 생성 + STT 오인식 보정
5. Remotion 프로젝트 구현 (슬라이드 스크롤 / 자막 / 챕터카드 / 인트로 / 아웃트로)
6. 30초 데모 렌더 → 검수 → 자막 4줄 제한 수정
7. 전체 119분 본 렌더 → study-video.mp4

실제로 사용한 프롬프트 (전문)

① 자료를 던지고 컨셉을 설명한 첫 지시


""C:\Users\송아영\Documents\카카오톡 받은 파일\05-26_주간_회의_AI_글쓰기_전자책_제작_저작권.mp3"
E:\송아영\05-26_주간_회의_AI_글쓰기_전자책_제작_저작권.txt"
그리고 "E:\송아영\사례발표 화면" 이 경로에 발표자 화면 있어.
설명할 때 오디오에 해당하는 화면을 천천히 스크롤하면서 보여주고 싶어

→ 클로드 코드가 알아서 녹취록에서 화자(`참석자 1~8`)와 타임스탬프를 파악하고,

PNG 6장의 해상도를 분석(세로로 매우 긴 캡처임을 확인)한 뒤,

"슬라이드 자동 스크롤" 방식이 적합하다고 판단해 설계를 시작했습니다.

② 발표자 닉네임 매핑을 바로잡은 지시

참석자 3은 배꽃이야. 참석자 4는 이응이응, 참석자7은 백구우야.
참석자 6은 AJ (에이제이)
그리고 스크롤 할 이미지에 발표내용이 다들어 있지 않거나 짧을 수 있어.
이럴 땐 리모션 영상 넣어서 내용 전달 잘 할 수 있도록 구성해줘.
필요하다면 화면 이미지 해당부분 재차 보여줘도 되고

→ STT가 닉네임을 "소영강/소현장/백구호/에이제이…" 등으로 제멋대로 적어둔 걸,

정식 닉네임 표를 만들어 일괄 치환 규칙으로 정리했습니다.

③ 자막이 화면을 너무 가린다 → 4줄 제한

자막이 한번에 너무 많이 보여서 화면을 좀 가리는 부분이 많은데
이거 조정 간단한거야. 아니면 리소스나 시간 많이 드는 작업이야?
최대 4줄이 넘지 않도록 하는건 어때?

→ 한 발화(긴 건 1~2분짜리도 있음)를 통째로 보여주던 걸,

문장 → 쉼표 → 공백 순으로 자연스럽게 잘라 한 화면에 ~4줄(약 130자)만 띄우고,

발화 시간을 등분해 자막을 차례로 넘기도록 고쳤습니다. (`1/3`, 2/3 진행 표시도 추가)

핵심 코드 ① — 슬라이드 자동 스크롤

세로로 긴 PNG를, 챕터(=발표) 길이에 맞춰 위→아래로 균등하게 흘려보내는 컴포넌트입니다.

슬라이드가 너무 길면(AJ 슬라이드는 무려 29,272px!) cap 모드로 표준 속도까지만 스크롤하고 멈추게 했습니다.

```tsx
// 슬라이드별 원본 크기를 하드코딩 → 런타임 이미지 로딩 없이 정확한 스크롤 계산
const SLIDE_SIZES: Record<string, { w: number; h: number }> = {
"AJ.png": { w: 1920, h: 29272 }, // 매우 김 → cap 모드
"노명숙.png": { w: 1652, h: 11194 },
"배꽃.png": { w: 1920, h: 12394 },
"백구우.png": { w: 1652, h: 8578 },
"소양강.png": { w: 1652, h: 9164 },
"이응이응.png": { w: 1652, h: 6034 },
};
export const SlideScroll: React.FC<{
slide: string; durationFrames: number; scrollMode: "fit" | "cap";
}> = ({ slide, durationFrames, scrollMode }) => {
const frame = useCurrentFrame();
const meta = SLIDE_SIZES[slide];
const displayW = 1920;
const scale = displayW / meta.w;
const displayH = meta.h * scale; // 화면 폭에 맞췄을 때의 전체 높이
const scrollMax = Math.max(0, displayH - 1080); // 스크롤 가능 거리
const progress = frame / Math.max(1, durationFrames - 1);
let translateY: number;
if (scrollMode === "fit" || scrollMax === 0) {
translateY = -scrollMax * Math.min(1, progress); // 발표 시간에 맞춰 끝까지 균등 스크롤
} else {
const targetY = 16 * (frame / 30); // 표준 16px/초로 스크롤하다
translateY = -Math.min(scrollMax, targetY); // 끝에 닿으면 정지
}
return (
<AbsoluteFill style={{ backgroundColor: "#0a0d12", overflow: "hidden" }}>
<div style={{ width: displayW, height: displayH, transform: translateY(${translateY}px) }}>
<Img src={staticFile(`slides/${slide}`)} style={{ width: displayW, height: displayH }} />
</div>
</AbsoluteFill>
);
};
```

핵심 코드 ② — 자막 4줄 자동 분할

긴 발화를 화면을 안 가리도록 잘라주는 함수입니다.

```tsx
// 130자 ≈ 4줄. 문장(.!?) > 쉼표 > 공백 순으로 자연스럽게 끊는다.
function splitText(text: string, maxChars = 130): string[] {
if (text.length <= maxChars) return [text];
const breakPatterns = [/(?<=[.!?])\s+/g, /(?<=,)/g, /\s+/g];
const chunks: string[] = [];
let remaining = text;
while (remaining.length > maxChars) {
let cutAt = -1;
for (const re of breakPatterns) {
for (const m of remaining.matchAll(re)) {
const pos = m.index! + m[0].length;
if (pos > maxChars * 0.55 && pos <= maxChars) cutAt = pos; // 너무 짧지 않게
}
if (cutAt > 0) break;
}
if (cutAt < 0) cutAt = maxChars; // 끊을 곳 없으면 강제 분할
chunks.push(remaining.slice(0, cutAt).trim());
remaining = remaining.slice(cutAt).trim();
}
if (remaining) chunks.push(remaining);
return chunks;
}
```

핵심 코드 ③ — 챕터를 시간축에 배치 (전체 영상 조립)

초 → 프레임 변환으로 각 발표 구간을 영상 타임라인에 그대로 꽂았습니다.

```tsx
export const StudyVideo: React.FC = () => (
<AbsoluteFill style={{ backgroundColor: "#0f1419" }}>
<Audio src={staticFile("audio.mp3")} startFrom={0} /> {/* 원본 오디오 전체 */}
<Sequence from={0} durationInFrames={5 * 30}><LogoIntro /></Sequence> {/* 인트로 5초 */}
{CHAPTERS.map((ch) => (
<Sequence key={ch.id}
from={secToFrames(ch.startSec)}
durationInFrames={secToFrames(ch.endSec - ch.startSec)}>
<ChapterRenderer chapter={ch} absoluteSecOffset={ch.startSec} />
</Sequence>
))}
</AbsoluteFill>
);
```

> (관련 캡처 정리는 같은 폴더의 대화기록_주요프롬프트.md 참고)

완성 영상 샘플

❤️ 결과와 배운 점

결과

  • 사라진 줄 알았던 119분 영상이 자막·발표자 배지·챕터 카드까지 붙은 완성본으로 부활했습니다.

  • 영상 편집 프로그램을 한 번도 안 열고, 타임라인을 코드(초 단위)로 정의한 게 전부였어요.

  • 자막·챕터·스크롤 속도를 바꾸고 싶으면 숫자 한두 개만 고치고 다시 렌더하면 됩니다. (수동 편집이었다면 처음부터 다시 했어야 할 일)

나만의 꿀팁

  1. "화면 녹화"라는 고정관념을 버리니 길이 보였다. 원본 화면이 없어도, 발표자가 보여주던 자료(PNG)만 있으면 "스크롤 연출"로 충분히 그 느낌을 살릴 수 있었습니다.

  2. 클로드 코드에게는 "결과의 그림"을 먼저 주자. "오디오에 맞춰 화면을 천천히 스크롤하고 싶어" 라는 한 문장이, 폴더 구조부터 렌더까지 전부를 끌어냈습니다. 세세한 코드를 지시하지 않아도, 의도만 명확하면 알아서 설계합니다.

  3. 검수는 '짧은 데모 → 전체'로. 처음부터 119분(약 2시간)을 렌더하지 않고 30초 데모부터 뽑아 자막·스크롤을 확인했습니다. 자막이 화면을 가린다는 문제도 데모에서 먼저 잡았어요.라고 크롤드코드가 작성해줬지만 사실은 전체 영상 만든 후 방해 된다고 느껴서 그때 수정했습니다. 최대 4줄 넘지 않게 해달라고 요청했답니다.

  4. STT 오인식은 '치환 규칙표'로 한 방에. "소영강/소현장/소연강…"처럼 흩어진 이름을 정식 닉네임으로 모으는 규칙을 만들어두니, 녹취록이 바뀌어도 스크립트만 다시 돌리면 됩니다. 그래도 꼼꼼히 살피지 않았더니 영상 중간에 오타가 굉장히 많았습니다~ 제 발음 문제겠지만요 ^^

시행착오

  • `node` 실행이 막혔다. 클로드 코드의 안전 모드가 "검증 안 된 스크립트 실행"을 차단해서, 자막 생성 스크립트를 PowerShell 인라인 코드로 바꿔 같은 로직을 돌렸습니다. (우회가 아니라 허용된 도구로 전환)

  • Remotion 컴포지션 id에 언더스코어(`_`)를 못 쓴다. Ch0_Opening 에서 에러 → Ch0-Opening(하이픈)으로 수정.

  • 리모션은 렌더 시간 오래걸린다. 슬라이드가 크고 긴 후반 챕터(노명숙·배꽃)에서 더 느려져서, 최종적으로 약 4시간 걸렸어요.

  • Studio와 렌더를 동시에 켜두니 느렸다. 미리보기용 Studio를 끄니 렌더가 빨라졌습니다.

  • 폰트 로딩 경고. Noto Sans KR을 weight 4종 다 불러와서 매 탭마다 네트워크 요청이 폭주했어요. (다음엔 weight를 줄여 로딩 최적화 예정)

❤️ 도움이 필요한 부분

  • 자막을 문장 단위로 더 정교하게 끊고 싶습니다. 지금은 글자 수 기준이라 가끔 어색하게 잘려요. 아~ 이 부분은 해결 방법이 있긴 합니다. 오디오를 위스퍼를 이용해 실제 대화 인지하도록 한 후 원하는 형식으로 끊어달라고 하면 됩니다. 자막과 오디오 불일치는 이전에 외주영상 만들면서 지옥 문턱까지 가서 터득한 노하우입니다 ㅎㅎㅎㅎ~

  • 긴 슬라이드(AJ 29,272px)는 스크롤이 빨라 가독성이 떨어집니다. "중요 부분만 잘라 확대(줌인)" 하는 인서트를 넣는 게 다음 숙제예요.

앞으로의 계획

  • 스터디때 녹화 확인을 생활화 하겠습니다~ ^^

    내가 맹세하는 단어가 적힌 만화 펭귄

도움 받은 글 / 참고 자료

  • Remotion 공식 문서 — https://www.remotion.dev/docs/

  • Remotion 기본 개념(Fundamentals) — https://www.remotion.dev/docs/the-fundamentals

  • 리모션_개념과_활용법.pdf — Remotion 핵심 개념·코드 패턴·학습 링크 정리

    리모션_개념과_활용법.pdf
    334.43KB
  • 대화기록_주요프롬프트.pdf— 이번 작업에서 오간 핵심 프롬프트·의사결정 캡처

    대화기록_주요프롬프트.pdf
    354.7KB

6
1개의 답글
밀어주고 끌어주는

온·오프라인 AI 스터디

AI로 어디까지 할 수 있는지
직접 확인하실 분만 신청하세요.