
WebCodecs, WebGPU, 그리고 WASM을 사용하여 로컬 우선(Local-First) AI 비디오 편집기를 구축한 방법
요약
WebCodecs, WebGPU, WASM을 활용하여 서버 업로드 없이 브라우저 내에서 모든 AI 비디오 편집을 수행하는 'Local-First' 아키텍처 구축 방법을 소개합니다. React와 ONNX Runtime Web을 결합하여 미디어 재생, AI 추론, 오디오 믹싱을 로컬 환경에서 구현한 사례를 다룹니다.
핵심 포인트
- WebCodecs와 WebGPU를 통한 브라우저 기반 고성능 미디어 처리
- ONNX Runtime Web을 활용한 로컬 AI 추론 구현
- 실시간 미리보기와 고품질 내보내기를 위한 이원화된 재생 경로 설계
- WASM과 Web Worker를 이용한 효율적인 리소스 관리 및 반응성 유지
현대의 비디오 편집기들은 강력하지만, AI 지원 워크플로우는 종종 동일한 트레이드오프(trade-off)로 시작됩니다. 즉, 미디어를 타인의 서버에 업로드하고, 처리를 기다리며, 편집 가능한 상태가 다른 어딘가에 존재한다는 점을 받아들여야 한다는 것입니다.
저는 다른 제약 조건을 탐구하고 싶었습니다:
본격적인 AI 비디오 편집 워크플로우 중 얼마나 많은 부분을 브라우저 내부에서 완전히 실행할 수 있을까?
그 결과물은 React, 브라우저 미디어 API, ONNX Runtime Web, WebGPU, WASM, 그리고 WebCodecs로 구축된 MIT 라이선스 비디오 편집기인 Timeline Studio입니다.

흥미로운 점은 단순히 또 다른 타임라인 UI를 추가하는 것이 아니었습니다. 편집 백엔드(backend)에 의존하지 않고 미디어 재생, AI 추론 (inference), 편집 가능한 타임라인 상태, 오디오 믹싱, 그리고 결정론적(deterministic) 내보내기가 동일한 시간 정의에 합의하도록 만드는 것이었습니다.
아키텍처 한눈에 보기
Timeline Studio는 대화형 편집과 비용이 많이 드는 미디어 및 AI 작업을 분리합니다:
React UI 및 타임라인 상태
|
+-- 반응형 미리보기를 위한 네이티브 미디어 재생
...
대규모 모델은 기능이 필요할 때만 로드됩니다. 모델 아티팩트(artifacts)는 리비전이 고정(revision-pinned)되어 로컬에 캐싱되며, 추론 (inference)은 수명이 긴 워커(workers)에서 실행되므로 반복적인 작업 시 전체 런타임 (runtime)을 다시 구축할 필요가 없습니다.
편집기가 반응성을 유지하는 이유는 React가 모든 디코딩된 비디오 프레임이 아닌, 편집 인터페이스와 선언적 프로젝트 상태를 소유하기 때문입니다.
하나의 타임라인, 두 가지 재생 경로
실시간 미리보기와 고품질 내보내기는 서로 다른 요구 사항을 가집니다.
편집 중에는 활성화된 비디오 요소가 브라우저의 네이티브 재생 경로 (native playback path)를 따릅니다. 지연된 React 상태 (state)로부터 미디어 요소를 지속적으로 탐색(seek)하려고 시도하면, 특히 여러 레이어가 있을 때 눈에 띄는 끊김 현상이 발생했습니다.
내보내기 (Export) 작업은 정반대의 방식을 취합니다. 이는 정확한 출력 타임스탬프 (timestamp)로부터 모든 프레임을 해결(resolve)합니다. 각 타임스탬프에 대해, 렌더러 (renderer)는 어떤 클립이 활성화되어 있는지 결정하고 다음 항목들을 합성 (compose)합니다:
- 메인 비주얼 미디어 (main visual media);
- PIP (picture-in-picture) 오버레이;
- 자막 (captions) 및 스티커;
- 마스크 (masks), 필터 (filters), 및 효과 (effects);
- 키프레임 변환 (keyframed transforms);
- 애니메이션 (animations) 및 전환 (transitions).
이러한 분리는 내보낸 파일이 실시간 UI 성능에 의존하지 않도록 하면서도, 편집기에는 부드러운 재생을 제공합니다.

