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