MediaDevices.getUserMedia() で PTZ（パン・チルト・ズーム）用の仕組みがあるのを知って試してみる

MediaDevices.getUserMedia() で PTZ（パン・チルト・ズーム）ができる仕組みを見かけて、とりあえず試してみたという話です。

●Control camera pan, tilt, and zoom
　https://web.dev/camera-pan-tilt-zoom/

![PTZ（パン・チルト・ズーム）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/8f03d3d4-59f1-1897-77d6-5cf337ac57a5.jpeg)

## デモページ

以下がデモページのようです。

●ptz.glitch.me
　https://ptz.glitch.me/

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MediaDevices.getUserMedia() で、画像のPTZ（パン・チルト・ズーム）を実現する API の件、まずはデモページでお試し。<br><br>●<a href="https://t.co/MPsfQsPQ4W">https://t.co/MPsfQsPQ4W</a><br>　<a href="https://t.co/cpFEgtlyWs">https://t.co/cpFEgtlyWs</a> <a href="https://t.co/cgG9SIGFVc">https://t.co/cgG9SIGFVc</a> <a href="https://t.co/u2aArID80T">pic.twitter.com/u2aArID80T</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1464789100657995777?ref_src=twsrc%5Etfw">November 28, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 試している時の様子
こんな感じで試せました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MediaDevices.getUserMedia() で、画像のPTZ（パン・チルト・ズーム）を実現する仕組み、<br>そのデモページ（ <a href="https://t.co/HT8tAewsXd">https://t.co/HT8tAewsXd</a> ）を試している様子を動画にしてみた。 <a href="https://t.co/COwt3IhDNU">pic.twitter.com/COwt3IhDNU</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1464797002999291907?ref_src=twsrc%5Etfw">November 28, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

自分の Webカメラは、カメラの土台が動くようなものではなく、固定の映像が取得できるだけのものです。
その中で実現しているというのを考えてみても、そして実際に使ってみた感じの挙動として、「カメラ全体の映像の一部を拡大している状況の場合 ＝ カメラで取得できている画像の一部のみを表示している状態の時、その画面の一部の表示する範囲を移動させられる」、というような挙動になっているのかなと思います。

## 技術的な部分を見ていく
### プログラムの書き方
さらに技術的な部分を見ていきます。

●mediacapture-image/ptz-explainer.md at main · w3c/mediacapture-image
　https://github.com/w3c/mediacapture-image/blob/main/ptz-explainer.md

以下のようなサンプルがのっていました。

```javascript
// User is prompted to grant both camera and PTZ access in a single call.
// If the camera does not support PTZ or user denies PTZ permission, it falls
// back to a regular camera prompt.
const videoStream = await navigator.mediaDevices.getUserMedia({
  // [NEW] Website asks to control camera PTZ as well.
  video: { pan: true, tilt: true, zoom: true },
});

// Show camera video stream to user.
const video = document.querySelector("video");
video.srcObject = videoStream;

// Get video track capabilities and settings.
const [videoTrack] = videoStream.getVideoTracks();
const capabilities = videoTrack.getCapabilities();
const settings = videoTrack.getSettings();

// [NEW] Let the user control the camera pan motion if the camera supports it
// and PTZ access is granted.
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.oninput = async (event) => {
    await videoTrack.applyConstraints({
      advanced: [{ pan: input.value }],
    });
  };
}

// [NEW] Let the user control the camera tilt motion if the camera supports it
// and PTZ access is granted.
if ("tilt" in settings) {
  // similar to the pan motion above.
}
```

### ポップアップによる許可の操作

「User is prompted to grant both camera and PTZ access in a single call.」と書かれた部分を見て、あらためてカメラ利用許可のポップアップを気にして見てみました。

カメラの許可のポップアップは 1つ、そしてカメラ利用の許可と「PTZ（パン・チルト・ズーム）の許可を同時に」という意味は、以下の画像のような形で確認できました（許可する対象の記載の後ろに、「移動」という記載も含む形になりました）。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">MediaDevices.getUserMedia() で、画像のPTZ（パン・チルト・ズーム）を実現する仕組みの件、<br>カメラ利用の許可のポップアップで「移動」の許可も求めるような記載になるか！ <a href="https://t.co/OqrJdnS1OT">pic.twitter.com/OqrJdnS1OT</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1464791728553033731?ref_src=twsrc%5Etfw">November 28, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

単純にカメラ利用のみを求める場合は、以下の表示になり、「移動」に関する話は出てきません。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">PTZ（パン・チルト・ズーム）を求めない場合の、カメラ利用のみ許可を求めるポップアップ。 <a href="https://t.co/cHOOeQnTGF">pic.twitter.com/cHOOeQnTGF</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1464791833494523907?ref_src=twsrc%5Etfw">November 28, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### 値の変更
それと、PTZ（パン・チルト・ズーム）を適用する際の処理は、以下の部分が該当しているようです。
![値の変更.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/55a9b483-a347-3e7b-cdab-4c86891ad305.jpeg)

### パーミッションの変更
パーミッションまわりの処理は、途中で変更したり、その変更を検出したりというのができそうな記載がありました。

![パーミッションの変更](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/f8e45fce-0cad-826f-cfda-49525f9ae42b.jpeg)


## おわりに
概要はつかめたかな、と思えたので、あとは何か使い道を考えつつ試せればと思っています。