WebCodecs를 이용한 결정론적 내보내기 (Deterministic export)
MediaRecorder는 호환성이 중요할 때 유용하지만, 실시간 스트림을 기록합니다. 만약 탭이 멈추거나 장치가 속도를 따라가지 못하면, 출력물은 녹화 세션의 타이밍 문제를 그대로 물려받을 수 있습니다.
따라서 Timeline Studio는 WebCodecs를 주요 내보내기 경로로 취급합니다.
각 출력 프레임에 대해 렌더러는 다음을 수행합니다:
- 프레임 인덱스를 정확한 타임라인 타임스탬프로 변환합니다.
- 모든 활성 비주얼과 그 소스 타임스탬프를 해결합니다.
- 공유된 합성 기하 구조 (composition geometry)를 내보내기용 캔버스 (canvas)에 그립니다.
- 프레임을 선택된 비디오 인코더 (video encoder)로 전달합니다.
- 오디오를 별도로 믹싱하고 최종 컨테이너 (container)로 멀티플렉싱 (mux) 합니다.
미리보기와 내보내기는 동일한 기하 구조 규칙을 공유합니다. 자막, 마스크, 오버레이 또는 변환이 단순히 출력 해상도가 변경되었다는 이유만으로 움직여서는 안 됩니다.
MediaRecorder는 호환성을 위한 폴백 (fallback)으로 유지되지만, 요청된 형식을 조용히 변경하는 것은 허용되지 않습니다. 또한 활성화된 내보내기 작업은 추가 작업을 중단하고, 미디어 리소스를 해제하며, 불완전한 파일을 절대 다운로드하지 않는 실제 취소 경로 (cancel path)를 노출합니다.
WebGPU 및 WASM을 사용한 ONNX 모델 실행
현재 이 에디터는 여러 워크플로우를 위해 브라우저 측 모델을 사용합니다:
- 다국어 음성 생성을 위한 Piper/VITS 및 Kokoro;
- 자동 자막을 위한 Whisper small q8;
- 피사체 탐지(subject detection) 및 인물 매팅(portrait matting)을 위한 YOLOS 및 MODNet;
- 보컬 분리(vocal separation) 및 AI 음악 생성;
- 토킹 아바타(talking-avatar) 생성을 위한 JoyVASA 및 LivePortrait.
모델 경로가 WebGPU로 검증된 경우 WebGPU를 우선적으로 사용합니다. WASM은 숨겨진 엔진 변경이 아니라 명시적인 폴백(fallback) 방식입니다.
이 작업을 통해 얻은 교훈은 모델의 가용성(availability)이 워크플로우의 신뢰성(reliability)과 동일하지 않다는 점입니다. 단순히 ONNX 파일이 존재한다고 해서 목소리가 카탈로그에 추가되는 것이 아닙니다. 해당 목소리는 에디터 자체를 통해 생성, 타임라인 삽입, 그리고 다운로드된 WAV 파일 검증 과정을 모두 통과해야 합니다.
무거운 추론(inference) 작업은 UI 스레드 외부에서 실행됩니다. 여러 아티팩트(artifact)를 포함하는 모델 번들의 경우, 다운로드는 병렬로 진행되는 반면, GPU 세션은 불안정한 초기화와 메모리 압박을 피하기 위해 직렬(serially)로 생성됩니다. 일단 초기화되면, 워커(worker)는 동일한 페이지에서의 반복적인 생성을 위해 계속 살아있는 상태를 유지합니다.
대규모 모델 아티팩트 캐싱
방문할 때마다 모델을 다시 다운로드한다면 브라우저 기반 AI 에디터는 실용적이지 않을 것입니다.
Timeline Studio는 애플리케이션 셸(application shell)과 대규모 런타임 자산을 위해 서비스 워커(service worker)와 버전 관리된 브라우저 캐시를 사용합니다. 모델 URL은 리비전 고정(revision-pinned)되어 있어 캐시된 아티팩트가 안정적인 식별자를 갖도록 합니다. 호스팅 위치가 변경되더라도 레거시 캐시 키를 여전히 인식할 수 있어, 사용자가 동일한 가중치(weights)를 다시 다운로드해야 하는 상황을 방지합니다.
이는 체감되는 워크플로우를 다음과 같이 변화시킵니다:
- 첫 실행 시 모델 설정을 수행합니다;
- 이후 실행 시에는 초기화되었거나 캐시된 자산을 재사용합니다;
- 반복적인 생성은 또 다른 가짜 "모델 다운로드"가 아닌, 실제 "생성"으로 제시됩니다.
또한 이 애플리케이션은 PWA로 설치 가능하므로, 에디터 셸은 전체 네트워크 라운드 트립(network round trip)과 독립적으로 시작될 수 있습니다.
오디오는 그 자체로 타임라인의 문제
비디오 내보내기(Video export)는 작업의 절반에 불과합니다. 보이스오버(Voiceovers), 음악, 분리된 소스 오디오, 그리고 활성화된 임베디드 비디오 오디오 모두 클립 범위 및 소스 오프셋(source offsets)과 일치해야 합니다.
Timeline Studio는 OfflineAudioContext를 사용하여 오디오를 독립적으로 준비합니다. 각 소스는 내보내기 범위에 맞춰 크롭(crop) 및 스케줄링된 후, 멀티플렉싱(muxing) 전에 믹싱(mixing)됩니다.
이는 사용자 정의 인/아웃(in/out) 내보내기에서 특히 중요해집니다. 시각적 요소만 크롭하는 것으로는 충분하지 않습니다. 자막, 오버레이(overlays), 음성, 음악, 임베디드 오디오, 그리고 SRT 타이밍 모두 일관되게 제로(zero) 기준으로 재설정(rebased)되어야 합니다.
웨이브폼(Waveforms)은 디코딩된 피크(peaks)가 사용 가능할 때 이를 통해 도출됩니다. 디코딩 또는 복원(restoration)이 진행 중인 동안에는 클립이 빈 화면으로 나타나 시각적 모호함을 주는 대신, 안정적인 저강도 플레이스홀더(low-emphasis placeholder)를 렌더링합니다.
AI 출력물은 편집 가능한 상태가 되어야 합니다
가장 유용한 아키텍처 결정은 AI 출력물을 최종적인 불투명한 결과물(opaque artifact)로 취급하지 않는 것이었습니다.
대신 다음과 같이 처리합니다:
- 음성 인식(speech recognition)은 타이밍이 지정된 자막 클립이 됩니다.
- 생성된 음성(generated speech)은 자막에 연결된 편집 가능한 오디오가 됩니다.
- 피사체 탐지(subject detection)는 타임스탬프가 찍힌 분석 트랙이 됩니다.
- 보컬 분리(vocal separation)는 독립적인 보컬 및 인스트루멘탈(instrumental) 클립이 됩니다.
- 아바타 생성(avatar generation)은 교체 가능한 시각 매체가 됩니다.
- AI 음악은 자동으로 삽입되는 대신 에셋 라이브러리(asset library)에 추가됩니다.
이를 통해 AI 작업의 가역성(reversibility)을 유지할 수 있습니다. 사용자는 전체 워크플로우를 반복하지 않고도 개별 결과물을 이동, 트리밍(trim), 교체, 연결 해제 또는 재생성할 수 있습니다.
타임라인을 에이전트 편집 가능하게 만들기
이 저장소에는 edit-timeline-studio 스킬과 Codex, Claude Code, Copilot, Gemini CLI와 같은 도구를 위한 버전 관리된 커맨드 러너(command runner)가 포함되어 있습니다.
커맨드 레이어는 휴대 가능한 .timeline 프로젝트를 검사하고, 버전 관리된 편집 계획을 검증하며, 필드 수준의 차이(diffs)를 보여주고, 지원되는 편집을 트랜잭션(transactionally) 방식으로 적용하며, 문서화된 휴대 가능한 서브셋(subset)을 H.264/AAC MP4로 렌더링할 수 있습니다.
예를 들어:
npm run agent -- project.inspect /absolute/path/project.timeline
npm run agent -- project.diff /absolute/path/edit-plan.json
npm run agent -- project.run /absolute/path/edit-plan.json
...
여기서는 드라이 런 (Dry runs), 안정적인 클립 ID (stable clip IDs), 명시적인 타임스탬프 (explicit timestamps), 리비전 체크 (revision checks), 그리고 멱등적 작업 ID (idempotent operation IDs)가 중요합니다. 에이전트(Agent)는 사용자의 편집 가능한 프로젝트를 되돌릴 수 없는 렌더링 결과물로 바꾸거나, 재시도 후에 동일한 변형 (mutation)을 두 번 적용해서는 안 됩니다.
내가 배운 것들
브라우저 기반 비디오 편집기를 구축하는 것은 프레임을 그리는 것보다 시간에 대한 하나의 일관된 해석을 유지하는 것에 더 가깝습니다.
타임라인 (Timeline), 미디어 요소 (media elements), 파형 데이터 (waveform data), 자막 (captions), 키프레임 (keyframes), 소스 오프셋 (source offsets), 트랜지션 (transitions), 오디오 믹서 (audio mixer), 그리고 내보내기 렌더러 (export renderer)는 모두 동일한 질문에 답할 수 있어야 합니다:
- 현재 어떤 클립이 활성화되어 있는가?
- 어떤 소스 프레임이나 오디오 샘플이 여기에 속하는가?
- 이 타임스탬프에서 어떤 값들이 보간 (interpolated)되는가?
- 첫 번째 키프레임 이전과 마지막 키프레임 이후에는 어떤 일이 일어나야 하는가?
AI는 또 다른 레이어를 추가하지만, 동일한 원칙이 적용됩니다. 생성된 결과물은 결정론적 (deterministic)이고 편집 가능한 타임라인 모델로 들어올 때 훨씬 더 유용해집니다.
브라우저 플랫폼은 이제 제가 예상했던 것보다 훨씬 더 많은 스택을 처리할 수 있는 능력을 갖추고 있습니다. WebCodecs, WebGPU, WASM, Workers, OfflineAudioContext, Cache Storage, 그리고 설치 가능한 PWA는 각자의 책임이 명확하게 분리되어 있는 한, 상당한 수준의 로컬 우선 (local-first) 미디어 워크플로우를 지원할 수 있습니다.
체험해보기
Timeline Studio는 오픈 소스이며 활발히 개발되고 있습니다:
Node.js 20 이상 버전이 설치되어 있다면 로컬에서 실행할 수 있습니다:
git clone https://github.com/MartinDelophy/ai-video-editor.git
cd ai-video-editor
npm install
...
만약 여러분이 브라우저 미디어 (browser media), WebCodecs, WebGPU, ONNX, 타임라인 UX (timeline UX), 또는 결정론적 렌더링 (deterministic rendering) 분야에서 작업하고 있다면, 피드백과 집중적인 기여를 환영합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기