やりたいこと
- webカメラの映像をvideo要素に表示する
- video要素からcanvasに描画する
- canvasからStreamを生成する
ブラウザごとにgetUserMediaの挙動が異なる
全部のブラウザで確かめたわけではないですが、少なくともChromeとFireFoxではgetUserMediaをする際に指定する制約(MediaConstraints)で値を指定した時の挙動が異なります。
navigater.mediaDevices.getUserMedia({ // ← このときに指定する値がconstraintsになります
video: {
width: "640px",
height: "360px"
}
}) .then((stream) => {...})
Chromeの挙動
- カメラが対応している解像度の範囲内なら指定した解像度でstreamを取得してくれる
FireFoxの挙動
- カメラが対応している解像度のなかで指定した解像度に近い値を選んでくれる
またブラウザごとに対応しているMediaConstraintsの内容が異なるのできちんと確かめなければいけません。
getSupportedConstraintsを使用すると、サポートされている値がわかります。
例えば現時点ではアスペクト比(aspectRatio)はChromeではサポートされていますが、FireFoxではサポートされていません。
navigator.mediaDevices.getSupportedConstraints();
Chromeと同じように、FireFoxでカメラが対応していなくても指定した解像度の映像を取得したいと思った時に、canvasに描画してさらにStreamを取得するという方法にたどり着きました。
sample
See the Pen getUserMedia Constraint Test by mossan245 (@mossan245) on CodePen.
video要素からcanvasに表示&Streamを取得する
Webカメラの映像をgetUserMediaで取得後、canvasに表示します。
ここでは、映像と同じFPS30で描画したいので、setIntervalを使用しています。
const video = document.getElementById("player");
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext('2d');
setInterval(() => {
if (canvas && ctx){
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
}
}, 10000/30);
canvasのcreateStreamメソッドで、canvasからMediaStreamを生成することができます。
第一引数はFrameRateの値を指定することができます。
例えば映像のFPSを30からもっと少ない値に落としたいときにも使うことができます。
const canvas = document.getElementById("canvas");
const canvasStream = canvas.captureStream(30);
const videoCanvas = document.getElementById("player-canvas");
videoCanvas.srcObject = canvasStream;
sample
See the Pen Video Canvas Stream Test by mossan245 (@mossan245) on CodePen.