2020年3月20日金曜日

getUserMedia() のアスペクト比を保つ方法

JavaScript でカメラを利用できる getUserMedia() を、様々な環境でビデオサイズのアスペクト比を保つのは、意外とコツがいる。 少しハマったので回避方法をメモしておきます。

まずビデオの解像度を変更するための基本的な関数は以下になります。 カメラを止めて設定し直すような処理を入れておくのがポイント。
let video = document.createElement("video");

function syncVideo(video, options) {
  if (video.srcObject) {
    video.srcObject.getVideoTracks().forEach(function(camera) { camera.stop(); });
  }
  navigator.mediaDevices.getUserMedia(options).then(function(stream) {
    video.srcObject = stream;
    video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
    video.play();
    requestAnimationFrame(tick);
  }).catch(function(err) {
    alert(err.message);
  });
}

このコードを利用して、PC の Chrome などで「可能な限り w, h の大きさを維持して」アスペクトを保ったビデオを起動することを考えます。 カメラの解像度が対応していなかった時にアスペクト比が崩れないようにしないといけません。 aspectRatio を exact で最優先にすれば良さそう、と以下のオプションを考えるかと思います。
const options = { video: { facingMode: "environment",
  width:w, height:h, aspectRatio:{ exact:w/h } } };
syncVideo(video, options);

しかしこのコード iOS が動かないんですよねえ。 よって、様々な解像度に対応するビデオ呼び出しは以下のように書く必要があります。
const options = { video: { facingMode: "environment",
  width:{ min:0, max:w }, height: { min:0, max:w }, aspectRatio:w/h } };
syncVideo(video, options);


わかれば単純だけど、ここに辿り着くのに凄い時間が掛かりました。

0 件のコメント: