Home | History | Annotate | Download | only in video_WebRtcCamera
      1 <!DOCTYPE html>
      2 <html>
      3 <head><title>GetUserMedia test</title></head>
      4 <body>
      5   <script src="ssim.js"></script>
      6   <script src="blackframe.js"></script>
      7 <script>
      8 
      9 var resolutions = [[640, 480],
     10                    [1280, 720]];
     11 var results = {};
     12 var isTestDone = 0;
     13 var durationMs = 20000;
     14 
     15 function testNextResolution() {
     16   var nextResolution = resolutions.shift();
     17   if (nextResolution == undefined) {
     18     reportTestDone();
     19     return;
     20   }
     21   var test = new CameraTest(nextResolution);
     22   test.start();
     23   setTimeout(
     24     function() {
     25       test.stop();
     26       testNextResolution();
     27     },
     28     durationMs);
     29 }
     30 
     31 function reportTestDone() {
     32   console.log('tests completed');
     33   isTestDone = 1;
     34 }
     35 
     36 function getResults() {
     37   return results;
     38 }
     39 
     40 function resolutionMatchesIndependentOfRotation(aWidth, aHeight,
     41                                                 bWidth, bHeight) {
     42   return (aWidth === bWidth && aHeight === bHeight) ||
     43          (aWidth === bHeight && aHeight === bWidth);
     44 }
     45 
     46 function saveResult(resolution, verdict) {
     47   results[resolution] = verdict;
     48 }
     49 
     50 function CameraTest(resolution) {
     51   this.resolution = resolution;
     52   this.localVideo = document.createElement('video');
     53   this.localVideo.id = 'local-video';
     54   this.localVideo.autoplay = true;
     55   document.body.appendChild(this.localVideo);
     56   this.localStream = null;
     57   this.canvas = document.createElement('canvas');
     58   this.context = this.canvas.getContext('2d');
     59   this.previousFrame = [];
     60   this.identicalFrameSsimThreshold = 0.985;
     61   this.frameComparator = new Ssim();
     62   this.results = {cameraErrors: [],
     63       frameStats: {numBlackFrames: 0, numFrozenFrames:0, numFrames: 0}};
     64 
     65   this.constraints = {
     66     "audio": false,
     67     "video": {
     68       "mandatory" : {
     69           "maxWidth": this.resolution[0].toString(),
     70           "maxHeight": this.resolution[1].toString(),
     71           "minWidth": this.resolution[0].toString(),
     72           "minHeight": this.resolution[1].toString()
     73       },
     74     }
     75   };
     76 }
     77 
     78 CameraTest.prototype = {
     79 
     80   start: function() {
     81     this.localVideo.addEventListener('play',
     82         this.startCheckingVideoFrames.bind(this), false);
     83     navigator.getUserMedia = navigator.getUserMedia ||
     84         navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
     85 
     86     navigator.getUserMedia(this.constraints, this.gotLocalStream.bind(this),
     87         this.gotUserMediaError.bind(this));
     88   },
     89 
     90   gotLocalStream: function(stream) {
     91     this.localStream = stream;
     92     this.localVideo.src = window.URL.createObjectURL(stream);
     93   },
     94 
     95   gotUserMediaError: function(error) {
     96     console.log('navigator.getUserMedia error: ', error);
     97     this.results.cameraErrors.push('GetUserMedia error: ' + error.toString());
     98   },
     99 
    100   startCheckingVideoFrames: function() {
    101     if (!resolutionMatchesIndependentOfRotation(this.localVideo.videoWidth,
    102         this.localVideo.videoHeight, this.resolution[0], this.resolution[1])) {
    103       this.results.cameraErrors.push('resolution', 'Got ' +
    104           this.localVideo.videoWidth + 'x' + this.localVideo.videoHeight +
    105           ', expected ' + this.resolution[0] + 'x' + this.resolution[1] +
    106           ' or rotated version thereof');
    107     }
    108 
    109     this.videoFrameChecker = setInterval(this.checkVideoFrame.bind(this), 20);
    110   },
    111 
    112   checkVideoFrame: function() {
    113     this.context.drawImage(this.localVideo, 0, 0, this.canvas.width,
    114       this.canvas.height);
    115     var imageData = this.context.getImageData(0, 0, this.canvas.width,
    116       this.canvas.height);
    117 
    118     if (isBlackFrame(imageData.data, imageData.data.length)) {
    119       this.results.frameStats.numBlackFrames++;
    120     }
    121 
    122     if (this.frameComparator.calculate(this.previousFrame, imageData.data) >
    123       this.identicalFrameSsimThreshold) {
    124       this.results.frameStats.numFrozenFrames++;
    125     }
    126 
    127     this.previousFrame = imageData.data;
    128     this.results.frameStats.numFrames++;
    129   },
    130 
    131   stop: function() {
    132     clearInterval(this.videoFrameChecker);
    133     saveResult(this.resolution, this.results);
    134     this.localStream.getTracks().forEach(function(track) {
    135       track.stop();
    136     });
    137     document.body.removeChild(this.localVideo);
    138   },
    139 }
    140 
    141 window.onload = testNextResolution;
    142 window.onerror = function (message, filename, lineno, colno, error) {
    143   console.log("Something went wrong, here is the stack trace --> %s",
    144       error.stack);
    145 };
    146 </script>
    147 </body>
    148 </html>
    149