{"id":51138679,"url":"https://github.com/kwakseongjae/dawn-cut","last_synced_at":"2026-06-25T20:30:34.107Z","repository":{"id":363779523,"uuid":"1256742259","full_name":"kwakseongjae/dawn-cut","owner":"kwakseongjae","description":"Open-source, 100% local AI video editor — text-based editing, Korean auto-subtitles, auto silence removal, color/reframe/overlays, one-click style packs. No cloud, no account, no watermark.","archived":false,"fork":false,"pushed_at":"2026-06-10T10:47:24.000Z","size":7124,"stargazers_count":0,"open_issues_count":15,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-10T11:06:54.435Z","etag":null,"topics":["electron","ffmpeg","korean","llama-cpp","local-first","mcp","open-source","react","subtitles","typescript","video-editor","whisper"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kwakseongjae.png","metadata":{"files":{"readme":"README.ko.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-02T03:47:49.000Z","updated_at":"2026-06-10T10:47:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kwakseongjae/dawn-cut","commit_stats":null,"previous_names":["kwakseongjae/dawn-cut"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/kwakseongjae/dawn-cut","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kwakseongjae%2Fdawn-cut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kwakseongjae%2Fdawn-cut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kwakseongjae%2Fdawn-cut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kwakseongjae%2Fdawn-cut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kwakseongjae","download_url":"https://codeload.github.com/kwakseongjae/dawn-cut/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kwakseongjae%2Fdawn-cut/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34792208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-25T02:00:05.521Z","response_time":101,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electron","ffmpeg","korean","llama-cpp","local-first","mcp","open-source","react","subtitles","typescript","video-editor","whisper"],"created_at":"2026-06-25T20:30:33.026Z","updated_at":"2026-06-25T20:30:34.101Z","avatar_url":"https://github.com/kwakseongjae.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# dawn-cut\n\n### 내 영상이 이 컴퓨터를 절대 떠나지 않는 오픈소스 영상 편집기.\n\n문서 편집하듯 영상을 편집하세요 — **자동 자막, 텍스트 기반 컷편집, 자동 무음 제거까지\n100% 로컬.** 클라우드 없음, 계정 없음, 워터마크 없음, 구독 없음.\n\n\u003cp\u003e\n  \u003cimg alt=\"100% local\" src=\"https://img.shields.io/badge/100%25-local-2ea44f\"\u003e\n  \u003cimg alt=\"no watermark\" src=\"https://img.shields.io/badge/no-watermark-2ea44f\"\u003e\n  \u003cimg alt=\"no subscription\" src=\"https://img.shields.io/badge/no-subscription-2ea44f\"\u003e\n  \u003cimg alt=\"no account\" src=\"https://img.shields.io/badge/no-account-2ea44f\"\u003e\n  \u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/license-MIT-blue\"\u003e\n\u003c/p\u003e\n\n[English](README.md) · **한국어**\n\n\u003e **상태: v0.1.** 결정적(deterministic) 편집 코어는 실제로 동작하고, 테스트되어 있으며,\n\u003e 바로 쓸 수 있습니다 — 텍스트 기반 컷, 무음 제거, 한국어 자동 자막, **1탭 적응형 자동\n\u003e 보정**, **저신뢰 자막 검수·교정**, 색보정, 9:16/1:1 리프레이밍, 이미지/스티커/GIF 오버레이,\n\u003e 1클릭 스타일 팩, TTS, SRT/챕터 내보내기까지 전부 100% 로컬입니다. 자연어 AI 편집과 헤드리스\n\u003e **MCP** 에이전트 서버도 로컬에서 동작하지만, **\"실험적(experimental)\"으로 표기**해서 냅니다 —\n\u003e 모델을 한 번 받아야 하고 아직 다듬는 중이기 때문입니다. 모든 것을 정직하게 라벨링합니다:\n\u003e [지금 되는 것](#지금-되는-것) · [실험적 기능](#실험적-기능-opt-in) · [로드맵](#로드맵).\n\n---\n\n## 데모\n\n\u003c!-- TODO(release): 라이선스-클린 히어로 GIF(원본 → 자막+색보정 컷)를 assets/hero.gif에 추가 후 복원 --\u003e\n_(첫 릴리스와 함께 데모 GIF 추가 예정 — `docs/PRODUCTION.md` 참고)_\n\n\u003e 실제 `whisper.cpp` + FFmpeg로 끝까지 돌린 재현 가능한 결과가 [`demo-output/`](demo-output/README.md)에\n\u003e 있습니다: 23.6초 영어 내레이션 클립을 전사 → 텍스트 편집 → 무음 제거(17.3초) → 끌 수 있는\n\u003e 소프트 자막 트랙 + SRT + 재사용 가능한 `.dawn` 프로젝트로 내보냅니다. 재생성:\n\u003e `pnpm demo:assets \u0026\u0026 pnpm demo:run \u0026\u0026 pnpm demo:ui`.\n\n---\n\n## 왜 dawn-cut인가\n\n흔한 \"AI 영상 편집기\"는 당신이 정말 원하는 두 가지 — *프라이버시*와 *AI 도움* — 중 **하나만**\n고르게 만듭니다. 클라우드 도구는 당신의 영상을 가져가고, 로컬 도구는 똑똑하지 못하죠.\ndawn-cut은 둘 중 하나를 포기하지 않아도 되도록 만들었습니다.\n\n| | dawn-cut | CapCut | Vrew | Descript | OpenCut |\n|---|---|---|---|---|---|\n| 100% 로컬 실행 | **예** | 아니오(클라우드) | 아니오(클라우드 STT) | 아니오(클라우드) | 예(브라우저) |\n| 계정/워터마크/구독 없음 | **예** | 아니오 | 무료 제한 | 크레딧/제한 | 예 |\n| 단어 단위 STT + 텍스트 기반 편집 | **예** | 아니오 | 부분적 | 예 | 아니오 |\n| 자동 자막(한국어 포함) | **예(로컬)** | 클라우드 | 클라우드 | 클라우드 | 아니오 |\n| 결정적·검증 가능한 편집 코어(EDL + 불변식) | **예** | 아니오 | 아니오 | 아니오 | 아니오 |\n| 오픈소스 | **예(MIT)** | 아니오 | 아니오 | 아니오 | 예(MIT) |\n\n- **vs CapCut** — 영상이 노트북을 떠나지 않습니다. 텔레메트리 없음, 당신의 얼굴·목소리에 대한\n  라이선스를 주장하는 약관 없음, 내보내기 워터마크 없음.\n- **vs Vrew** — 비슷한 수준의 한국어 자동 자막(whisper `large-v3-turbo`)을 로컬·무제한·무료로.\n  whisper 토큰에서 한국어 *어절*(단어+조사)을 무손실로 재조립합니다 —\n  [`whisper.ts`](packages/core/src/whisper.ts) 참고.\n- **vs Descript** — \"문장을 지우면 영상이 잘리는\" 같은 텍스트 기반 편집을, 클라우드·크레딧·업로드\n  없이.\n- **vs OpenCut** — OpenCut이 범용 수동 타임라인을 차지했다면, dawn-cut은 그것이 남긴 빈자리\n  — **단어 단위 STT, 텍스트 기반 편집, 그리고 기계가 운전할 수 있는 결정적 편집 코어** — 즉\n  에이전트 편집의 토대를 가져갑니다.\n\n---\n\n## 지금 되는 것\n\n정직한 목록 — 아래 항목은 모두 [`packages/core`](packages/core)에 구현되어 단위/속성 테스트로\n검증되거나, Electron UI에 실제로 연결되어 있습니다.\n\n- **단어 단위 전사** — `whisper.cpp`(MIT, 로컬)가 단어별 타임스탬프를 만들고, 한국어 *어절*을\n  무손실로 재조립합니다(글자 정확도 검증, mojibake 0).\n- **텍스트 기반 편집** — 단어 범위를 지우면 해당 영상이 잘리고 빈틈없이 당겨집니다\n  (`deleteWordRange`, `cutSourceRange`).\n- **자동 무음 제거** — 무음 구간을 감지해 여유(padding)를 두고 잘라냅니다(`removeSilences`).\n- **말버릇 감지** — 보수적인 한국어 말버릇 사전, 정확 일치만(`detectFillers`).\n- **자막 정확도 검수·교정** — whisper 토큰 확률에서 신뢰도가 낮은(오인식 가능성 높은) *어절*을\n  골라(`lowConfidenceWords`) 대본에서 빨갛게 표시하고, 그 어절들 사이를 점프하며, 더블클릭으로\n  바로 고칠 수 있습니다. 교정 내용은 cue/SRT/자막 번인에 자동 반영되고 감사로그에 남습니다\n  (`correctWord` verb).\n- **1탭 적응형 자동 보정** — 실제 영상을 분석(FFmpeg `signalstats`: 밝기/대비/채도)해 *계산된*\n  색보정을 적용합니다 — 어두우면 밝히고, 둔하면 화사하게, 과보정은 절대 하지 않습니다\n  (`analyzeVideo` → 순수 `autoEnhanceParams` → `applyAutoEnhance`; 길이 불변, 정확한 수치를\n  EDL에 기록).\n- **자동 자막** — 살아있는 단어를 프로그램 시간 기준 cue로 묶고, 문장 끝/컷/글자수에서 끊으며,\n  단어별 **reveal / karaoke** 애니메이션 + **SRT** 내보내기(`transcriptToCues`, `captionFrames`,\n  `formatSrt`).\n- **자동 챕터** — 대본에서 룰 기반으로 유튜브 `M:SS 제목` 챕터 목록 생성(`extractChapters`,\n  `formatChapters`).\n- **내 사전(고유명사 치환)** — 대본 전체에 결정적 용어 치환(`applyGlossary`).\n- **색보정** — 6종 프리셋(warm / cool / punch / cinematic / flat / vivid)을 강도(intensity)로\n  가중, command bus로 적용 후 FFmpeg `eq`/`curves`로 렌더(`applyColorgrade`, `COLOR_PRESETS`).\n- **9:16 / 1:1 리프레이밍** — 가로 영상을 오버레이 좌표까지 맞춘 중앙 크롭으로 세로 쇼츠/정사각\n  으로(`cropForAspect`, `renderEdl({ reframe })`).\n- **이미지 / 스티커 / GIF 오버레이** — 위치·크기·투명도·z순서·회전·블렌드 모드·다중 키프레임\n  모션 경로를 FFmpeg overlay 필터로 **출력 영상에 실제 합성**\n  ([`overlay.ts`](packages/core/src/overlay.ts), [`draw.ts`](packages/core/src/draw.ts),\n  `renderEdl`).\n- **1클릭 스타일 팩** — 6종 장르 프리셋(viral-punch, mukbang-sizzle, beauty-glow, golden-hour,\n  city-night, talk-clean)을 *plan*(`EditCommand[]` 묶음)으로 표현 → GUI·LLM 플래너·MCP가 모두\n  공유(`STYLE_PACKS`, `templates.ts`).\n- **TTS 보이스오버** — 내레이션 합성(macOS `say`) 후 익스포트에 믹스.\n- **결정적 EDL 내보내기** — 타임라인이 Export Decision List로 컴파일되고 FFmpeg 사이드카가\n  렌더(`timelineToEdl`).\n- **대본 ↔ 타임라인 동기화** — 단어와 프로그램 시간의 증명 가능한 양방향 매핑(`wordToProgram`,\n  `programToWord`).\n- **프로젝트 저장 / 열기** — 버전 관리되는 `.dawn` JSON, 전체 undo/redo\n  ([`history.ts`](packages/core/src/history.ts)).\n- **Electron 데스크톱 앱** — 미디어 가져오기, 전사, 텍스트로 편집, 스크럽, 라이브 자막\n  미리보기, 내보내기.\n\n### 분위기가 아니라 데이터 계약 위에\n\n편집 코어가 해자입니다. 이것은 **순수 TypeScript**라 `electron`, `fs`, `child_process`, `path`를\nimport할 수 없습니다(`dependency-cruiser`로 강제). 모든 모델은 검증된 불변식의 지배를 받습니다:\n\n- **시간은 정수 마이크로초(µs)**, 구간은 반열린 `[start, end)`.\n- `validateSync`가 대본↔타임라인 왕복을 증명(SYNC-INV).\n- `validateEdl`이 내보내기 목록의 연속성·총길이 정확성을 증명(EDL-INV).\n- `validateCues`가 자막의 순차성·비중첩·범위를 증명(SUB-INV).\n- 명령은 `{ before, after, removedProgramUs }`를 반환하는 **순수 함수** → 모든 편집이 undo·replay\n  가능.\n\n결정성·검증·undo·헤드리스 실행 — 이 속성들이 바로 AI 편집 에이전트가 필요로 하는 비기능 요구사항\n입니다.\n\n---\n\n## 실험적 기능 (opt-in)\n\n아래는 **지금도 로컬에서 끝까지 동작**하지만, 모델을 한 번 받아야 하거나 알려진 한계가 있어\n\"실험적\"으로 표기합니다. 목업이 아니라 진짜이고, 다만 다듬는 중입니다. 의도적으로 켜세요 —\n위의 코어는 절대 이들에 의존하지 않습니다.\n\n- **자연어 편집(로컬 LLM 플래너)** — *\"말버릇 빼고 시네마틱하게\"* 라고 입력하면 로컬 `llama.cpp`\n  플래너(기본 **Qwen2.5-1.5B**, Apache-2.0)가 **검증된 `EditCommand` plan**을 만들고, 적용 전에\n  dry-run diff로 미리보기합니다. 문법 제약 디코딩(GBNF)으로 스키마를 벗어나지 않게 하며, 모델이\n  없으면 결정적 룰 플래너로 폴백합니다. 설치: `pnpm setup:llm`.\n  _주의:_ 모델 다운로드 필요, 계획 품질은 1.5B 모델 한계에 묶임, CI는 룰 경로만 검증(LLM 경로는\n  수동 확인).\n- **MCP 에이전트 서버** — 헤드리스 [Model Context Protocol](https://modelcontextprotocol.io)\n  서버(`@dawn-cut/mcp`)로 외부 에이전트(Claude Desktop / Cursor)가 `.dawn` 프로젝트 위에서 **같은**\n  command bus를 구동합니다: `open_project → command_manifest → plan → dry_run → apply →\n  save_project → render`(9:16/1:1 리프레이밍 포함). 모든 편집이 GUI와 동일한 불변식 + 해시체인\n  감사로그를 거칩니다.\n  _주의:_ `render`는 아직 자막/오버레이 번인을 포함하지 않습니다(컷+색+줌+리프레이밍만), 워크스페이스\n  헤드리스로 실행(`npx` 설치형 bin은 아직 미배포). [`docs/P4-MCP.md`](docs/P4-MCP.md) 참고.\n\n---\n\n## 비전\n\n\u003e **원하는 걸 말하면, AI가 편집을 제안하고, 당신이 타임라인/EDL을 검토한 뒤 렌더한다.** 블랙박스가\n\u003e 아니라.\n\n최종 목표는 *\"빈 공간 잘라내고 핵심에 자막 달아줘\"* 라고 입력하면 LLM이 **검증되고 직렬화 가능한\n`EditCommand` 목록**을 내놓고, 결정적 코어가 그것을 적용·렌더하는 편집기입니다 — 먼저 dry-run\ndiff로 승인받고서요. 코어가 이미 검토 가능한 중간 표현(타임라인 + EDL)을 노출하고 매 단계를\n검증하므로, 에이전트의 편집은 불투명하지 않고 재현·자동검증 가능합니다.\n\n이 중 많은 부분이 **이미 만들어졌습니다.** command bus(Zod 파생 `EditCommand` + 불변식 검증 +\n해시체인 감사로그), 1클릭 스타일 팩(*plan*으로 표현된 템플릿), 9:16/1:1 리프레이밍은 코어에\n실려 있고, 로컬 llama.cpp 플래너(자연어 → plan → dry-run → 승인)와 `render` 도구를 갖춘 헤드리스\n**MCP 서버**(외부 AI가 같은 command bus로 `.dawn` 편집)는 [실험적](#실험적-기능-opt-in)으로 함께\n냅니다. 아직 남은 것: 앱↔MCP 라이브 브리지, MCP 자막 번인, 전환/비트싱크, 멀티트랙.\n[`docs/PRODUCTION.md`](docs/PRODUCTION.md) 참고.\n\n---\n\n## 로드맵\n\n- **Phase 1 — Command bus.** UI에 흩어진 편집 동작을 단일 직렬화 `EditCommand` 유니언 + 단일\n  `applyCommand` 디스패처로 모으고, verb마다 Zod 스키마 1개(→ TS 타입 + 런타임 가드 + JSON-Schema\n  매니페스트). 매 명령 후 불변식 검증 게이트.\n- **Phase 2 — Dry-run / diff / commit + 감사로그.** 복제 상태에서 편집을 미리보고 diff(제거 µs,\n  변경 cue, 길이 변화)를 보여준 뒤 append-only 해시체인 로그로 커밋. 펀치인 줌·색보정 실렌더\n  (effect-aware EDL) 추가.\n- **Phase 3 — 로컬 LLM 플래너(차별점).** `llama.cpp` 사이드카(whisper.cpp IPC 패턴 재사용) +\n  문법 제약 디코딩으로 자연어에서 검증된 `EditCommand` plan 생성, dry-run + 승인 + 커밋 —\n  100% 로컬.\n- **Phase 4 — MCP 서버 + OTIO + 멀티트랙.** 명령 레지스트리를 외부 에이전트용 MCP 서버로 노출하고,\n  멀티트랙/다중 소스(B-roll, PIP, 음악)로 일반화하며, Premiere/Resolve/FCP 연동용 OTIO 내보내기 추가.\n\n---\n\n## 빠른 시작\n\n**Node ≥ 20**, **pnpm 10**, (전사용) **cmake** + **FFmpeg** 필요.\n\n```bash\npnpm install            # 워크스페이스 의존성 설치\n\npnpm verify             # lint + 코어 경계 검사 + 빌드 + 단위 + E2E\n                        # (whisper 의존 단계는 자동 스킵; fixture 있으면 통합 테스트 실행)\n\npnpm setup:binaries     # whisper.cpp 빌드 + 모델 다운로드 (cmake + ffmpeg 필요)\n                        # 기본 모델: large-v3-turbo (~1.6GB)\n                        # 가벼운 설치: DAWN_WHISPER_MODEL=base pnpm setup:binaries\n\npnpm make:fixture       # 결정적 테스트 영상 생성 (macOS `say` 사용)\n```\n\n그 외 유용한 스크립트: `pnpm test:unit`, `pnpm test:int`, `pnpm test:e2e`,\n`pnpm setup:llm`(자연어 편집 활성화, 선택), `pnpm demo:assets \u0026\u0026 pnpm demo:run \u0026\u0026 pnpm demo:ui`\n(실제 미디어 풀 데모).\n\n---\n\n## 아키텍처\n\n코어에 엄격한 이식성 경계를 둔 3계층:\n\n```\nUI / 셸     ──►  편집 코어     ──►  AI / 렌더 사이드카\n(Electron, React)  (순수 TS)        (Node 서브프로세스 래퍼)\n```\n\n- **`packages/core`** — 이식 가능한 순수 TypeScript 편집 코어: 대본 / 타임라인 / 동기화 / 명령 /\n  EDL / 자막 / 오버레이 / 챕터. Node·Electron import 금지(강제). 미래의 에이전트가 운전할 대상.\n- **`packages/ui`** — React UI + Zustand 스토어(`@dawn-cut/ui`).\n- **`apps/desktop`** — Electron 셸(`@dawn-cut/desktop`).\n- **`sidecar/stt`** — `whisper.cpp` 서브프로세스 래퍼, 단어 단위 타임스탬프(MIT).\n- **`sidecar/ffmpeg`** — FFmpeg / ffprobe 서브프로세스 래퍼(LGPL, 서브프로세스 호출만).\n- **`sidecar/tts`** — TTS(기본 macOS `say` 오프라인, Piper 옵트인).\n\n**EDL**은 *편집*과 *내보내기*를 분리하는 결정적 IR입니다: 코어가 만들고 FFmpeg 사이드카가\n소비하므로 같은 편집은 항상 같은 결과로 렌더됩니다. 전체 설계:\n[`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md), PoC 문서는\n[`docs/poc/`](docs/poc/README.md).\n\n### 검증 주도\n\n모든 마일스톤 게이트는 자동 테스트로 뒷받침됩니다. `pnpm verify`가 `0`으로 종료하는 것이 \"완료\"의\n필요조건입니다. [`docs/poc/03-TEST-GATES.md`](docs/poc/03-TEST-GATES.md) 참고.\n\n---\n\n## 라이선스\n\n**MIT** — [LICENSE](LICENSE), [NOTICE](NOTICE) 참고. 코어는 영원히 무료·로컬입니다.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkwakseongjae%2Fdawn-cut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkwakseongjae%2Fdawn-cut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkwakseongjae%2Fdawn-cut/lists"}