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