# Claude Code 영상 편집 자동화: 컷편집·자막 직접 돌려 본 과정과 막힌 3곳

> Claude Code는 mp4 대신 받아쓰기를 읽고 ffmpeg로 자릅니다. 말이 중심인 토크·강의 영상은 무음·실수 테이크 정리와 자막까지 맡기고, 화면을 보고 고르는 컷은 사람이 맡습니다.

- URL: https://blog.laozhang.ai/ko/posts/claude-code-video-editing
- Published: 2026-10-15
- Updated: 2026-10-15
- Author: LaoZhang AI Team (https://blog.laozhang.ai/ko/about)
- Topic: Claude Code
- Tags: Claude Code, 영상 편집, 자막, ffmpeg, Whisper

---
Claude Code(클로드 코드)로 영상 편집을 자동화할 수는 있지만, Claude가 mp4를 직접 보고 자르는 방식은 아닙니다. Whisper 같은 받아쓰기 도구가 음성을 단어별 시간이 붙은 텍스트로 바꾸고, Claude Code는 그 텍스트를 읽어 남길 구간을 정한 뒤 ffmpeg 명령을 실행합니다. 그래서 1인 토크, 화면 녹화 강의, 인터뷰, 팟캐스트, 라이브 다시보기처럼 **말로 컷을 정할 수 있는 영상**이라면 무음 삭제, 실수한 테이크 제거, 자막, 세로 9:16 버전까지 첫 컷편집을 맡길 만합니다. 멀티캠 전환, 색보정, 표정이나 동작을 보고 고르는 컷, B롤 선택은 여전히 편집 프로그램과 사람이 맡아야 합니다.

아래 테스트는 2026년 10월 15일 Apple M4 맥(macOS 26.1)에서 Claude Code(Opus 5.5) 세션으로 32초짜리 클립을 한 번 편집한 결과입니다. 클립은 macOS `say`로 만든 영어 합성 음성과 ffmpeg 테스트 화면이라서 실제 촬영본의 잡음, 여러 화자, 한국어 받아쓰기 정확도는 이 결과로 판단할 수 없습니다. video-use, ButterCut, ChatCut, 편집 프로그램용 MCP 서버는 테스트에 포함되지 않았으므로 해당 부분은 각 프로젝트의 공개 문서를 바탕으로 설명합니다.

## Claude Code가 영상을 편집하는 방식: mp4 대신 받아쓰기를 읽습니다

Claude는 영상과 오디오를 입력으로 받지 않습니다. [Anthropic Claude 비전 문서](https://platform.claude.com/docs/en/build-with-claude/vision)에 적힌 지원 형식은 JPEG, PNG, GIF(첫 프레임만), WebP 이미지뿐이고, [Claude Code 도구 레퍼런스](https://code.claude.com/docs/en/tools-reference)의 Read 도구가 읽는 것도 이미지·PDF·노트북입니다. 두 문서 어디에도 동영상이나 오디오 항목은 없습니다. 그래서 Claude에게 영상을 '보여 주려면' ffmpeg로 프레임을 이미지로 뽑거나, 음성을 텍스트로 받아써야 합니다.

실제 편집은 네 단계로 돌아갑니다.

1. **받아쓰기**: 로컬 Whisper나 유료 API인 ElevenLabs Scribe가 음성을 단어마다 시작·끝 시간이 붙은 텍스트로 바꿉니다.
2. **편집 결정**: Claude Code가 받아쓰기를 읽고 남길 구간 목록(EDL, 편집 결정 목록)을 씁니다. 같은 문장을 두 번 말했다면 마지막 테이크를 남기는 판단이 여기서 나옵니다.
3. **실행**: ffmpeg가 목록대로 자르고 붙이고 자막을 입힙니다. 명령은 Claude Code가 작성해 터미널에서 실행합니다.
4. **확인**: 결과물을 다시 받아쓰거나 프레임 몇 장을 뽑아 Claude가 이미지로 확인합니다.

![받아쓰기, 편집 결정, ffmpeg 실행, 확인으로 이어지는 Claude Code 영상 편집 네 단계와 단계별 결과 파일 words.json, edl.json, final.mp4](https://blog.laozhang.ai/posts/ko/claude-code-video-editing/img/claude-code-video-editing-workflow.webp)

Claude Code는 편집 기능을 가진 프로그램이라기보다 이런 도구를 부리는 지휘자에 가깝습니다. 일본 Fyve의 입문 글(2026년 6월 29일)도 같은 구조로 설명하면서, 결과물을 "70%는 자동, 30%는 수작업"인 초안으로 보라고 조언합니다.

이미 찍은 소스를 자르는 일과 새 영상을 만드는 일은 다른 작업입니다. 코드로 애니메이션 MP4를 만드는 방법은 [Claude Opus 5.5 영상 생성: 코드로 MP4 만드는 법과 한계](https://blog.laozhang.ai/ko/posts/claude-opus-5-5-video-generation)에서 다룹니다. claude.ai의 Claude Motion은 텍스트·차트·이미지를 움직이는 MP4로 만드는 Team·Enterprise 베타 기능으로, 올린 촬영본을 편집하지 않고 Claude Code와도 별개입니다. 자세한 내용은 [Claude 대시보드·Motion 사용법: Motion은 Team부터, 안 보일 때 켤 설정](https://blog.laozhang.ai/ko/posts/claude-dashboards-and-motion)을 참고하세요.

## 영상 10분의 토큰 비용: 프레임은 약 $6.46, 받아쓰기는 $0.08 이하

받아쓰기를 먼저 만드는 이유는 비용입니다. Anthropic 비전 문서의 현재 공식은 이미지 한 장 = ⌈가로/28⌉ × ⌈세로/28⌉ 토큰입니다. Claude 4.7 이후 모델(Opus 5.5 포함)은 고해상도 등급이라 1920×1080 프레임을 줄이지 않고 2,691토큰으로 계산합니다. 고해상도 등급이 아닌 모델에서는 같은 프레임이 1456×819로 줄어 1,560토큰입니다.

10분짜리 토크 영상을 기준으로 계산하면 다음과 같습니다. 가격은 Opus 5.5 API 표준가인 입력 100만 토큰당 $4(출력은 $20)를 썼고, 2026년 10월 10일 Claude 가격 페이지 기준입니다.

| Claude에 보내는 것 | 계산 | 입력 토큰 | Opus 5.5 입력 비용 |
| --- | --- | --- | --- |
| 1080p 프레임, 초당 1장 | 600장 × 2,691 | 약 161만 | 약 $6.46 |
| 640×360으로 줄인 프레임, 초당 1장 | 600장 × (23 × 13 = 299) | 약 17.9만 | 약 $0.72 |
| 단어별 JSON 받아쓰기 | 1,500단어 × 약 57바이트 ≈ 86KB, 4글자당 1토큰 | 약 2.1만 | 약 $0.08 |
| "시작 끝 단어" 한 줄 형식 받아쓰기 | 1,500단어 × 약 20바이트 ≈ 30KB, 4글자당 1토큰 | 약 7,500 | 약 $0.03 |

전제는 분당 150단어, 4글자당 1토큰(영어 경험칙)이고, 단어당 57바이트는 테스트 받아쓰기(57단어, 3,275바이트) 한 건에서 잰 값입니다. 청구서로 확인한 금액이 아니라 공식으로 낸 추정치이며, 실제 Claude Code 세션에는 시스템 프롬프트, 도구 정의, 앞선 대화가 더해져 이보다 많이 씁니다. 한국어 받아쓰기는 글자당 토큰 비율이 영어와 다를 수 있습니다. 프레임을 아무리 많이 보내도 Claude는 소리를 듣지 못한다는 점도 함께 기억해야 합니다.

1시간 소스라면 받아쓰기 쪽 입력은 6배인 약 4.5만~12.6만 토큰, Opus 5.5 입력 비용으로 약 $0.18~$0.50입니다. video-use README도 같은 이유로 프레임을 통째로 보내는 방식(3만 프레임 × 1,500토큰 ≈ 4,500만 토큰)을 피하고, 약 12KB로 압축한 받아쓰기와 PNG 몇 장만 Claude에게 넘긴다고 설명합니다.

Pro·Max 구독으로 쓴다면 이 숫자는 청구액이 아니라 사용 한도를 그만큼 소모한다는 뜻입니다. 한국어 블로그 Heimdex(2026년 8월 5일)는 소스가 길수록 토큰을 많이 써서 사용 한도를 소진할 수 있다고 경고합니다. 한도가 예상보다 빨리 줄어든다면 [Claude Code Max 사용량 비정상 소모? 완전 진단 및 해결 가이드 (2026)](https://blog.laozhang.ai/ko/posts/claude-code-max-quota-consumption)에서 원인을 점검할 수 있고, 플랜별 차이는 [Claude Code 가격 2026: Pro, Max, Team, API, extra usage 선택법](https://blog.laozhang.ai/ko/posts/claude-code-pricing-guide)에 정리되어 있습니다.

## 내 소스에 맞나: 말로 컷을 정할 수 있는 영상이면 맡길 만합니다

판단 기준은 하나입니다. "어디를 자를지"를 받아쓰기만 보고 정할 수 있으면 Claude Code가 잘하는 영역이고, 화면을 봐야 정할 수 있으면 사람이 할 일이 남습니다.

| 소스 유형 | Claude Code에 맡길 수 있는 일 | 사람이 확인해야 하는 일 |
| --- | --- | --- |
| 1인 토크·얼굴 나오는 말하기 영상 | 앞뒤 무음, 문장 사이 공백, 다시 말한 테이크 정리, 자막, 세로 버전 | 표정이 더 나은 테이크 고르기, 화자가 움직일 때 세로 구도 |
| 화면 녹화 강의 | 무음과 NG 구간 삭제, 자막 | 화면 내용이 바뀌는 순간을 기준으로 한 컷(프레임을 뽑아 확인) |
| 인터뷰·팟캐스트 | 받아쓰기 기반 발췌, 자막 | 화자 구분(여러 화자는 테스트 범위 밖), 발췌한 말의 맥락 |
| 라이브 다시보기처럼 긴 소스 | 받아쓰기로 쓸 만한 구간 후보 찾기 | 토큰 사용량, 긴 영상의 자막 밀림 |
| 멀티캠, 색보정 중심, B롤 위주, 스포츠·액션 | 거의 없음 | 대부분(편집 프로그램에서 작업) |

긴 영상의 자막 밀림은 Fyve가 지적한 문제입니다. 러시아 Habr의 video-use 리뷰(2026년 5월 7일)는 이 스킬이 토크 영상 전용에 가깝고 B롤은 기본으로 지원하지 않는다고 평가했고, 가끔 편집하는 정도라면 다빈치 리졸브에서 손으로 하는 편이 간단할 수 있다고 덧붙였습니다.

## 어떤 경로로 시작할까: 6가지 방법의 키·추가 비용·깨지는 지점

Claude Code로 소스를 편집하는 방법은 크게 여섯 가지입니다. 어느 경로든 Claude Code 자체에는 Claude 유료 구독이나 API 사용량이 필요하고, 아래 표의 비용은 그 외에 드는 것입니다.

| 경로 | 하는 일 | Claude 외에 필요한 것 | 깨지는 지점 |
| --- | --- | --- | --- |
| 로컬 Whisper + ffmpeg (Claude Code가 스크립트 작성·실행) | 받아쓰기 기반 컷, 자막, 세로 버전 | 받아쓰기 시간당 비용 없음. Python, ffmpeg 설치 | 패키지 버전 충돌, 단어 경계 오차, 하드 자막 필터 없음(아래 테스트) |
| [video-use](https://github.com/browser-use/video-use) 스킬 | 군말·말실수·무음 제거, 구간별 색보정, 30ms 페이드, 하드 자막, 오버레이, 컷 지점 자체 점검(최대 3회) | ElevenLabs API 키 필수. Scribe 오디오 시간당 $0.22, 무료 등급에 약 4.5시간 포함 | 병합된 로컬 Whisper 옵션 없음. 토크 영상 중심 |
| [auto-editor](https://github.com/WyattBlue/auto-editor) | 소리 크기나 움직임 기준으로 무음 삭제, 편집 프로그램용 타임라인 내보내기 | 무료(Unlicense) | 실수한 테이크를 구분하지 못함(아래 테스트) |
| [ButterCut](https://github.com/barefootford/buttercut) | 로컬 WhisperX와 화면 분석으로 셀렉트·러프컷을 만들어 파이널 컷 프로·프리미어 프로·다빈치 리졸브용 XML로 내보냄 | Ruby, Python, full FFmpeg, WhisperX. 애플 실리콘 맥 중심. 멀티트랙 B롤은 Pro 연 $49 | 마무리는 편집 프로그램에서 해야 함 |
| [ChatCut Claude Code 플러그인](https://www.chatcut.io/claude-code-plugin) | 소스를 ChatCut에 올려 트림, 잡음 제거, 자막, 모션그래픽, 생성 B롤, 보이스오버, 브라우저 타임라인 | ChatCut 월 $25~$160(100~800크레딧), 무료 플랜 표시 없음 | 소스가 외부 서버로 올라감. Claude 사용량과 ChatCut 요금이 따로 듦 |
| 편집 프로그램 MCP(다빈치 리졸브, 프리미어 프로, Palmier Pro) | Claude가 실제 타임라인에서 조립·마커·렌더 | 리졸브는 사실상 스튜디오(유료), 프리미어는 CEP 패널, Palmier Pro는 macOS 26 이상 + 애플 실리콘 | 컷 판단은 하지 않음. 커뮤니티 프로젝트 |

표의 가격과 조건은 2026년 10월 15일 기준 각 프로젝트 페이지와 [ElevenLabs API 요금 페이지](https://elevenlabs.io/pricing/api)를 따른 것입니다.

경로마다 알아 둘 조건은 다음과 같습니다.

- **video-use**: GitHub 별 28,957개(2026년 10월 15일), MIT 라이선스입니다. 저장소를 내려받아 `~/.claude/skills/video-use`에 심볼릭 링크로 연결하고 `uv sync`, `brew install ffmpeg`를 실행한 뒤 `.env`에 `ELEVENLABS_API_KEY`를 넣는 구성입니다. 컷을 자르기 전에 전략을 제안하고 사용자 승인을 기다립니다. 문서(SKILL.md)는 CPU에서 로컬 Whisper를 돌리는 것을 "느리고 군말을 정리해 버린다"는 이유로 피해야 할 방식으로 꼽고, 로컬 Whisper나 Groq를 붙이자는 PR은 2026년 10월 15일 기준 하나도 병합되지 않았습니다(#12, #28, #114는 병합 없이 닫힘, #22, #60, #151, #223은 열려 있음). 설치 안내는 Homebrew 기본 ffmpeg인데, 아래 테스트에서 그 빌드에는 하드 자막 필터가 없었으므로 video-use의 자막 번인이 이 조합에서 동작하는지는 실제로 돌려 봐야 알 수 있습니다.
- **ButterCut**: 라이선스가 PolyForm Noncommercial 1.0.0이지만, 이 도구로 만든 영상의 상업적 사용은 예외로 허용합니다. 윈도우와 리눅스는 우선 지원 대상이 아닙니다.
- **편집 프로그램 MCP**: 가장 큰 커뮤니티 프로젝트인 `samuelgursky/davinci-resolve-mcp`는 README에서 "컷 판단"과 "편집자 대체"를 목표에서 빼고, 결과물을 "첫 조립본(first-pass assembly)"이라고 부릅니다. 무료판 리졸브는 앱 안 브리지 스크립트가 필요하고, 리졸브 21.1부터 Python 스크립팅이 스튜디오 전용이 되었다고 적혀 있습니다. 프리미어용 `hetpatel-11/Adobe_Premiere_Pro_MCP`는 macOS에서만 검증되었고 자막과 효과 조작에 제약이 있습니다. Palmier Pro는 앱이 열려 있을 때 내 컴퓨터의 19789번 포트에 MCP 서버를 띄우고, Claude Code에서는 `claude mcp add --transport http`로 그 주소를 등록해 연결하며, v0.7.6 이후 빌드는 소스가 공개되지 않습니다. 세 프로젝트 모두 Blackmagic이나 Adobe의 공식 제품이 아닙니다. MCP 서버 연결 방법 자체는 [Claude Code MCP 추천: 용도별 첫 서버 선택과 설치 확인](https://blog.laozhang.ai/ko/posts/claude-code-best-mcp-servers)에 있습니다.

상황별로 고르면 이렇습니다.

- **추가 비용 없이 내 컴퓨터에서 끝내고 싶다**: 로컬 Whisper + ffmpeg. 아래 테스트 순서를 그대로 따라 하면 됩니다.
- **무음만 빨리 지우고 프리미어 프로·다빈치 리졸브·파이널 컷 프로에서 마무리한다**: auto-editor의 타임라인 내보내기.
- **말실수까지 알아서 정리하고 자막 스타일과 오버레이까지 맡기고 싶다, 시간당 $0.22는 괜찮다**: video-use.
- **맥에서 러프컷만 받아 편집 프로그램에서 다듬는다**: ButterCut.
- **터미널 설정이 부담스럽고 월 구독과 소스 업로드를 받아들일 수 있다**: ChatCut.
- **이미 리졸브 스튜디오나 프리미어 프로로 작업하며 반복 조립을 줄이고 싶다**: 편집 프로그램 MCP. 컷 선택까지 기대하지는 마세요.

캡컷(CapCut)은 Claude Code가 직접 조작하는 방법이 공개 문서에 나와 있지 않습니다. Claude Code로 만든 러프컷 mp4를 캡컷으로 불러와 마무리하는 식으로 역할을 나누는 편이 현실적입니다.

Claude Code 영상 작업에 쓰이지만 소스를 자르지는 않는 도구도 있습니다. [claude-code-video-toolkit](https://github.com/digitalsamba/claude-code-video-toolkit)은 Remotion 템플릿, TTS 내레이션, 아바타로 새 영상을 만드는 데 초점이 있고, 기존 소스에 대해서는 더빙 교체, 배경음악, 워터마크 제거, 자르기·붙이기·세로 크롭 정도만 합니다. 무음 삭제와 자막 기능은 없습니다. 자막 바·차트·타이틀 같은 오버레이는 [HyperFrames](https://github.com/heygen-com/hyperframes)(Apache-2.0, Node 22 이상)나 Remotion으로 만듭니다. Remotion은 개인, 직원 3명 이하 영리 조직, 비영리 단체는 무료이고 그 밖에는 좌석당 월 $25 또는 렌더당 $0.01(월 최소 $100)의 회사 라이선스가 필요합니다. Heimdex가 지적하듯 컷을 바꾸면 그래픽 타이밍이 깨지므로, 오버레이는 컷을 확정한 뒤에 얹는 것이 순서입니다.

## 로컬 Whisper + ffmpeg로 돌려 본 컷편집: 32.59초가 15.53초로

테스트 클립은 32.59초, 1080p 30fps입니다. 앞에 3초 공백이 있고, 문장 사이에 긴 공백이 있으며, 중간에 "First, we cut out the long pauses. Um, wait, let me say that again."이라고 말을 멈춘 실수 테이크 뒤에 같은 문장을 다시 말한 테이크가 이어집니다. 목표는 앞 공백과 실수 테이크, 긴 공백을 지우고 자막과 세로 버전을 만드는 것이었습니다.

| 단계 | 결과 |
| --- | --- |
| 받아쓰기(faster-whisper 1.2.1, `base.en`, CPU int8) | 57단어, 3.0초(모델 로딩 포함, 첫 실행 때 약 141MB 모델 다운로드는 제외) |
| Claude Code의 편집 결정 | 4개 구간 유지, 실수 테이크 전체 삭제 |
| 자르기·붙이기 렌더(ffmpeg 필터 한 번) | 약 1.5초, 결과 15.53초 |
| 자막 파일 | 큐 18개, 57단어 중 43단어 유지(삭제된 14단어가 정확히 실수 테이크) |
| 하드 자막 번인 / 세로 1080×1920 | 1.67초 / 1.39초 |
| 검증 | 결과물을 다시 받아써서 대본 전체가 남았고 실수 테이크가 사라진 것을 확인 |

![32.59초 원본에서 앞 공백, 실수 테이크, 긴 공백을 지우고 네 구간만 남겨 15.53초가 된 타임라인과, 실수 테이크가 남은 auto-editor 21.31초 결과 비교](https://blog.laozhang.ai/posts/ko/claude-code-video-editing/img/cut-timeline-test.webp)

### 1단계: faster-whisper로 단어별 시간이 붙은 받아쓰기 만들기

```bash
python3 -m venv venv
./venv/bin/pip install faster-whisper "av<19"
./venv/bin/python transcribe.py raw/talk.mp4 base.en
```

`"av<19"`를 붙이는 이유는 아래 '막힌 3곳'의 첫 번째 오류 때문입니다. `transcribe.py`는 단어마다 시작·끝 시간을 `words.json`으로 저장합니다. API 키가 필요 없고 모델은 첫 실행 때 내려받습니다.

```python
"""Step 1: word-level transcript of the raw clip (local, no API key)."""
import json
import sys
import time

from faster_whisper import WhisperModel

src = sys.argv[1]
model_name = sys.argv[2] if len(sys.argv) > 2 else "base.en"

t0 = time.time()
model = WhisperModel(model_name, device="cpu", compute_type="int8")
segments, info = model.transcribe(src, word_timestamps=True, vad_filter=False)
words = []
for seg in segments:
    for w in seg.words:
        words.append({"start": round(w.start, 2), "end": round(w.end, 2), "word": w.word.strip()})
json.dump(words, open("words.json", "w"), indent=1)
print(f"model={model_name} words={len(words)} audio={info.duration:.1f}s elapsed={time.time()-t0:.1f}s")
```

한국어 소스에는 `base.en`을 그대로 쓰면 안 됩니다. [OpenAI Whisper README](https://github.com/openai/whisper)에 따르면 이름이 `.en`으로 끝나는 모델(`tiny.en`, `base.en`, `small.en`, `medium.en`)은 영어 전용입니다. 한국어라면 `small`, `medium`, `large` 같은 다국어 모델을 고르고 `model.transcribe()`에 `language="ko"`를 넘기면 됩니다. 어느 크기가 한국어 토크에 충분한지는 이 테스트로 알 수 없으니, 1~2분짜리 클립으로 먼저 받아쓰기 품질을 확인한 뒤 전체를 돌리세요.

### 2단계: Claude Code가 words.json을 읽고 남길 구간을 정하기

여기가 Claude Code가 실제로 판단하는 단계입니다. 요청은 예를 들어 이렇게 할 수 있습니다.

```text
words.json은 raw/talk.mp4의 단어별 받아쓰기입니다. 같은 문장을 다시 말한 부분은
마지막 테이크만 남기고, 앞뒤 무음과 문장 사이 긴 공백을 줄여서 남길 구간을
edl.json에 [{"start": 초, "end": 초}] 형식으로 써 주세요.
자르기 전에 어떤 구간을 버리는지 먼저 보여 주세요.
```

테스트에서 Claude Code는 받아쓰기를 읽고 "First, we cut out the long pauses"가 두 번 나온다는 것을 근거로 앞쪽 테이크 전체를 버렸습니다. 최종 `edl.json`은 네 구간입니다.

```json
[{"start": 2.92, "end": 6.51}, {"start": 14.83, "end": 18.31}, {"start": 20.66, "end": 24.83}, {"start": 25.89, "end": 30.14}]
```

처음 버전은 Whisper 시간에 약간의 여유만 더해 15.83초짜리 결과를 냈지만 마지막 단어 끝이 잘렸습니다. 위 숫자는 그 문제를 고친 뒤의 값이며, 고친 방법은 '막힌 3곳'의 두 번째 항목에 있습니다.

### 3단계: render.py로 자르고 붙인 뒤 자막 파일 만들기

```bash
python3 render.py raw/talk.mp4
```

`render.py`는 구간마다 `trim`/`atrim`으로 자르고, 끊기는 소리를 막으려고 오디오에 30ms 페이드를 넣은 뒤 `concat`으로 붙이는 필터 그래프를 한 번에 실행합니다. 자르기와 붙이기만 할 때는 Homebrew 기본 ffmpeg로 충분했습니다. 이어서 단어 시간을 새 타임라인으로 옮겨 2~3단어씩 묶은 `final.srt`를 씁니다.

```python
"""Step 3: turn an edit decision list (keep ranges) into final.mp4 + subtitles.

edl.json: [{"start": s, "end": e}, ...] on the source timeline.
Writes final.mp4 (concat with 30 ms audio fades), final.srt (remapped word timings).
"""
import json
import subprocess
import sys

src = sys.argv[1]
edl = json.load(open("edl.json"))
words = json.load(open("words.json"))
FADE = 0.03

# 1) cut + concat in one ffmpeg filter graph
parts, labels = [], []
for i, k in enumerate(edl):
    d = k["end"] - k["start"]
    parts.append(f"[0:v]trim={k['start']}:{k['end']},setpts=PTS-STARTPTS[v{i}]")
    parts.append(
        f"[0:a]atrim={k['start']}:{k['end']},asetpts=PTS-STARTPTS,"
        f"afade=t=in:d={FADE},afade=t=out:st={d - FADE:.3f}:d={FADE}[a{i}]"
    )
    labels.append(f"[v{i}][a{i}]")
graph = ";".join(parts) + ";" + "".join(labels) + f"concat=n={len(edl)}:v=1:a=1[v][a]"
subprocess.run(
    ["ffmpeg", "-v", "error", "-y", "-i", src, "-filter_complex", graph, "-map", "[v]", "-map", "[a]",
     "-c:v", "libx264", "-crf", "20", "-preset", "veryfast", "-c:a", "aac", "-b:a", "160k", "final.mp4"],
    check=True,
)

# 2) remap word times to the new timeline and group up to 3 words per caption (fewer at punctuation)
# a word is kept if it overlaps a keep range; its times are clamped into that range
# (Whisper word boundaries drift by a few hundred ms, so exact containment drops words)
kept = []
for w in words:
    offset = 0.0
    for k in edl:
        overlap = min(w["end"], k["end"]) - max(w["start"], k["start"])
        if overlap > 0:
            s = max(w["start"], k["start"]) - k["start"] + offset
            e = min(w["end"], k["end"]) - k["start"] + offset
            kept.append({"start": s, "end": e, "word": w["word"]})
            break
        offset += k["end"] - k["start"]

def ts(t):
    h, rem = divmod(t, 3600)
    m, s = divmod(rem, 60)
    return f"{int(h):02d}:{int(m):02d}:{int(s):02d},{int(round((s % 1) * 1000)):03d}"

cues, chunk = [], []
for w in kept:
    chunk.append(w)
    if len(chunk) == 3 or w["word"].endswith((".", ",", "?", "!")):
        cues.append(chunk)
        chunk = []
if chunk:
    cues.append(chunk)
with open("final.srt", "w") as f:
    for n, c in enumerate(cues, 1):
        text = " ".join(x["word"] for x in c)
        f.write(f"{n}\n{ts(c[0]['start'])} --> {ts(c[-1]['end'])}\n{text}\n\n")
print(f"segments={len(edl)} kept_words={len(kept)}/{len(words)} cues={len(cues)}")
```

스크립트 자체의 버그도 하나 있었습니다. 첫 버전은 시작과 끝이 모두 유지 구간 안에 들어간 단어만 자막에 남겼는데, 컷 경계를 무음 쪽으로 옮기자 "Hi," 같은 단어가 빠져 57단어 중 40단어만 남았습니다. 구간과 조금이라도 겹치는 단어를 남기고 시간을 구간 안으로 잘라 넣는 방식(위 코드)으로 바꾸자 43단어가 됐습니다.

### 4단계: 소프트 자막, 하드 자막(번인), 세로 9:16 버전

자막을 켜고 끌 수 있는 소프트 자막은 기본 ffmpeg로 넣을 수 있습니다.

```bash
ffmpeg -i final.mp4 -i final.srt -map 0 -map 1 -c copy -c:s mov_text -metadata:s:s:0 language=eng final_softsubs.mp4
```

화면에 자막을 새기는 하드 자막과 세로 버전은 `ffmpeg-full`의 바이너리로 실행했습니다(이유는 '막힌 3곳'의 세 번째 항목).

```bash
/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg -i final.mp4 \
  -vf "subtitles=final.srt:force_style='FontName=Helvetica,FontSize=22,Outline=2'" \
  -c:v libx264 -crf 20 -preset veryfast -c:a copy final_burned.mp4

/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg -i final.mp4 \
  -vf "crop=ih*9/16:ih,scale=1080:1920,subtitles=final.srt:force_style='FontName=Helvetica,FontSize=14,MarginV=60,Outline=2'" \
  -c:v libx264 -crf 20 -preset veryfast -c:a copy final_vertical.mp4
```

결과 영상 1.2초 지점의 프레임을 뽑아 보니 테스트 화면에 원본 타임코드 00:00:03.800과 자막 "this is a"가 함께 보여, 컷 위치와 자막이 맞게 옮겨졌음을 확인할 수 있었습니다. 세로 버전은 화면 가운데를 잘라 내는 방식이라 화자가 중앙에 있을 때만 맞습니다. 움직이는 화자를 따라가는 얼굴 추적은 테스트하지 않았습니다.

## 테스트에서 막힌 3곳: 오류 메시지와 해결 명령

### faster-whisper `metadata_errors` 오류: PyAV를 19 미만으로 고정

`pip install faster-whisper`만 실행하면 faster-whisper 1.2.1(2026년 10월 15일 기준 PyPI 최신)과 함께 PyAV 19.0.1이 설치되었고, `model.transcribe()`에서 다음 오류가 났습니다.

```text
TypeError: open() got an unexpected keyword argument 'metadata_errors'
```

PyAV 19.0.0은 2026년 9월 29일, 19.0.1은 10월 3일에 나왔습니다. `pip install faster-whisper "av<19"`로 PyAV 18.1.0을 설치하자 정상 동작했습니다. 원인은 오류 추적 내용으로 미루어 본 것이고, 이후 faster-whisper 업데이트로 해결될 수 있으니 이 오류가 안 나면 고정하지 않아도 됩니다.

### Whisper 시간대로 자르면 끝음절이 잘림: 무음 경계에 맞추기

Whisper는 마지막 단어 "platforms."가 29.50초에 끝난다고 표시했지만, 실제 소리는 30.04초까지 이어졌습니다. Whisper 시간대로 자른 결과물을 다시 받아쓰자 "platform."으로 들렸습니다. 이 샘플에서 Whisper의 단어 경계는 최대 약 0.5초 어긋났습니다.

해결은 ffmpeg로 실제 무음 구간을 찾아 컷 경계를 그쪽에 맞추는 것입니다.

```bash
ffmpeg -i raw/talk.mp4 -af silencedetect=noise=-40dB:d=0.3 -f null -
```

출력되는 `silence_start`/`silence_end` 값을 Claude Code에 함께 주고 "각 구간의 시작과 끝을 가장 가까운 무음 경계로 옮기고 0.1초 여유를 두라"고 요청하면 됩니다. 이렇게 고친 구간이 2단계의 최종 `edl.json`입니다. 다른 곳에서도 같은 문제가 보고되어 있습니다. 스페인 Aducti(2026년 9월 1일)는 Whisper가 앞 무음을 구간 첫 단어에 포함해 약 0.5초의 무음이 남는다고 적었고, video-use 문서는 Scribe의 타임스탬프도 50~100ms 흔들리므로 컷에 30~200ms 여유를 두고 400ms 이상의 무음에서 자르라고 권합니다.

### `No such filter: 'subtitles'`: 기본 ffmpeg엔 하드 자막 필터 없음

Homebrew의 `ffmpeg`(8.0.1_2와 현재 9.0.2 모두)에는 `subtitles`, `ass`, `drawtext` 필터가 들어 있지 않습니다. 하드 자막을 넣으려 하면 이런 오류가 납니다.

```text
-vf subtitles=final.srt           → No option name near 'final.srt' / Error parsing filterchain
-vf subtitles=filename=final.srt  → No such filter: 'subtitles'
```

`ffmpeg -filters | grep subtitles`로 확인하면 아무것도 나오지 않습니다. 기본 `ffmpeg` 포뮬러에는 자막 렌더링에 필요한 libass와 freetype이 없고, `ffmpeg-full`에는 libass, freetype, fontconfig, harfbuzz와 whisper.cpp 등이 포함됩니다. `brew install ffmpeg-full`은 2분 05초 걸렸고, 이 포뮬러는 keg-only라서 PATH에 올라가지 않으므로 `/opt/homebrew/opt/ffmpeg-full/bin/ffmpeg`처럼 전체 경로로 실행해야 합니다. 자막을 켜고 끄는 소프트 자막(`-c:s mov_text`)은 기본 ffmpeg로도 됩니다. 리눅스나 윈도우의 ffmpeg 빌드는 구성이 달라 이 결과가 그대로 적용되지 않을 수 있습니다.

`ffmpeg-full` 설치에는 부작용도 있었습니다. 공유 라이브러리 libvpx가 1.15.2에서 1.17.0으로 올라가면서, 업데이트하지 않은 기존 `ffmpeg` 8.0.1_2가 실행되지 않았습니다.

```text
dyld: Library not loaded: /opt/homebrew/opt/libvpx/lib/libvpx.11.dylib
```

`brew upgrade ffmpeg`(9.0.2_1로, 8초)를 실행하자 복구되었고, 이후 `brew linkage --test`에서도 빠진 라이브러리는 없었습니다. 오래된 ffmpeg가 깔려 있다면 `ffmpeg-full` 설치 직후 기본 `ffmpeg`가 실행되는지 한 번 확인하세요.

## auto-editor 비교: 무음은 지웠지만 실수 테이크는 남았습니다

같은 클립을 auto-editor 31.7.2(Homebrew)로 잘라 봤습니다.

```bash
brew install auto-editor
auto-editor raw/talk.mp4 --margin 0.2s -o ae31_cut.mp4 --no-open
```

3.9초 만에 21.31초짜리 결과가 나왔습니다. 무음은 지웠지만 실수 테이크는 그대로 남았습니다. 타임라인(FCPXML)으로 내보내 보면 8.8초에서 시작하는 152프레임짜리 클립이 바로 그 실수 테이크입니다. auto-editor는 소리 크기나 움직임으로만 자르기 때문에, 크게 말한 테이크가 실수라는 사실은 알 수 없습니다. 그 판단에는 받아쓰기를 읽는 단계가 필요하고, 이 부분이 Claude Code를 쓰는 이유입니다.

대신 auto-editor는 `--export premiere`, `--export resolve`, `--export final-cut-pro`, `--export shotcut`, `--export kdenlive`로 원본 소스를 가리키는 타임라인 파일을 만들어 줍니다. 무음 정리만 자동으로 하고 나머지는 프리미어 프로나 다빈치 리졸브에서 손보는 방식이라면 이것으로 충분합니다. `pip`에 있는 auto-editor는 29.3.1(2025년 11월 4일)에서 멈춰 있고 README도 pip 배포를 중단했다고 밝히므로, `brew install auto-editor`나 GitHub 릴리스 바이너리를 쓰는 편이 맞습니다.

Python 없이 받아쓰기만 하는 방법도 두 가지 돌려 봤습니다.

- **auto-editor `whisper` 하위 명령**: `auto-editor whisper <파일> <ggml-모델> -f srt --prompt "Claude Code" -o out.srt` 형식이고, 모델 파일(ggml-base.en.bin, 148MB)은 huggingface.co/ggerganov/whisper.cpp에서 받습니다. 12.2초가 걸렸고 `--prompt` 덕분에 "Claude Code"를 정확히 적었습니다. 하지만 자막마다 끝 시간이 시작 시간 + 4~5초로 기계적으로 찍혀 있어 컷 지점으로는 쓸 수 없습니다.
- **ffmpeg-full의 `whisper` 필터**: `-af "whisper=model=…:language=en:destination=out.srt:format=srt"` 형식으로 12.95초가 걸렸습니다. 프롬프트 없이 돌리자 "Claude."와 "code."를 서로 다른 자막으로 나눴고, SRT 번호가 1이 아니라 0부터 시작했습니다.

고유명사는 더 큰 모델이라고 해서 맞게 적는다는 보장이 없습니다. 같은 오디오에서 faster-whisper `small.en`은 "Claude Code"를 "clog code"로 들었고 `base.en`은 맞게 들었습니다. 샘플 하나의 결과라 모델 우열을 말해 주지는 않지만, 제품명·인명·채널명이 많은 영상이라면 프롬프트를 주거나 자막을 꼭 다시 읽어야 한다는 뜻입니다.

## 게시 전 사람이 확인할 7가지

Claude Code가 만든 결과물은 첫 컷편집입니다. 올리기 전에 다음을 확인하세요.

1. **컷 경계의 끝음절**: 결과물을 다시 받아쓰거나 각 컷 앞뒤 1초를 들어 봅니다. 테스트의 "platforms" → "platform" 같은 잘림은 영상만 훑어서는 놓치기 쉽습니다.
2. **남긴 테이크가 맞는지**: Habr의 video-use 리뷰는 자체 점검이 끊김, 팝 노이즈, 가려진 자막 같은 기술적 문제는 잡지만 잘못된 테이크를 남긴 것 같은 의미상 실수는 잡지 못한다고 지적했습니다. 받아쓰기상 같은 문장이라도 표정이나 말투가 나은 쪽은 사람이 골라야 합니다.
3. **고유명사 자막**: 제품명과 이름을 자막에서 찾아 읽습니다. ElevenLabs Scribe는 키워드 프롬프트를 시간당 $0.05에 추가할 수 있고, Whisper 계열은 프롬프트로 단어를 알려 줄 수 있습니다.
4. **자막은 마지막에, 그래픽은 컷 확정 뒤에**: video-use 문서는 오버레이를 나중에 얹으면 자막을 가리므로 자막을 마지막에 입히라고 하고, 글꼴 문제는 오류 없이 조용히 실패한다고 경고합니다.
5. **한글 글꼴**: 테스트는 영어 자막에 Helvetica(macOS 글꼴)를 썼습니다. 한글 자막을 번인할 때는 한글을 지원하는 글꼴 이름을 `FontName`에 지정하고, 프레임을 몇 장 뽑아 글자가 제대로 나오는지 확인하세요. 한글 번인은 이번 테스트 범위 밖입니다.
6. **세로 구도**: 가운데 크롭은 화자가 중앙에 있을 때만 맞습니다. 숏폼으로 올리기 전에 처음·중간·끝 프레임을 확인합니다.
7. **업로드 형식**: ffmpeg `whisper` 필터처럼 SRT 번호를 0부터 매기는 도구도 있으니, 업로드가 거부되면 1부터 다시 매깁니다. 소프트 자막 트랙은 플랫폼에 따라 무시될 수 있으니 자막 파일을 따로 올리는 편이 확실합니다. Aducti는 아이폰이 HEVC 영상의 `hev1` 태그를 거부해 `hvc1` 태그가 필요하다고 적었고, Fyve는 긴 영상에서 자막이 점점 밀리는 문제를 지적했습니다.

한 번 흐름이 잡히면 어디서 자를지, 자막을 어느 높이에 둘지, 줌을 몇 번까지 넣을지 같은 규칙을 스킬 파일로 남겨 두면 다음 영상부터 같은 설명을 반복하지 않아도 됩니다. Aducti의 편집 스킬도 이런 규칙을 짧은 SKILL.md에 고정해 두는 방식입니다. 스킬을 만드는 방법은 [Claude Code Hooks·Skills·슬래시 명령어 차이와 사용 예제](https://blog.laozhang.ai/ko/posts/claude-code-hooks-slash-commands-skills)를 참고하세요.

## Claude Code 영상 편집 질문: 무료 여부, 캡컷, 한국어 자막

### Claude Code로 영상 편집을 하면 무료인가요?

편집 도구는 무료로 쓸 수 있지만 Claude Code 자체는 무료가 아닙니다. Claude 유료 구독이나 API 사용량이 필요하고, 받아쓰기를 로컬 Whisper로 하면 시간당 받아쓰기 비용이 들지 않습니다. video-use는 ElevenLabs 무료 등급(약 4.5시간)을 넘으면 오디오 시간당 $0.22가 추가되고, ChatCut은 Claude 사용량과 별도로 월 $25부터 요금이 듭니다. Claude Code 설치는 [Claude Code 설치 방법: 전 플랫폼 완벽 설정 가이드 (2026)](https://blog.laozhang.ai/ko/posts/claude-code-install)에 정리되어 있습니다.

### 캡컷이나 프리미어 프로와 같이 쓸 수 있나요?

프리미어 프로, 다빈치 리졸브, 파이널 컷 프로는 auto-editor의 `--export` 옵션이나 ButterCut의 XML로 러프컷을 넘겨받아 마무리할 수 있습니다. 편집 프로그램을 Claude가 직접 조작하는 커뮤니티 MCP 서버도 있지만 결과물은 첫 조립본 수준입니다. 캡컷은 Claude Code가 직접 조작하는 방법이 공개 문서에 없으므로, 완성된 mp4를 캡컷으로 가져가 다듬는 방식으로 나눠 쓰세요.

### 한국어 영상도 같은 방법으로 되나요?

흐름은 같지만 모델을 바꿔야 합니다. `.en`으로 끝나는 Whisper 모델은 영어 전용이므로 다국어 모델과 `language="ko"`를 쓰고, 한글 자막을 번인할 때는 한글 글꼴을 지정해야 합니다. 테스트는 영어 합성 음성으로만 이뤄졌기 때문에 한국어 받아쓰기 정확도나 띄어쓰기 품질은 짧은 클립으로 직접 확인한 뒤 전체 소스에 적용하는 것이 안전합니다.

### 1시간짜리 라이브 다시보기도 맡길 수 있나요?

받아쓰기 기반이라면 가능하지만 사용량과 확인 작업이 늘어납니다. 단어별 JSON을 그대로 읽히면 1시간에 약 12.6만 입력 토큰, 한 줄 형식으로 줄이면 약 4.5만 토큰 수준이므로, 받아쓰기를 압축된 형식으로 넘기고 하이라이트 후보만 고르게 한 뒤 사람이 구간을 확정하는 편이 사용 한도를 아낍니다. 긴 영상은 자막 밀림도 생길 수 있어 앞·중간·끝 자막 싱크를 따로 봐야 합니다.

### 영상 편집 스킬은 무엇을 설치하면 되나요?

말실수까지 자동으로 정리하는 완성형 스킬을 원하면 video-use(ElevenLabs 키 필요), 로컬에서 러프컷을 만들어 편집 프로그램으로 넘기려면 ButterCut이 후보입니다. 둘 다 부담스럽다면 별도 스킬 없이 위 테스트처럼 Claude Code에게 Whisper와 ffmpeg 스크립트를 쓰게 한 뒤, 잘 된 규칙을 직접 스킬로 저장해도 됩니다. 작업별 스킬 고르는 기준은 [Claude Code 스킬 추천: 작업별 첫 선택과 설치·확인 방법](https://blog.laozhang.ai/ko/posts/claude-code-best-skills)에 있습니다.

## 참고 자료

이 글이 링크한 외부 페이지를 본문에 나온 순서대로 정리했습니다. 마지막 업데이트: 2026-10-15.

- [Anthropic Claude 비전 문서](https://platform.claude.com/docs/en/build-with-claude/vision) (platform.claude.com)
- [Claude Code 도구 레퍼런스](https://code.claude.com/docs/en/tools-reference) (code.claude.com)
- [video-use](https://github.com/browser-use/video-use) (github.com)
- [auto-editor](https://github.com/WyattBlue/auto-editor) (github.com)
- [ButterCut](https://github.com/barefootford/buttercut) (github.com)
- [ChatCut Claude Code 플러그인](https://www.chatcut.io/claude-code-plugin) (chatcut.io)
- [ElevenLabs API 요금 페이지](https://elevenlabs.io/pricing/api) (elevenlabs.io)
- [claude-code-video-toolkit](https://github.com/digitalsamba/claude-code-video-toolkit) (github.com)
- [HyperFrames](https://github.com/heygen-com/hyperframes) (github.com)
- [OpenAI Whisper README](https://github.com/openai/whisper) (github.com)
