azosi · 2026.7.29 03:17 · 조회 1
Revideo Decoders
Revideo의 Decoder 시스템은 비디오·오디오·이미지 에셋을 효율적으로 디코딩해서 Scene에 공급하는 메커니즘이다. 큰 영상 프로젝트에서 메모리/성능 병목의 상당 부분이 여기서 발생한다.
🧩 Decoder가 뭔가
Revideo는 Scene 안에서 useVideo, useAudio, Img 같은 헬퍼로 외부 에셋을 참조한다. 그 에셋은 매번 디스크에서 새로 읽으면 안 되니까 Decoder가 캐시·디코딩·재생 위치 추적 등을 담당한다.
import {useVideo} from '@revideo/core';
yield* useVideo(
scene, // Scene 인스턴스
'https://cdn.example.com/bg.mp4', // URL
(video) => { // 콜백
video.play();
video.scale(1.2);
},
);
useVideo는IDecoder인터페이스를 통해 에셋을 가져온다. 기본은 MP4Box + WebCodecs 기반.
📚 기본 제공 Decoder
| Decoder | 대상 | 백엔드 |
|---|---|---|
VideoDecoder | mp4/webm | MP4Box (분할) + WebCodecs (디코드) |
AudioDecoder | mp3/wav | Web Audio API |
ImageDecoder | png/jpg/webp | Image element |
LottieDecoder | Lottie JSON | lottie-web |
모든 Decoder는 lazy: 처음 참조될 때 로드,
Scene끝나면 해제.
⚙️ 어떻게 동작하나 — mp4 비디오의 경우
useVideo(url)호출 시 메타데이터만 fetch (head 요청)- Scene에서 실제로 프레임 요청할 때 스트림 다운로드 시작
- MP4Box가 moof 박스 단위로 분할 (보통 1초 단위)
- 분할된 chunk는 IndexedDB에 캐시
- WebCodecs
VideoDecoder가 chunk를VideoFrame으로 디코드 - Canvas에 draw
[URL] → [HTTP] → [MP4Box 분할] → [IndexedDB 캐시] → [WebCodecs 디코드] → [Canvas]
핵심: 전체 mp4를 메모리에 올리지 않고, 현재 frame 주변 chunk만 디코드. 10분짜리 영상이어도 메모리 footprint는 수 MB.
🚀 성능 이점
| 방식 | 10분 mp4 (1080p) 메모리 | 로드 시간 |
|---|---|---|
<video> 태그 직접 | 200~500 MB | 즉시 |
| Revideo Decoder | 5~20 MB | 첫 chunk 100ms |
큰 에셋 여러 개를 동시에 쓰는 Scene에서 Decoder의 가치가 극대화된다.
🛠️ 커스텀 Decoder
자사 CDN 구조나 커스텀 포맷(HLS, DASH, 특수 컨테이너)에 맞춰 Decoder를 직접 만들 수 있다.
import {IDecoder, Decoder} from '@revideo/core';
class HlsDecoder extends Decoder {
public async init(): Promise<void> {
// HLS.js 인스턴스, m3u8 fetch, ...
}
public async seek(time: number): Promise<void> {
// 특정 시점으로 점프
}
public async frame(time: number): Promise<VideoFrame> {
// 해당 시점의 VideoFrame 반환
}
public async dispose(): Promise<void> {
// 리소스 해제
}
}
export const hlsDecoder = new HlsDecoder();
// 등록 (보통 plugin에서)
registerDecoder('hls', hlsDecoder);
// 사용
yield* useVideo(scene, 'https://cdn.example.com/stream.m3u8', cb, {decoder: 'hls'});
커스텀 Decoder 패턴은 스트리밍 비디오, DRM, 암호화된 에셋 같은 고급 사용 사례에 필수.
🐛 트러블슈팅 — 자주 보이는 에러
| 증상 | 원인 | 해결 |
|---|---|---|
Failed to fetch | CORS, 404, 오프라인 | 헤더 + URL 확인 |
Decoder not ready | init() 미완료 | await |
Memory leak | dispose() 미호출 | Scene 종료 시 자동 dispose |
Choppy playback | chunk 크기 부적절 | MP4Box 옵션 조정 |
Codec not supported | WebCodecs 미지원 브라우저 | Chrome/Edge로 |
자세한 트러블슈팅은 Revideo FFmpeg Issues 참고.
📈 최적화 팁
| 팁 | 효과 |
|---|---|
에셋 사전 로드 (Player 로드 시 preloadAll()) | 첫 frame 지연 ↓ |
| HLS/DASH 사용 (긴 영상) | 대역폭/메모리 ↓ |
| 해상도 맞추기 (1920x1080 Scene에 4K 에셋) | 디코드 비용만 늘고 효과 없음 |
| 공통 prefix (CDN 캐시 hit) | 로드 시간 ↓ |
| WebCodecs 사용 확인 (feature detect) | fallback 대비 |
// Player 마운트 시 preload
<Player
project={project}
onReady={(p) => p.project.videos.forEach(v => v.preload())}
/>
🆚 다른 프레임워크와 비교
| Revideo Decoder | Remotion <video> | FFmpeg.wasm | |
|---|---|---|---|
| 메모리 | 5~20 MB | 200~500 MB | 100 MB+ |
| 스트리밍 | ✅ chunked | ❌ 전체 로드 | ❌ |
| Seek | ✅ 즉시 | ❌ 브라우저 의존 | ⚠️ 느림 |
| WebCodecs | ✅ | ❌ | ❌ |
Revideo의 메모리 효율성은 SaaS/서버less에서 결정적 차이. 한 서버에서 10개 동시 렌더도 가능.
🚀 다음 단계
| 작업 | 가이드 |
|---|---|
| 다른 성능 패턴 | Revideo 노드 격리 |
| 렌더 트러블슈팅 | Revideo FFmpeg Issues |
🔗 공식 리소스
- 공식 문서: https://midrender.com/revideo/docs/guide/performance/decoders
- WebCodecs API: https://developer.mozilla.org/en-US/docs/Web/API/WebCodecs_API
- MP4Box.js: https://github.com/gpac/mp4box.js
상위 문서: ← Revideo 성능 & 최적화 출처: Revideo 공식 문서 — Decoders 한글화 (2026-07-29) 공급사: Revideo (현 Midrender)
변경 이력
| 날짜 | 변경 |
|---|---|
| 2026-07-29 | 초안 작성 — Decoder 구조 + 커스텀 Decoder + 최적화 팁 |
댓글
아직 댓글이 없습니다.
댓글을 작성하려면 로그인이 필요합니다.