동영상 스크립트 고정밀 역공학
동영상 하나를 재현 가능한 정적 텍스트 스크립트로 복원합니다. 핵심 판단 기준: 독자가 영상을 보지 않고도 '볼 수' 있어야 합니다. 즉, 무엇을 말하는지, 어떻게 말하는지, 얼굴이 어떻게 변하는지, 누구를 바라보는지, 왜 그렇게 말하는지가 명확해야 합니다.
언제 호출하는가
- 사용자가 동영상 파일을 제공하며 '스크립트 분석 / 스크립트 재구성 / 프레임별 분석 / 장면 분석 / 텍스트 스크립트 변환 / 이 영상 어떻게 찍었는지' 등을 요구할 때
- 참조 영상에서 마케팅 카피 구조(고통점→공감→증거→가격 제시→행동 유도)를 추출해야 할 때
- 배우/연출자에게 연기 지시 시트(어조, 표정 변화, 시선 위치)를 제공해야 할 때
- 벤치마킹 영상으로부터 장면 분할과 편집 리듬을 역추론해야 할 때
부적합: 순수 자막 추출(ASR로 충분), 비디오 편집 자체, 음원 채보.
불변의 법칙 (먼저 이 다섯 가지를 기억하세요)
- 대사 절대 정리 금지: '어/에/음/응/아/휴/오/흠' 등을 그대로 유지하세요. 이것들은 현실감과 인물 배분의 핵심 증거이므로, 미화하거나 삭제하지 마십시오.
- 시선은 반드시 구체적으로 명시: '[A]의 시선이 [B의 구체적인 신분/부위]에 고정됨 + 머문 시간'과 같이 작성하고, '상대를 바라봄', '깊은 눈빛 교환' 같은 모호한 표현은 금지입니다.
- 표정은 '변화 궤적'으로 작성:
[시작] → [중간] → [끝]단계별로 진행합니다(예: 눈을 크게 뜸 → 동공 확장 → 눈썹 펴짐 입술 오므림). 단순한 정적 형용사 사용은 금지입니다. - 어조는 '음성 질감'으로 작성: 음높이, 음량, 말하기 속도, 호흡(속삭임/쉰 목소리/숨 들이쉼/한숨), 강세 위치, 멈춤 길이 — 다섯 가지 중 최소 세 가지를 포함해야 합니다.
- 화자는 반드시 검증 사슬을 통과해야 함: ASR 화자 분리는 반드시 오류를 포함합니다 → 분할 재전사 비교(P6) → 초 단위 자막 기준표(P3.5) → 입 모양 프레임 판정. 네 가지 증거를 모두 통과한 후에만 '[화자]'를 기재합니다.
실행 프로세스 (P0–P7)
P0 소재 프로브
ffprobe -v error -show_entries format=duration,size:stream=codec_type,codec_name,width,height,r_frame_rate \
-of default=noprint_wrappers=1 "<video>"
이를 바탕으로 샘플링 밀도를 결정(아래 표 참조)하고 오디오 트랙 존재 여부를 확인합니다(오디오 트랙이 없으면 P1을 건너뛰고 화면으로 추론).
| 길이 | 프레임 추출 전략 | 최대 프레임 수 | 설명 |
|---|---|---|---|
| ≤2분 | 2초당 1프레임 + 핵심 구간 1초당 1프레임 | 60–80 | 짧은 영상/광고, 모든 세부 정보 필요 |
| 2–10분 | 5초당 1프레임 | 60–100 | 드라마 단편 |
| 10–30분 | 10초당 1프레임 + 후크 구간 밀집 | 80–120 | 단편 드라마/긴 라이브 방송, 처음과 끝 각 90초는 3초당 1프레임 필요 |
| >30분 | 20초당 1프레임 + 분할 샘플링 | 100–150 | 장(chapter) 단위 복원만 수행, 먼저 개요를 만든 후 세부 분석 |
비용 규칙: 단일 작업에서 ViewImage 총 호출 수는 60회 이내로 유지하며, 배치당 8장씩 병렬 처리합니다. 프레임 수가 부족할 경우 '표정 전환점, 제품 클로즈업, 소품 클로즈업, 자막 카드'를 우선시합니다.
P1 오디오 전체 전사
ffmpeg -y -v error -i "<video>" -vn -ac 1 -ar 16000 -b:a 96k audio.mp3
AudioTranscribe(mp3/wav/m4a/mp4 등 지원, ≤1GB 또는 5시간)로 전사합니다. [시작, 끝, 화자ID]가 포함된 타임스탬프 텍스트를 생성합니다 — 이는 이후 모든 시간 축의 뼈대가 됩니다.
참고: 반환된 화자 ID는 단순 클러스터링 번호이며, 캐릭터가 아닙니다. 반드시 의미론, 어조, 화면을 함께 판단해야 합니다.
P2 프레임 추출
# 먼저 장면 전환 감지 시도(컷이 많은 영상에 사용)
ffmpeg -y -v error -i "<video>" -vf "select='gt(scene,0.15)',showinfo" -vsync vfr -q:v 3 kf_%03d.jpg 2> scene_log.txt
grep -o "pts_time:[0-9.]*" scene_log.txt | head -100
- 10프레임 미만 검출 → 단일 카메라 연속 촬영(라이브 방송/드라마)이므로 균일 프레임 추출로 전환:
-vf "fps=1/10,scale=576:-1" - 임계값을
0.08로 낮추어 재시도할 수 있음. 그래도 전환이 없으면 장면 감지 포기 - 세로형 짧은 영상은 통일
scale=576:-1, 표정을 충분히 볼 수 있으면서 토큰을 낭비하지 않음
P3 배치 프레임 보기
배치당 8장씩 ViewImage 병렬 처리, 통일된 쿼리 템플릿 사용(비교 가능성 보장):
이 세로형 영상 프레임 설명: 인물 외모, 표정, 동작, 장면, 의상, 자막 텍스트, 구도
프레임 읽기 중요 포인트:
- 인물 관계 방향(누가 누구를 잡아끄는지, 누가 누구를 쫓는지, 누가 끌려가는지, 누가 어떤 차에 타는지)은 반드시 프레임을 통해 확인해야 합니다. ASR은 절대 이 정보를 제공하지 않습니다. 같은 장면에 두 명의 동성 성인이 있을 경우, 클러스터 ID를 캐릭터로 직접 사용하지 마십시오.
- 자막 텍스트는 무료 고가치 정보입니다(드라마 제목 워터마크, 브랜드명, 제품 자막, 가격 자막, 면책 조항, 대사 인물명) — 프레임별로 모두 기록하세요. 자막에 등장하는 인물명(예: '구천아, 질질 끌지 마')과 화면에서 '누가 끌려가는지'를 결합하면 대사 귀속의 결정적 증거가 됩니다.
- 상주 요소(워터마크, 면책 자막, 로고)에 주의하세요. 이들은 문서 상단에 기록합니다.
- 각 프레임에 해당하는 초를 기억하세요(
kf_001= 0초,kf_002= 10초...). 이후 장면 설명에 사용합니다.
P3.5 전체 영상 자막 그리드: 초 단위 대사 기준표 생성 (화자 귀속의 첫 번째 증거)
자막이 내장된 영상(단편 드라마/마케팅 영상은 거의 모두 해당)의 경우, 먼저 대사의 '공식 답안'을 확보합니다:
# 초당 1프레임으로 자막 영역 크롭(먼저 1프레임 전체 이미지로 자막 세로 위치 확인, 예시는 y=710, 높이 140)
ffmpeg -y -v error -i "<video>" -vf "fps=1,crop=576:140:0:710,drawtext=fontfile='<font>':text='%{pts\:hms}':x=8:y=6:fontsize=24:fontcolor=white:box=1:[email protected],tile=3x10" -q:v 3 sub/grid%02d.jpg
- 30프레임/그림 → 14분 영상 기준 약 29장. 각각
ViewImage로 '타임스탬프→자막 텍스트' 읽음 - 파란색/흰색 테두리 자막은 일반적으로 나레이션 전환 자막(예: '두 사람은 어쩔 수 없이 헤어진다')이므로 별도 분류, 대사에 혼합 금지
- 두 줄 자막은 윗줄이 잘릴 수 있음 — 의심스러우면 해당 초의 전체 프레임 확인
이 초 단위 기준표는 한 번에 네 가지 문제를 해결합니다: 문장 누락, 문장 중복, 텍스트 오타(그/그녀), 감탄사 귀속 — ASR과 자막이 충돌할 때는 자막 텍스트를 먼저 신뢰하고, 입 모양 프레임으로 화자를 판정(자막은 화자를 표시하지 않음).
P4 뼈대 구축: 대사 흐름을 장면 구간으로 나누기
- ASR 타임스탬프를 축으로, 장면/공간 변화에 따라 구간 분할(장면 전환, 상대방 변경, 감정 기조 변화)
- 각 구간 명명 형식:
⏱️ [mm:ss - mm:ss] 이벤트명(기능 레이블), 예:[04:15 - 05:10] 간호 테이블에서의 신호·립밤 첫 등장 - 구간 시작에
> 장면 설명:(조명, 구도, 주요 물체 위치, 인물 위치) - 구간 내 대사는 시간 순서대로 한 줄씩 정렬, 여러 명이 중첩될 경우 행을 나누고 '(여기서 X와 동시 발성)' 표시
P5 5차원 채우기 (각 대사 줄 아래에 다섯 개 레이블)
| 레이블 | 필수 내용 |
|---|---|
| 🎙️ 음성 질감 | 음높이 변화 / 음량 / 말하기 속도 / 호흡(속삭임·쉰 목소리·숨 들이쉼·한숨) / 강세가 있는 단어 / 멈춤(초) |
| 😐 표정 변화 궤적 | [시작]→[중간]→[끝] 세 단계, 눈썹, 눈, 입, 콧날, 턱의 구체적 움직임까지 작성 |
| 👀 시선 상호작용 | [주체]의 시선이 [객체 구체적 명칭]에 고정됨, 머문 시간; 시선 이동은 경로를 작성해야 함 |
| 🙌 동작 세부 | 손 동작, 몸 방향, 이동 궤적, 소품 상호작용(손가락 마디 하얘짐/움켜쥠/손끝 떨림 같은 미세 동작 우선) |
| 🫧 표정·분위기 | 한 문장으로 이 순간의 심리 상태를 규정(연출자 관점, 표정을 다시 말하는 것이 아님) |
감탄사는 별도 문장으로 분석해야 함: '흠' 한 소리가 비강 기음인지 후음인지, 냉소인지 항복인지, 다음 문장과의 간격을 명확히 작성 — 이것이 누구의 대사인지 결정합니다.
P6 2차 교차 검증 (이 스킬의 핵심 가치, 건너뛰면 안 됨)
문제점: 전체 영상을 한 번에 전사하면 인접한 두 사람의 말이 한 덩어리로 합쳐지고, '그/그녀'를 같은 글자로 작성하며, 의문문을 평서문으로 작성할 수 있습니다.
방법: 4–6개의 '고위험 구간'을 선별하여 다시 전사하고, 전체 전사본과 문장별로 비교합니다.
고위험 구간 특징(하나라도 해당되면 분할):
- 한 구간에 ≥2명의 캐릭터 대화 포함(특히 속삭임 구간, 싸움 구간, 군중 장면)
- 같은 장면에 두 명의 동성 성인 등장(음색이 비슷하여 클러스터링이 쉽게 합쳐짐)
- '그/그녀'가 등장하고 지칭이 혼동될 가능성 있음
- 겹치는 말, 끼어들기, 동시 발성 발생
- 감탄사가 독립된 문장으로 등장(흠/오/에/아)
- 이별, 잡아당김, 추격, 배웅 장면('누가 끌려가고, 누가 쫓는지'가 매우 쉽게 반대로 쓰임)
- 타임스탬프 간격 >20초인데 화자 ID가 변하지 않음(합쳐졌다는 의미)
# 70–90초 구간 자르기(무음 경계 피하기, 앞뒤 각 1초 여유)
ffmpeg -y -v error -ss 15 -t 75 -i "<video>" -vn -ac 1 -ar 16000 -b:a 96k seg1.mp3
각 구간에 대해 AudioTranscribe를 한 번씩 실행하고, 아래 표에 따라 판정합니다:
| 차이 유형 | 판정 방법 | 처리 |
|---|---|---|
| 화자 전도 | 분할 구간에서 발성 위치가 번갈아 나타나는지 확인(A/B/A/B); 이후 화면 입 모양 및 줄거리 인과 관계 결합 | 교대 규칙 + 줄거리 논리를 기준으로 본문에 📌 교정 설명 추가 |
| 그/그녀 혼동 | 동음이의어는 반드시 오류. 지칭 대상의 실제 성별로 수정 | 직접 수정, 원문 유지 금지 |
| 문장 누락(전체 전사본에 없음) | 분할 전사본에 나타난 문장이 본문에 없음 | 추가하고, 구간 내 시간 축 조정 |
| 합쳐진 문장 분할 필요 | 한 문장에서 주어와 술어가 일치하지 않음('빨리 가, 질질 끌지 마, 기다리고 있어') | 의미에 따라 2–3행으로 분할, 각각 귀속 |
| 의문문/평서문 오판 | 끝말 올라감 여부, '?' 의미 확인 | 항의문은 '!', 추궁문만 '?' 사용 |
| 화면 밖 나레이션 vs 발성 | 분할 구간에서 앞뒤와 같은 발성 위치 연속성, 오디오 트랙 전환 여부 | 연속 동일 위치 = 발성 속삭임, '상대가 듣지 못함' 표시, '내적 독백' 아님 |
| 동작 방향 전도 | 프레임 확인: 누가 누구를 잡는 손, 누가 어떤 차에 탔는지, 자막 호칭이 누구를 부르는지 | 전체 구간 반전하여 재작성, 본문에 📌 교정 설명 추가 및 프레임 증거 첨부 |
3차 화면 재검증: 동작 방향, 인물 관계(누가 끌려가는지/누가 쫓는지/누가 누구를 잡는지)와 관련된 결론은 2차 순수 텍스트 비교만으로는 확정할 수 없습니다. 반드시 밀집 프레임 추출(1초당 1프레임)로 화면을 확인하고, 이후 대사(예: '15년 전에 네가 나를 끌고 갔잖아')를 이용한 역추론으로 상호 검증해야 합니다. 실제 사례는 references/pitfalls.md #9 참조.
4차 자막 기준표 재검증: 인계 전에 P3.5의 초 단위 자막 기준표와 스크립트를 한 줄씩 정렬 — 스크립트 대사가 자막 텍스트와 일치하지 않거나 자막에는 있는데 스크립트에 없는 문장은 하나씩 수정/추가합니다. 귀속이 의심스러운 지점은 전체 프레임으로 입 모양 확인하여 확정(프레임 추출 시점 = 자막이 나타난 초). 두 가지 특별 규칙:
- 회상 장면의 원래 음성이 넘쳐흐름: 회상 화면이 끝난 후, 원래 음성이 현실 장면으로 이어질 수 있음(예: 현실 장면에서 어머니의 입이 닫혀 있지만 자막은 어린 시절의 '쉿'을 보여줌) — 귀속은 오디오 트랙을 따르고, 화면을 따르지 않음;
- 자막의 '그녀'가 반드시 여성은 아님: 원본 자막은 종종 '그/그녀'를 혼용하므로, 의미와 이후 지칭을 기준으로 실제 지칭을 판단하지만, 원문 자막을 인용할 때는 원문을 유지하고 주석을 추가합니다.
검증 기록은 인계물에 포함되어야 함(표: 시간 지점 / 원고 / 검증 후 / 판정 근거 + 일치도 + 미해결 불확실 사항) — 이는 스크립트 신뢰도의 증거입니다.
P7 인계 및 자체 점검
단일 Markdown 파일로 출력, 구조는 references/script-template.md 참조. 인계 전에 references/qc-checklist.md를 하나씩 확인합니다.
마지막으로 present_files로 표시하고, 답변에 다음을 포함합니다: 영상 식별 결과(드라마명/카테고리/길이), 핵심 줄거리 한 문장, 마케팅 구조, 이번 검증에서 수정된 사항 수.
스크립트 도구
scripts/extract_assets.sh 한 번으로 프로브→오디오→장면 감지→균일 프레임 추출→고위험 구간 분할까지 수행:
bash scripts/extract_assets.sh "<video>" "<outdir>" [프레임 간격(초)]
# 예: bash scripts/extract_assets.sh ./v.mp4 ./frames 10
스크립트 출력: probe.txt, audio.mp3, kf_*.jpg(번호↔초 매핑 포함), scene_log.txt. 프레임 수와 길이를 작업량 표로 출력합니다.
참조 파일
references/script-template.md— 인계물 완전한 뼈대 (캐릭터 프로필 / 어조·표정 총표 / 구간별 5차원 / 마케팅 방법론 / 연기 지시 시트 / 검증 기록)references/qc-checklist.md— 인계 전 16항목 자체 점검 목록references/pitfalls.md— 10가지 고빈도 오류와 대책 (실제 사례 포함)
출력 규칙
- 시간 형식 통일
mm:ss(1시간 초과 시hh:mm:ss), 단락 제목에는 구간을, 대사 블록 내에는 단일 초 표시 가능 - 캐릭터명 통일: 첫 등장 시 전체 이름, 본문에서는 【】로 감싸기, 예시
【구모】 - 동일 캐릭터의 다른 신분(가명/어린 시절/성인)은 반드시 별도 파일로 구분하고, 파일 내에 대응 관계 명시
- 제품명, 브랜드명, 가격은 반드시 프레임별로 자막 확인(ASR은 브랜드명을 자주 잘못 들음, 예: '호로꿍수' → '당근 수')