web-dev-qa-db-ja.com

FirefoxのgetUserMedia()ビデオサイズ&Chromeは異なります

私はgetUserMedia()を使用していますが、制約を実装する場合(以下を参照)、制約はChromeでのみ機能し、Mozillaでは機能しません。mozillaのサイズは常に引き伸ばされて表示され、最終的には丁目で1つ。

_var vid_constraints = {
    mandatory: {
        maxHeight: 180,
        maxWidth: 320
    }
}
var constraints = { audio: false, video: vid_constraints };
navigator.getUserMedia(constraints, successCallback, errorCallback);
_

いくつか読んだ後、MozGetUserMedia()は解像度の制約をサポートしていないようです。 FirefoxとChromeの両方で同じサイズ/解像度になるようにビデオを表示する方法はありますか?

ありがとう

編集スナップショットを作成するようにスクリプトを変更しました。スナップショットをMozとChromeに保存しました-結果は次のとおりです。

ChromeMozilla

(左= Chrome、右= Mozilla

これは問題を明らかにするかもしれないと思った。アスペクト比のようです。

編集(テイク2)

はい-chrome 1のアスペクト比は16:9ですが、Mozのアスペクト比は4:3です。これを変更するにはどうすればよいですか?

11
sidewaiise

4月15日編集

@ jib 彼の 素晴らしい答え で述べたように、

Firefox [38+]は、getUserMedia()で制約のサブセットをサポートしますが、ChromeおよびOperaが使用している古い構文はサポートしません。必須/オプション構文は1年前に廃止され、minWidthとminHeightはその1年前に廃止されました。

したがって、仕様で承認されている新しい構文は次のとおりです。

var constraints = {
    audio: false,
    video: {
        width: { min: 1024, ideal: 1280, max: 1920 },
        height: { min: 576, ideal: 720, max: 1080 },
    }
};

ただし、この構文はChromeでエラーをスローします。コメントに記載されているように、 [〜#〜] pr [〜#〜] to adapter.jsが作成されました。これには、古いFFとクロムの polyfill が含まれます。

これが私の試みです。chromeのみ(ただし、FFの新しいバージョンは魔法の隠されたrequire:['width', 'height']を受け入れるようです。

        var video_constraints = {
                width: { min: 320, max: 480 },
                height: { min: 240, max: 360 },
                require: ["width", "height"] // needed pre-Firefox 38 (non-spec)
                };
                

        function getMedia(){
     
        if(navigator.webkitGetUserMedia){
                                var wkConstraints={mandatory: {} };
                                var c = video_constraints;
                                for(var i in c){
                                        switch(i){
                                         case 'width': for(j in c[i]){
                                                  switch(j){
                                                         case 'max': wkConstraints.mandatory.maxWidth = c[i][j]; break;
                                                         case 'min': wkConstraints.mandatory.minWidth = c[i][j]; break;
                                                         case 'exact': wkConstraints.mandatory.minWidth = wkConstraints.mandatory.maxWidth = c[i][j]; break;
                                                         }
                                                }; break;

                                         case 'height': for(var j in c[i]){
                                                  switch(j){
                                                         case 'max': wkConstraints.mandatory.maxHeight = c[i][j]; break;
                                                         case 'min': wkConstraints.mandatory.minHeight = c[i][j]; break;
                                                         case 'exact': wkConstraints.mandatory.minHeight = wkConstraints.mandatory.maxHeight = c[i][j]; break;
                                                         }
                                                }; break;
                                         default: break;
                                        }
                                }
                                video_constraints = wkConstraints;
                                }

                navigator.getUserMedia = (      navigator.getUserMedia ||
                                                                navigator.webkitGetUserMedia ||
                                                                navigator.mozGetUserMedia);

        if(!navigator.getUserMedia){
                        alert("your browser doesn't support getUserMedia")
                        }

                
                navigator.getUserMedia(
                {
                                video: video_constraints,
                                audio: false,
                                },
                        
                                function(stream) {
                                        if (navigator.mozGetUserMedia) {
                                                video.mozSrcObject = stream;
                                                } 
                                        else {
                                                var URL = window.URL || window.webkitURL;
                                                video.src = URL.createObjectURL(stream);
                                                }
                                        video.play();
                                        },

                                function(err) {
                                        console.log(err);
                                        }
                                );
                }

          var video= document.querySelector('video');
          video.addEventListener('playing', loopStart, false);                     
          function loopStart(){
                  this.removeEventListener('playing', loopStart);
                  if(this.videoHeight === 0){
                        window.setTimeout(function() {
                          this.pause();
                          this.play();
                          loopStart();
                        }, 100);
                        }
                        else {
                          this.setAttribute('width', this.videoWidth);
                          this.setAttribute('height', this.videoHeight);
                          }
                 }
          getMedia();
<video/>

最初の答え

それで、あなたがあなた自身の質問に答える前に、私はあなたにこれを書き始めました。

コメントに記載されているように、サイズ変更されたキャンバスに合うようにビデオの各フレームを描画しています。

var video, canvas, streaming = false,
  constrainedWidth = 320,
  constrainedHeight = 180;

function streamCam() {
  navigator.getMedia = (navigator.getUserMedia ||
    navigator.webkitGetUserMedia ||
    navigator.mozGetUserMedia ||
    navigator.msGetUserMedia);

  //**Deprecated Now, see the update**
  var video_constraints = {
    "mandatory": {
      "minWidth": constrainedWidth,
      "minHeight": constrainedHeight,
      "minFrameRate": "30"
    },
    "optional": []
  }

  navigator.getMedia({
      video: video_constraints,
      audio: false
    },
    function(stream) {
      if (navigator.mozGetUserMedia) {
        video.mozSrcObject = stream;
      } else {
        var vendorURL = window.URL || window.webkitURL;
        video.src = vendorURL.createObjectURL(stream);
      }
      video.play();
    },
    function(err) {
      console.log("An error occured! " + err);
      streamCam();
    }
  );


}

function FFResize() {
  canvas.width = constrainedWidth;
  canvas.height = constrainedHeight;
  canvas.getContext('2d').drawImage(video, 0, 0, constrainedWidth, constrainedHeight);
  setTimeout(function() {
    requestAnimationFrame(FFResize)
  }, 10);
}


window.onload = function() {
  video = document.querySelector('#video'),
    canvas = document.querySelector('#canvas');

  streamCam();

  video.addEventListener('playing', function(ev) {
    if (!streaming) {
      if (video.videoHeight === 0) {
        window.setTimeout(function() {
          video.pause();
          video.play();
        }, 100);
      } else {
        video.setAttribute('width', video.videoWidth);
        video.setAttribute('height', video.videoHeight);
        canvas.setAttribute('width', constrainedWidth);
        canvas.setAttribute('height', constrainedHeight);
        streaming = true;
        requestAnimationFrame(FFResize);
      }
    }
  }, false);

};
#canvas {
  position: fixed;
  top: 0;
}
<video id="video"></video>
<canvas id="canvas"></canvas>

これはその仕事をしますが、あなたが指摘したように、制約はまだ開発中であり、Firefoxでそれらを機能させる唯一の方法は、すべてのブラウザのmedia.navigator.video.default_about:configに手動で設定することです。

19
Kaiido

OK。久しぶりです。

次のコードが見つかりました:

_var vid_constraints = {
    mandatory: {
        maxHeight: 180,
        maxWidth: 320
    }
}
_

実際には役に立たない。よりうまく機能するのは、単に使用することです

_navigator.getUserMedia({audio: true, video: true}, function(stream){..},function(e){...});
_

そして、CSSまたはインラインHTMLを介してビデオのサイズを設定するだけです。私のアプリケーションでは、ビデオコンテンツをキャンバスにコピーするだけでよいため、これは問題なく機能しました。最終的にはうまくいきました。

したがって、結論として、問題は制約オプションにあるように見えました。複数のブラウザで動作させようとしている場合は、それらから離れてください。

カメラの解像度をより適切に制御する必要がある場合、これは機能しない可能性があります。解像度を有限に制御する必要がある場合は、条件付き(つまり、if(navigator.mozGetUserMedia){... //compatible resolutions etc ...})を試してください。

すぐにすべてのブラウザで処理される標準のgetUserMedia関数があることを祈っています! :)

単なる参考資料です。私はいくつかのfiddleJSコードをフォークし、それを変更してChromeおよびMozilla: http://jsfiddle.net/sidewaiise/Laq5txvq/

1
sidewaiise