24

I am capturing the user's camera, i want to catch the picture with the best resolution possible, so my code is something like the snippet below,

I want to read the resolution details from the incoming stream, so i can set it as video height and width, which I ll use to click snapshot, I want the snapshot to be of best quality offered by the stream, is this possible( to read resolution details from stream variable) ?

EDIT : I am transmitting the video using webrtc so I would also like to find out the frame rate of the transmitted videostream

$(document).ready(function(){

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


if(navigator.getUserMedia){
  navigator.getUserMedia({ video: true, audio:true}, function(stream) {
    var video =  $('#video')[0];
   video.src = window.URL.createObjectURL(stream);
    video.muted=true;
    //$('#video').hide();
  },  function(){
    showMessage('unable to get camera', 'error');
  });
}else{
    showMessage('no camera access mate.', 'error');
}



function showMessage(msg,type) { // type 'success' or 'error'
    $('#msg').text(msg);
}

})

the html code:

<div id='msg' class'message'></div>
  <div >
    <video id='video' autoplay></video>
  </div>
mido
  • 24,198
  • 15
  • 92
  • 117

3 Answers3

48

navigator.mediaDevices.getUserMedia() method returns MediaStream object with you video and audio streams. This MediaStream object has getVideoTracks() and getAudioTracks() methods.

getVideoTracks()[0] returns video stream from local webcam. This videotrack object has getSettings() method returning some usefull properties like:

stream.getVideoTracks()[0].getSettings().deviceId
stream.getVideoTracks()[0].getSettings().frameRate
stream.getVideoTracks()[0].getSettings().height
stream.getVideoTracks()[0].getSettings().width
stream.getVideoTracks()[0].getSettings().frameRate

Result, for example:

aspectRatio: 1.3333333333333333

deviceId: "e85a2bd38cb0896cc6223b47c5d3266169524e43b6ab6043d8dd22d60ec01a2f"

frameRate: 30

height: 480

width: 640


aspectRatio -- 4x3(1.3333333333333333) or 16x9 (fullscreen or not),

deviceId -- webcam Id,

framRate -- framerate of your videostream,

width -- video width,

height -- video height.

Ratmir Asanov
  • 6,237
  • 5
  • 26
  • 40
Eugene
  • 492
  • 4
  • 9
  • 4
    please add some description to explain answer. – jjj Oct 06 '17 at 09:22
  • 1
    descriptions added – Eugene Oct 26 '17 at 10:07
  • 1
    Unfortunately, the width and height from MediaTrackSettings are not adjusted for the device's orientation. The two would be swapped when compared with the video element's videoWidth and videoHeight. – cleong Apr 15 '18 at 02:03
  • 1
    Note that this is broken on Android and will always return the dimensions you specified in the constraints. – Florian Wendelborn Nov 28 '18 at 18:53
  • 1
    Same in Chrome on Windows. Rather than calling getSettings(), call getCapabilities(), which will return the actual resolution and framerate data. – Bas Feb 06 '20 at 09:33
13

You can get video stream native resolution from the video element once the stream is attached to it via onloadedmetadata. This does not provide frame rate information.

  navigator.getUserMedia({ video: true, audio:true}, function(stream) {
    var video =  $('#video')[0];
    video.src = window.URL.createObjectURL(stream);
    video.muted=true;
    video.onloadedmetadata = function() {
      console.log('width is', this.videoWidth);
      console.log('height is', this.videoHeight);
    }
    //$('#video').hide();
  },  function(){
    showMessage('unable to get camera', 'error');
  });

Per the W3C draft, the media track within the stream should provide this information, but in practice browsers have yet to implement it.

The getCapabilities() method returns the dictionary of the names of the constrainable properties that the object supports.

mygzi
  • 1,303
  • 1
  • 11
  • 21
  • 1
    Note that this only works if you haven't modified the width and height of the stream. If you have then you will just get the settings for the local video window rather than the webrtc stream (which will be different). – CpnCrunch Nov 27 '17 at 17:32
1

here's my vanillaJS Promise-based solution to get a MediaStream video dimensions :

/**
 * @method streamSize : get MediaStream video dimensions
 * @param {MediaStream} stream : some stream with a video track
 */
static streamSize(stream) {

    return new Promise((resolve, reject) => {

        let video = document.createElement("video");

        video.muted = true;

        video.srcObject = stream;
        
        video.onloadedmetadata = () => {

            let dimensions = {
                width: video.videoWidth, 
                height: video.videoHeight
            };

            video = null;

            resolve(dimensions);

        };
    
    });
    
}
nicopowa
  • 459
  • 3
  • 11