blob: 0504c03ea42e7b04b2df337eab38396a707ba43a [file] [log] [blame]
<html>
<body id="body">
<h1>WebRTC Feed Switch Test</h1>
<p>Status: <span id="status">not-started</span></p>
</body>
<script type="text/javascript" src="webrtc_test_utilities.js"></script>
<script type="text/javascript" src="peerconnection-multiple-streams.js"></script>
<script type="text/javascript">
const $ = document.getElementById.bind(document);
const MAIN_FEED_RESOLUTION = {w:1280, h:720};
// This resolution is typical for a small feed in a video call.
const SMALL_FEED_RESOLUTION = {w:182, h:136};
class TestRunner {
constructor(numConnections, runtimeSeconds, iterationDelayMillis) {
this.runtimeSeconds = runtimeSeconds;
this.iterationDelayMillis = iterationDelayMillis;
this.videoElements = [];
this.mainFeed = null;
this.peerConnections = [];
this.numConnections = numConnections;
this.iteration = 0;
this.startTime = 0; // initialized to dummy value
this.status = this.getStatusInternal_();
}
runTest() {
for (let i = 0; i < this.numConnections; i++) {
const videoElement = document.createElement('video');
videoElement.autoplay = true;
$('body').appendChild(videoElement);
if (!this.mainFeed) {
// The first created is the main feed.
setSize(videoElement, MAIN_FEED_RESOLUTION);
this.mainFeed = videoElement;
} else {
setSize(videoElement, SMALL_FEED_RESOLUTION);
this.videoElements.push(videoElement);
}
this.peerConnections.push(new PeerConnection(
videoElement, [MAIN_FEED_RESOLUTION], false));
}
const promises = this.peerConnections.map((conn) => conn.start());
Promise.all(promises)
.then(() => {
this.startTime = Date.now();
this.switchFeedLoop();
})
.catch((e) => {throw e});
}
switchFeedLoop() {
this.iteration++;
this.status = this.getStatusInternal_();
$('status').textContent = this.status;
if (this.status == 'ok-done') {
reportTestSuccess();
} else {
const switchWith = Math.floor(Math.random() * this.videoElements.length);
const newMainSrc = this.videoElements[switchWith].srcObject;
this.videoElements[switchWith].srcObject = this.mainFeed.srcObject;
this.mainFeed.srcObject = newMainSrc;
setTimeout(
() => this.switchFeedLoop(), this.iterationDelayMillis);
}
}
getStatus() {
return this.status;
}
getStatusInternal_() {
if (this.iteration == 0) {
return 'not-started';
}
const timeSpent = Date.now() - this.startTime;
if (timeSpent >= this.runtimeSeconds * 1000) {
return 'ok-done';
} else {
return `running, iteration: ${this.iteration}`;
}
}
}
function setSize(element, size) {
element.setAttribute('style', `width:${size.w}px;height:${size.h}px`);
}
function startTest(
runtimeSeconds, numPeerConnections, iterationDelayMillis) {
const testRunner = new TestRunner(
numPeerConnections, runtimeSeconds, iterationDelayMillis);
testRunner.runTest();
}
function getStatus() {
return testRunner ? testRunner.getStatus() : 'not-initialized';
}
</script>