본문으로 건너뛰기

Camera Capture

MSK Camera Capture는 브라우저 카메라 캡처 primitive입니다(사진 + 영상). Mic Capture와 대칭이며 카메라 고유 기능을 더합니다: 라이브 프리뷰(<video>), 사진 캡처(canvas → Blob), 전/후면 전환(facingMode, 모바일). storage-agnostic — Blob만 넘겨줍니다.

Preview

실제 카메라에 접근합니다. 영상/사진은 브라우저 내에서만 처리되며 어디에도 전송되지 않습니다.

Data API

<div data-msk-camera-capture
data-msk-camera-default-label="기본 카메라"
data-msk-camera-generic-label="카메라 :index">
<video data-msk-camera-preview playsinline muted></video>
<select data-msk-camera-select></select>
<button type="button" data-msk-camera-refresh></button>
<button type="button" data-msk-camera-shot>📷</button>
<button type="button" data-msk-camera-facing>🔄</button>
</div>

initCameraCaptures()가 자동 바인딩하며, root.__mskCamera로 controller에 접근합니다. 직접 생성할 수도 있습니다:

const cam = window.MSK.ui.cameraCapture.create({
videoConstraints: { width: 1280, height: 720 }, // 선택
audio: false, // true → 영상 녹화 시 오디오 포함
onPhoto(blob, type) { /* 사진 업로드 */ },
onError(code, err) { /* mic 과 동일한 코드 */ },
});

cam.attachPreview(videoEl); // 라이브 프리뷰
cam.prime(); // 권한 요청 + 기기명 노출
cam.setFacingMode('environment'); // 후면 카메라(모바일)
const photo = await cam.capturePhoto(); // 현재 프레임 → 이미지 Blob(JPEG)
await cam.start(); // 영상 녹화 시작
const video = await cam.stop(); // 정지 → 영상 Blob
cam.release(); // 트랙 정지 + 프리뷰 해제

Events

root.addEventListener('msk:camera-photo', (event) => {
// event.detail.blob: Blob(image), event.detail.type: string
upload(event.detail.blob);
});
// 그 외: msk:camera-devices, msk:camera-error, msk:camera-state, msk:camera-recording

에러 진단

Mic Capture와 동일하게 blocked(브라우저-사이트 차단)와 blocked_system(OS/전역 차단)을 구분합니다. 문구는 4개 언어의 camera_* 키로 제공됩니다: __('msk-ui::media.camera_blocked'), camera_blocked_system, camera_not_found, camera_in_use, camera_unsupported, 그리고 camera_capture_photo / camera_facing_user / camera_facing_environment.

보안 (Permissions-Policy)

카메라도 secure-by-default입니다. 카메라를 사용하는 프로젝트만 .envCORE_PP_CAMERA=(self)를 선언하면 됩니다. Mic Capture와 동일한 opt-in 구조입니다.

Accessibility

  • 캡처는 HTTPS(secure context)에서만 동작합니다.
  • 영상/사진 데이터는 브라우저 내에서만 처리되며 소비처가 명시적으로 업로드할 때만 전송됩니다.