문제 해결
증상을 찾은 다음 원인과 해결 방법을 확인하십시오. 오류에는 코드(GPU_INIT_FAILED, INVALID_INPUT 등)가 붙습니다. 브라우저 엔진과 네이티브 호스트는 엔진의 코드를 공유하며, 나머지 코드는 호스트 프로토콜에 있습니다. 코드에서 오류를 다루는 방법은 검증과 오류를 참고하십시오.
렌더링과 GPU
섹션 제목: “렌더링과 GPU”캔버스가 비어 있거나 GPU_INIT_FAILED로 실패한다
섹션 제목: “캔버스가 비어 있거나 GPU_INIT_FAILED로 실패한다”원인. 엔진이 GPU 디바이스를 만들지 못했습니다. 브라우저에서는 WebGPU도 WebGL2도 없거나(하드웨어 가속 꺼짐, 차단된 GPU, VM 안의 페이지), 소프트웨어 어댑터를 거부하도록 했는데 소프트웨어 어댑터밖에 없는 경우입니다. 서버에서는 호스트가 쓸 수 있는 GPU 드라이버가 없는 경우입니다.
해결.
- 브라우저에서는 엔진이 CPU 렌더러로 대체하게 하십시오.
alpha2/renderer-choice의createRenderer(binding, canvas, "auto")나 워커 호스트의renderer: "auto"는 GPU가 실패하면 CPU로 그리고, 무엇을 만들었는지rendererChoice로 알려 줍니다.WebEffectRegistry.createCpu(canvas)는 CPU 렌더러를 직접 만듭니다. 더 느리지만 같은 픽셀을 그립니다. createForHtmlCanvas에{ softwareAdapter: "refuse" }를 주면 SwiftShader, llvmpipe, WARP, WebGPU 폴백 어댑터를GPU_INIT_FAILED로 거부합니다. 이 옵션을 빼거나, 소프트웨어 어댑터보다 빠른 CPU 렌더러로 대체하십시오.- 네이티브에서
alpha2-host는GPU_INIT_FAILED일 때 상태 70으로 종료합니다. GPU가 없는 머신에서는--renderer auto(기본값)나--renderer cpu를 쓰십시오.--renderer gpu는 어댑터가 없으면 실패합니다. - 브라우저가 제공하는 기능은 플랫폼 지원에서 확인하십시오.
오류는 없는데 캔버스가 비어 있다
섹션 제목: “오류는 없는데 캔버스가 비어 있다”원인. 그 시점에 보여 줄 소스의 프레임이 엔진에 없습니다. 미디어는 애플리케이션이 디코딩해 업로드하며, 엔진은 받은 것만 그립니다.
해결. renderAt(ticks)의 반환값을 확인하십시오. missingSources와 missingFrames가 빠진 것을 알려 줍니다. frameNeeds(ticks)는 그 시점에 필요한 프레임을 정확한 소스 시간과 함께 나열합니다. 그 프레임을 업로드하고(uploadVideoFrame, uploadRgbaFrame, uploadRgbaImage) 다시 렌더링하거나, alpha2/frame-supply의 FrameSupply에 맡기십시오.
export가 GPU_DEVICE_HUNG이나 GPU_DEVICE_LOST로 실패한다
섹션 제목: “export가 GPU_DEVICE_HUNG이나 GPU_DEVICE_LOST로 실패한다”원인. GPU_DEVICE_LOST는 드라이버 리셋, 다른 프로그램, 절전 등으로 디바이스를 잃은 경우입니다. GPU_DEVICE_HUNG은 export 자신의 작업이 운영체제 GPU 워치독(기본 2000ms)의 절반 이상 GPU를 붙잡아 OS가 GPU를 리셋한 경우입니다. 같은 작업을 그 GPU에서 다시 실행하면 다시 멈춥니다.
해결. 디바이스 손실은 새 프로세스나 새 디바이스에서 재시도하십시오. 네이티브 호스트는 응답한 뒤 종료하며, 브라우저 플레이어의 GpuRecoveryLadder가 이 과정을 대신합니다. 멈춘 경우에는 CPU로 렌더링하거나(--renderer cpu) 무거운 프레임을 가볍게 하십시오. failure.diagnostics.gpuSubmission이 가장 긴 제출과 그 프레임, 이펙트를 알려 줍니다. alpha2/export-retry의 decideRetry가 이 중에서 골라 줍니다.
CPU 렌더러에서 EFFECT_ERROR가 난다
섹션 제목: “CPU 렌더러에서 EFFECT_ERROR가 난다”원인. 프로젝트가 런타임 WGSL 이펙트를 씁니다. CPU 렌더러는 내장 이펙트와 트랜지션은 모두 그리지만, WGSL에는 GPU가 필요합니다.
해결. 그 프로젝트는 GPU가 있는 머신에서 --renderer gpu(또는 renderer: "gpu")로 렌더링하십시오.
브라우저 설정
섹션 제목: “브라우저 설정”프리뷰에서 소리가 나지 않는다
섹션 제목: “프리뷰에서 소리가 나지 않는다”원인. 오디오 프리뷰는 믹스한 오디오를 공유 메모리로 오디오 스레드에 넘기는데, 이를 위해 페이지가 교차 출처 격리(cross-origin isolated)되어 있어야 합니다. 비디오 프리뷰, 편집, export는 이것 없이도 동작합니다.
해결. 페이지를 다음 두 헤더와 함께 제공하십시오.
Cross-Origin-Opener-Policy: same-originCross-Origin-Embedder-Policy: require-corpalpha2/audio-timeline의 canShareAudioMemory()가 페이지가 격리되었는지 알려 줍니다. require-corp에서는 페이지가 불러오는 모든 교차 출처 리소스가 이를 허용해야 합니다(CORS나 Cross-Origin-Resource-Policy).
콘솔에 application/wasm MIME 타입 경고가 뜬다
섹션 제목: “콘솔에 application/wasm MIME 타입 경고가 뜬다”`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower.원인. 서버가 .wasm 파일을 다른 Content-Type으로 보냅니다.
해결. .wasm을 application/wasm으로 제공하십시오. 어느 쪽이든 동작은 하며, 대체 방식은 컴파일이 느릴 뿐입니다. 번들러가 파일을 옮긴다면 그 URL을 init({ module_or_path })에 넘기십시오.
dom-webcodecs 타입 때문에 TypeScript 오류가 난다
섹션 제목: “dom-webcodecs 타입 때문에 TypeScript 오류가 난다”원인. alpha2/mediabunny가 쓰는 선택적 의존성 mediabunny가 @types/dom-webcodecs 0.1.13을 설치하는데, 이 선언이 TypeScript 5.9의 DOM 라이브러리와 충돌합니다.
해결. skipLibCheck로 컴파일하거나, package.json에서 더 새 타입으로 고정하십시오.
"overrides": { "@types/dom-webcodecs": "0.1.19" }alpha2/mediabunny를 import하는 앱은 tsconfig.json의 lib에 "ESNext.Disposable"도 있어야 합니다.
브라우저 export가 H.264를 인코딩하지 못한다
섹션 제목: “브라우저 export가 H.264를 인코딩하지 못한다”원인. 브라우저 export는 브라우저의 WebCodecs 인코더로 인코딩하며, 모든 브라우저가 모든 크기에서 모든 코덱을 인코딩하지는 않습니다.
해결. 먼저 확인하십시오. canEncodeVideoTrack("avc", { width, height, rate })는 브라우저가 인코딩하지 못하면 null을 돌려줍니다. WebM의 vp9를 써 보거나 네이티브로 export하십시오. 편집기의 bridge.videoEncoders()도 같은 확인을 합니다.
텍스트와 폰트
섹션 제목: “텍스트와 폰트”텍스트가 엉뚱한 폰트로 그려진다
섹션 제목: “텍스트가 엉뚱한 폰트로 그려진다”원인. 엔진은 시스템 폰트를 읽지 않습니다. 넘겨받은 폰트 파일 중에서 font_family로 찾아 텍스트를 그립니다. 넘겨받은 폰트 어디에도 없는 패밀리는 대체 순서대로, 즉 해당 글리프가 있는 첫 폰트로 그려집니다.
해결. 렌더러에 폰트 파일을 어디서나 같은 순서로 넘기십시오. 브라우저에서는 워커 호스트의 fonts나 addFontFile, CLI에서는 --font, Node.js와 Python에서는 fonts입니다. 네이티브 export는 찾지 못한 패밀리를 unmatchedFontFamilies에 알려 줍니다. 패밀리는 폰트 name 테이블의 어떤 이름과도, 어떤 언어로든, 대소문자 구분 없이 일치하면 됩니다.
MISSING_INPUT: the project shows text, but no fonts were registered
섹션 제목: “MISSING_INPUT: the project shows text, but no fonts were registered”원인. 프레임에 텍스트나 자막이 있는데 폰트를 하나도 넘기지 않았습니다.
해결. 위와 같이 폰트 파일을 하나 이상 넘기십시오.
프리뷰와 export에서 줄바꿈 위치가 다르다
섹션 제목: “프리뷰와 export에서 줄바꿈 위치가 다르다”원인. 두 렌더러의 폰트가 다르거나, 같은 폰트라도 순서가 다릅니다.
해결. 같은 파일을 같은 순서로 쓰십시오. 폰트 바이트가 같으면 브라우저의 WasmTextRasterizer와 네이티브 export가 같은 텍스트를 그립니다.
export
섹션 제목: “export”브라우저 export가 waiting 티켓이나 missingSources에서 멈춘다
섹션 제목: “브라우저 export가 waiting 티켓이나 missingSources에서 멈춘다”원인. export할 프레임에 엔진에 없는 소스 프레임이 필요합니다. beginExportFrame()은 렌더링하는 대신 필요한 것(missingSources, missingFrames)을 담은 waiting 티켓을 돌려줍니다.
해결. 요청된 프레임을 업로드하고 다시 요청하면 같은 프레임에서 export가 이어집니다. exportToSink는 이 목록으로 refill을 호출합니다. refill을 네 번 해도 계속 기다리는 프레임은 sources-not-held 단계의 RESOURCE_LIMIT으로 실패합니다. refill이 요청받은 것을 업로드하지 않았거나 업로드가 프레임 예산을 넘은 경우입니다. refill은 프리뷰용이 아니라 이 export용으로 만든 DecoderRefillCoordinator를 써야 합니다.
네이티브 export가 MISSING_INPUT이나 CONFORM_FAILED로 실패한다
섹션 제목: “네이티브 export가 MISSING_INPUT이나 CONFORM_FAILED로 실패한다”원인. 렌더링에 필요한 파일을 넘기지 않았거나(MISSING_INPUT: 에셋, 이펙트 리소스, 폰트, 프레임), 넘긴 파일이 오프라인이거나 프로젝트에 기록된 미디어와 다릅니다(CONFORM_FAILED).
해결. 모든 소스에 --asset <source-id>=<path>(Node.js와 Python은 assets)를 주십시오. alpha2-host conform은 렌더링하지 않고 소스마다 찾은 것과 막는 것을 보고합니다. 오프라인 파일의 메시지에는 호스트가 찾아본 경로가 나옵니다.
서버나 Windows N에서 H.264 export가 INVALID_INPUT으로 실패한다
섹션 제목: “서버나 Windows N에서 H.264 export가 INVALID_INPUT으로 실패한다”원인. 릴리스 아카이브의 FFmpeg는 LGPL 빌드라 소프트웨어 H.264 인코더가 없습니다. H.264는 GPU 인코더(Vulkan Video, NVENC, VideoToolbox, Media Foundation, D3D12)나 OpenH264가 담당합니다. CPU 전용 서버, arm64 서버, NVIDIA 데이터센터 GPU, Media Feature Pack이 없는 Windows N·KN에는 이것이 없습니다.
해결.
- Cisco의 OpenH264를 설치하십시오.
npx @alpha2-sh/node install --openh264또는python -m alpha2 install --openh264입니다. - 또는 런타임이 CPU로 인코딩하는 VP9나 AV1로 export하십시오.
--video-codec vp9입니다. capabilities는 export 전에encode.h264.status를reason,remedy와 함께 알려 줍니다.
IO_ERROR: 출력 파일이 이미 있다
섹션 제목: “IO_ERROR: 출력 파일이 이미 있다”원인. export는 요청하지 않으면 파일을 교체하지 않습니다.
해결. --overwrite(overwrite: true)를 주십시오. export가 완성된 뒤에만 파일을 교체합니다. OUTPUT_IN_USE는 실행 중인 다른 export가 같은 출력에 쓰고 있다는 뜻입니다.
RESOURCE_LIMIT 또는 HOST_OOM_KILLED
섹션 제목: “RESOURCE_LIMIT 또는 HOST_OOM_KILLED”원인. export의 작업 집합이 머신이나 컨테이너가 호스트에 주는 메모리에 들어가지 않거나, 커널의 OOM killer가 호스트를 종료했습니다.
해결. 동시에 실행하는 export 수(concurrency)를 줄이거나, memory 예산을 낮추거나, 컨테이너에 메모리를 더 주십시오. 머신 메모리 때문에 거부되면 failure.stage가 machine-memory나 memory-limit-reached입니다.
네이티브 호스트 설치
섹션 제목: “네이티브 호스트 설치”macOS가 호스트를 거부한다: HOST_QUARANTINED
섹션 제목: “macOS가 호스트를 거부한다: HOST_QUARANTINED”원인. 브라우저로 내려받은 파일에는 격리 속성이 붙고, Gatekeeper가 압축을 푼 프로그램을 허용하지 않습니다.
해결. xattr -dr com.apple.quarantine <unpacked dir>를 실행하거나, curl -LO로 내려받거나, npx @alpha2-sh/node install로 설치하십시오. 브라우저로 내려받은 OpenH264 라이브러리에는 xattr -d com.apple.quarantine <library>가 필요합니다.
HOST_NOT_FOUND
섹션 제목: “HOST_NOT_FOUND”원인. 클라이언트가 hostPath 옵션, ALPHA2_HOST_PATH, 패키지, 캐시, PATH에서 alpha2-host를 찾았지만 없었습니다.
해결. npx @alpha2-sh/node install(또는 python -m alpha2 install)을 실행하거나, ALPHA2_HOST_PATH가 압축을 푼 아카이브의 bin/alpha2-host를 가리키게 하십시오.
Linux에서 HOST_LOAD_FAILED
섹션 제목: “Linux에서 HOST_LOAD_FAILED”원인. musl 기반 시스템(Alpine)이거나 glibc가 2.35보다 오래되었습니다.
해결. node:22-slim이나 Ubuntu 22.04처럼 glibc 2.35 이상인 기반을 쓰십시오. 재시도로는 해결되지 않습니다.
HOST_START_TIMEOUT 또는 HOST_BLOCKED
섹션 제목: “HOST_START_TIMEOUT 또는 HOST_BLOCKED”원인. 무언가가 호스트 실행을 붙잡았습니다. Gatekeeper 검사, 백신 검사, 또는(HOST_BLOCKED) Smart App Control, App Control, AppLocker 같은 Windows 정책입니다.
해결. 프로그램을 허용하거나, 첫 검사가 느리다면 hostStartTimeoutMs(Node.js)나 host_start_timeout(Python)을 늘리십시오.
프로젝트가 거부된다
섹션 제목: “프로젝트가 거부된다”엔진이 거부하는 문서는 문제를 지목하는 메시지와 함께 로드에 실패합니다. 같은 검사가 어디서나 실행됩니다. alpha2/project의 validateProject(project)는 로드하기 전에 문제를 문자열로 돌려주며, Python에서는 alpha2.validate_project가 같은 일을 합니다. 메시지 예시는 다음과 같습니다.
| 메시지 | 원인 | 해결 |
|---|---|---|
clips a and b overlap without a covering transition on track main |
한 트랙은 한 번에 클립 하나만 보여 줍니다. | 클립 하나를 다른 트랙으로 옮기거나, 겹치는 구간에 트랜지션을 넣으십시오. |
clip inset references unknown source nope |
source_id가 없는 소스를 가리킵니다. |
id를 고치거나 소스를 추가하십시오. |
missing field 'mode' |
애니메이션 가능한 값을 "scale": { "x": 1, "y": 1 }처럼 그대로 썼습니다. |
{ "mode": "constant", "value": { "x": 1, "y": 1 } }로 감싸십시오. |
unsupported schema version 2 |
다른 엔진 버전용 문서입니다. | alpha2 0.5에서는 schema_version 1을 쓰십시오. |
has unknown field "float" |
스키마에 없는 필드로, 대개 오타입니다. | 스키마 레퍼런스에서 필드를 확인하십시오. |
로드되는 프로젝트에도 lint 문제가 있을 수 있습니다. lintProject(alpha2.lint_project)는 거부하지 않고 이를 보고합니다. 프레임 사이에 놓인 시간은 off_frame_boundary, 어떤 프레임도 닿지 않는 키프레임(대개 시간 기준을 잘못 쓴 경우)은 unreached_keyframe입니다.
