카메라 팬, 틸트, 줌 제어


원문: François Beaufort, https://web.dev/camera-pan-tilt-zoom/

드디어 카메라의 팬, 틸트, 줌 기능을 웹에서 사용할 수 있게 되었다. (역자: 카메라에서 팬은 수평 방향 회전, 틸트는 수직 방향 회전, 줌은 확대와 축소를 의미한다.)

회의실 규모의 화상 회의 솔루션은 팬, 틸트, 줌(PTZ, pan-tilt-zoom) 카메라를 제공하여 소프트웨어가 카메라로 회의 참가자를 가리킬 수 있도록 하였다. 크롬 87부터 MediaDevices.getUserMedia()MediaStreamTrack.applyConstraints()에 있는 미디어 트랙 제한 인자를 사용하여 카메라의 팬, 틸트, 줌 기능을 웹사이트에서 사용할 수 있다.

API 사용하기

기능 탐지

하드웨어에 대한 기능 탐지는 당신이 흔히 사용하던 것과는 다르다. navigator.mediaDevices.getSupportedConstraints()"pan", "tilt", "zoom" 제한 인자가 있으면 브라우저가 카메라 PTZ 제어 API를 지원한다는 뜻이지만, 카메라 하드웨어가 PTZ를 지원하는지는 알 수 없다. 카메라 PTZ 제어는 크롬 87부터 데스크탑과 안드로이드에서 지원된다. 단, 안드로이드는 줌만 지원한다.

const supports = navigator.mediaDevices.getSupportedConstraints();
if (supports.pan && supports.tilt && supports.zoom) {
  // 브라우저가 카메라 PTZ를 지원하는 경우
}

카메라 PTZ 액세스 요청

웹사이트는 사용자가 프롬프트로 카메라의 PTZ 권한을 명시적으로 부여받은 경우에만 카메라 PTZ를 제어할 수 있다.

카메라 PTZ 액세스를 요청하기 위해서는 아래처럼 PTZ 제한 인자와 함께 navigator.mediaDevices.getUserMedia()를 호출해야 한다. 그러면 사용자에게 카메라와 PTZ 접근에 대한 권한을 부여하라는 프롬프트가 뜨게 된다.

Camera PTZ user prompt 카메라 PTZ 액세스 요청 프롬프트

반환된 프로미스는 사용자에게 카메라 비디오 스트림을 표시하는데 사용되는 MediaStream와 함께 이행된다. 만약 카메라가 PTZ를 지원하지 않는다면 사용자는 일반 카메라 프롬프트를 받게 된다.

try {
  // 한 번의 호출로 카메라와 PTZ 액세스 권한을 모두 부여하라는 프롬프트가 사용자에게 표시된다.
  // 만약 카메라가 PTZ를 지원하지 않는다면 단순히 일반적인 카메라 사용 프롬프트로 돌아간다.
  const stream = await navigator.mediaDevices.getUserMedia({
    // 웹사이트는 현재 팬, 틸트, 줌 설정을 변경하지 않고 카메라 PTZ를 제어하도록 요청한다.
    video: { pan: true, tilt: true, zoom: true }
  });

  // 카메라 비디오 스트림을 사용자에게 보여준다.
  document.querySelector("video").srcObject = stream;
} catch (error) {
  // 사용자가 프롬프트에서 권한을 부여하지 않았거나 사용할 수 있는 미디어 장치가 없을 경우
  console.log(error);
}

이전에 PTZ 액세스 권한 없이 권한을 부여한 카메라가 현재 사용 가능하여도 PTZ 액세스 권한은 자동으로 얻지 못한다. 이는 카메라의 PTZ 지원 여부와 관계없다. 권한은 다시 요청되어야 한다. 다행히 권한 API를 이용하여 PTZ 권한 상태를 확인하고 요청할 수 있다.

try {
  const panTiltZoomPermissionStatus = await navigator.permissions.query({
    name: "camera",
    panTiltZoom: true
  });

  if (panTiltZoomPermissionStatus.state == "granted") {
    // 사용자가 해당 웹사이트에 카메라 PTZ 제어 권한을 부여한 경우
  }

  panTiltZoomPermissionStatus.addEventListener("change", () => {
    // 사용자가 카메라 PTZ 제어 권한을 변경한 경우
  });
} catch (error) {
  console.log(error);
}

