문제 상황
Electron 앱의 Mac App Store(MAS) 빌드에서 특정 비디오를 재생하면 전체 창이 먹통이 된다.
증상:
-
태그로 HDR 비디오 재생 시 전체 윈도우 렌더링 실패 - 비디오 영역만이 아니라 앱 전체가 하얗게 변함
- 오디오는 정상 재생
재현 조건:
- MAS 빌드 (
com.apple.security.app-sandboxentitlement 적용) - 하드웨어 가속 활성화
- 10-bit HDR 콘텐츠 (BT.2020 색공간, HEVC/AV1 코덱)
- iPhone으로 촬영한 HDR 비디오가 대표적인 트리거
정상 동작하는 경우:
- 로컬 개발 환경 (샌드박스 미적용)
- Windows 빌드
- SDR 비디오
원인: Electron #47947
이 문제는 Electron Issue #47947에 문서화된 regression이다.
버전 정보:
- Electron 27.3.11: 정상 동작
- Electron 28.0.0 ~ 28.1.1: 앱 실행 자체가 크래시
- Electron 28.1.2 이후: 화면 먹통 (현재까지 미해결)
왜 MAS 샌드박스에서만 발생하는가?
중요한 점: 샌드박스가 HDR 렌더링 자체를 차단하는 게 아니다. 문제는 GPU 컨텍스트 손실 후 복구 과정에서 발생한다.
HDR 비디오는 SDR과 다르게 디코딩 후 추가 작업이 필요하다:
- 색역 변환 (BT.2020 → 디스플레이 색공간)
- 톤 매핑 (PQ/HLG 곡선 → SDR 밝기 범위)
실제 실패 체인:
- HDR 비디오 디코딩 → GPU가 high-bitdepth 프레임 생성
- GPU 컴포지터가 텍스처 합성 (여기까지는 정상 동작)
- 리소스 압박 또는 드라이버 버그로 GPU 컨텍스트 손실 발생
- 드라이버가 복구 시도 → 권한이 필요한 연산 요청
- 샌드박스가 복구 연산 차단
- 복구 실패 → 렌더링 중단
Chromium bug crbug.com/893177에 문서화된 내용: “일부 드라이버는 OUT_OF_MEM이나 컨텍스트 손실 후 복구하지 못한다.” 이 경우 exit_on_context_lost 옵션으로 GPU 프로세스를 재시작하는 워크어라운드가 있지만, MAS 환경에서는 이마저도 제대로 동작하지 않는 것으로 보인다.
Apple의 네이티브 AVFoundation/EDR 프레임워크는 샌드박스 내에서 정상 동작한다. 문제는 Chromium의 GPU 복구 메커니즘이 MAS 샌드박스와 호환되지 않는다는 점이다.
시도한 해결책들
1. --disable-gpu-compositing
app.commandLine.appendSwitch('disable-gpu-compositing')
결과: 동작함
문제: GPU 컴포지팅을 완전히 끄고 CPU로 화면을 합성한다. 모든 레이어(UI, 비디오, 웹 콘텐츠)를 CPU가 처리하므로:
- 스크롤, 애니메이션 성능 저하
- 배터리 소모 증가
- 화상 회의 기능에서 화면 끊김 제보 발생
하드웨어 가속을 쓰는 의미가 없어진다.
2. --disable-features=UseHDRTransferFunction
app.commandLine.appendSwitch('disable-features', 'UseHDRTransferFunction')
HDR 전송 함수(PQ/HLG)를 비활성화하고 SDR처럼 처리한다.
결과: 효과 없음
추가로 발견한 문제: 이 플래그는 모든 플랫폼에 적용된다. Mac에서만 발생하는 버그인데 Windows/Linux HDR 기능까지 끄게 된다. 적용하려면 플랫폼 분기 필요:
if (process.platform === 'darwin') {
app.commandLine.appendSwitch('disable-features', 'UseHDRTransferFunction')
}
참고로 이 플래그에 대해 coderabbitai 봇이 “ChromeOS 전용이라 효과 없다”고 분석했는데, 이건 틀린 정보다. Linux Wayland 환경에서도 HDR 활성화에 사용되는 크로스 플랫폼 플래그다.
3. --force-color-profile=srgb
app.commandLine.appendSwitch('force-color-profile', 'srgb')
앱 전체 색공간을 sRGB로 강제 고정해서 색공간 전환 자체를 막는다.
결과: 효과 없음
4. --disable-accelerated-video-decode
app.commandLine.appendSwitch('disable-accelerated-video-decode')
GPU 비디오 디코딩만 끄고 CPU로 디코딩. 디코딩된 프레임은 여전히 GPU로 렌더링.
결과: 테스트 필요
문제가 디코딩 단계인지, 디코딩 이후 렌더링 단계인지에 따라 효과가 달라질 것이다.
5. GPU 백엔드 변경
app.commandLine.appendSwitch('use-angle', 'metal')
// 또는
app.commandLine.appendSwitch('use-gl', 'angle')
결과: 효과 없음
다른 옵션들
아직 테스트하지 않은 방법들:
HDR 감지 후 Canvas 폴백
HDR 콘텐츠를 감지해서 대신 Canvas나 WebGL로 렌더링하는 방식. 구현 복잡도가 높다.
FFmpeg 기반 우회
LosslessCut이 사용하는 방식. Chromium의 비디오 스택을 완전히 우회하고 FFmpeg로 처리한다. 영상 편집 앱에는 적합하지만 범용 앱에는 과하다.
Electron 다운그레이드
27.3.11로 내리면 해결되지만, 2년 전 버전이라 보안 패치와 새 기능을 포기해야 한다.
대형 앱들의 선택
같은 Electron 기반이라도 MAS 배포 여부는 다르다:
| 앱 | MAS 배포 | 비디오 아키텍처 | 전략 |
|---|---|---|---|
| Discord | ❌ | Electron (darwin 빌드) | 직접 배포 |
| Slack | ✅ | Electron MAS | 화면 공유 버그 등 제한 수용 |
현재 상태
아직 완벽한 해결책을 찾지 못했다.
남은 선택지:
-
disable-gpu-compositing수용: 화상 회의 품질 저하를 감수 - HDR 감지 + 사용자 알림: HDR 비디오 감지 시 “이 비디오는 재생할 수 없습니다” 표시
- MAS 배포 포기: Darwin 빌드로 직접 배포
- Electron 이슈 해결 대기: 언제 될지 모름
MAS 배포를 쉽게 포기하기 어렵고, 화상 회의 기능도 중요해서 GPU 컴포지팅을 끄기도 어렵다. 현재로서는 HDR 감지 후 graceful degradation 하는 방향을 검토 중이다.
참고 자료
- Electron Issue #47947 – MAS HDR 렌더링 버그
- Electron Issue #41927 – MAS GPU 프로세스 실패
- mifi/electron-mas-video-bug – 최소 재현 레포
- Chromium Bug crbug.com/893177 – GPU 컨텍스트 손실 후 복구 실패
- LosslessCut Issue #2392 – FFmpeg 우회 방식 논의
이 글은 2026년 1월 기준 Electron 37.x 버전에서의 경험을 바탕으로 작성되었습니다. 이후 버전에서 수정될 수 있습니다.