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 10var resolutions = [[640, 480], 11 [1280, 720]]; 12var results = {}; 13var testProgress = 0; 14var durationMs = 20000; 15 16function 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 33function reportTestDone() { 34 console.log('tests completed'); 35 testProgress = 1; 36} 37 38function getResults() { 39 return results; 40} 41 42function saveResult(resolution, verdict) { 43 results[resolution] = verdict; 44} 45 46function 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 73CameraTest.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 128window.onload = testNextResolution; 129window.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