크로미움 기반 브라우저가 카메라 PTZ를 지원하는지 확인하려면 내부 about://media-internals 페이지로 이동하여 "비디오 캡쳐" 탭의 "Pan-Tilt-Zoom" 메뉴를 확인한다.

Internal page to debug PTZ camera support.
PTZ 카메라 지원 여부 확인 용 내부 페이지

카메라 PTZ 제어

앞서 얻은 stream 객체에서 MediaStreamTrack 미리보기를 사용하여 카메라 PTZ 기능 및 설정을 조작한다. MediaStreamTrack.getCapabilities()는 지원되는 기능과 허용되는 범위 또는 값 객체를 반환한다. 동일하게, MediaStreamTrack.getSettings()는 현재 설정을 반환한다.

팬, 틸트, 줌 기능과 설정은 카메라가 PTZ를 지원하고 사용자가 카메라에 PTZ 권한을 부여한 경우에만 사용할 수 있다.

카메라 PTZ 제어

아래 예시처럼 적절한 PTZ 고급 제한 인자와 함께 videoTrack.applyConstraints()를 호출하여 카메라 팬, 틸트, 줌을 제어한다. 반환된 프로미스는 성공했을 경우 이행한다. 실패하는 경우는 아래와 같다.

  • 카메라의 PTZ 권한이 부여되지 않음.
  • 카메라 하드웨어가 PTZ를 지원하지 않음
  • 페이지가 사용자에게 표시되지 않음. 활성화된 페이지가 변경된 것을 감지하기 위해 Page Visibility API를 사용한다.
// 비디오 트랙 기능과 설정을 얻는다.
const [videoTrack] = stream.getVideoTracks();
const capabilities = videoTrack.getCapabilities();
const settings = videoTrack.getSettings();

// 카메라가 팬을 지원하고 PTZ 액세스 권한이 부여된 경우 사용자가 이를 제어하도록 한다.
if ("pan" in settings) {
  const input = document.querySelector("input[type=range]");
  input.min = capabilities.pan.min;
  input.max = capabilities.pan.max;
  input.step = capabilities.pan.step;
  input.value = settings.pan;

  input.addEventListener("input", async () => {
    await videoTrack.applyConstraints({ advanced: [{ pan: input.value }] });
  });
}

if ("tilt" in settings) {
  // 마찬가지로 틸트도 제어할 수 있다.
}
if ("zoom" in settings) {
  // 마찬가지로 줌도 제어할 수 있다.
}

이상적인 카메라 PTZ 제한 값과 함께 navigator.mediaDevices.getUserMedia()를 호출하여 카메라의 팬, 틸트, 줌을 설정할 수도 있다. 미리 카메라의 PTZ 기능을 알고 있으면 편하다. 참고로, 필수적인 제한 인자(min, max, exact)는 여기서 사용할 수 없다.

const stream = await navigator.mediaDevices.getUserMedia({
  // 웹사이트는 기존의 카메라 팬을 재설정하도록 요청한다.
  video: { pan: 0, deviceId: { exact: "myCameraDeviceId" } }
});

체험하기

Glitch에서 데모를 실행하여 API를 사용해보고 소스코드를 확인해 볼 수 있다.

https://ptz.glitch.me

팁: PTZ를 지원하는 카메라가 없는 경우 --use-fake-device-for-media-stream 스위치로 크롬을 실행하여 컴퓨터에서 카메라를 시뮬레이션 할 수 있다.

보안 고려 사항

스펙 저자는 사용자 제어, 투명성, 인체 공학을 사용하여 해당 API를 설계하고 구현했다. 이 API를 사용하는 기능은 주로 미디어 캡쳐와 스트림 API와 동일한 권한 모델에 의해 제한된다. 사용자 프롬프트의 응답으로 웹사이트는 페이지가 사용자에게 보일 때만 카메라 PTZ를 제어할 수 있다.

도움이 될 자료

감사

이 글은 Joe MedleyThomas Steiner가 리뷰해주었다. 스펙 작성과 구현을 한 인텔의 Rijubrata BhaumikEero Häkkinen에게도 감사를 표한다.

곽희나2020.10.14
Back to list