0fe4d140 by David LaPalomento

Create player and mock environment

Load sinon to mock out XHR and timer functions. Create a player with the HLS tech on load. Send a fake response for the master playlist.
1 parent b0431885
......@@ -37,6 +37,11 @@
can helpful to understand how tweaks to the switching
logic will affect playback.
</p>
<p>
Flash security restrictions prevent this page from running
over the file protocol. Run <code>grunt connect</code> and
then <a href="http://localhost:9999/test/switcher">reload.</a>
</p>
</header>
<section>
<h2>Timeline</h2>
......@@ -63,9 +68,14 @@
capacity.
<button type=button class=add-time-period>Add time period</button>
</p>
<label>
The video bitrate is <input type=number min=1 value=1024> bits per second
</label>
The video is available at
<ul>
<li><input class=bitrate type=number min=1 value=65536> bits per second</li>
<li><input class=bitrate type=number min=1 value=153600> bits per second</li>
<li><input class=bitrate type=number min=1 value=450560> bits per second</li>
<li><input class=bitrate type=number min=1 value=921600> bits per second</li>
<li><input class=bitrate type=number min=1 value=1536000> bits per second</li>
</ul>
</form>
</section>
</article>
......@@ -78,13 +88,21 @@
<h3>videojs-contrib-hls</h3>
</footer>
</div>
<div id=fixture></div>
<script src="../../node_modules/sinon/lib/sinon.js"></script>
<script src="../../node_modules/sinon/lib/sinon/util/event.js"></script>
<script src="../../node_modules/sinon/lib/sinon/util/fake_xml_http_request.js"></script>
<script src="../../node_modules/sinon/lib/sinon/util/xhr_ie.js"></script>
<script src="../../node_modules/sinon/lib/sinon/util/fake_timers.js"></script>
<script src=js/vendor/d3.min.js></script>
<script src="js/vendor/d3.min.js"></script>
<script src="../../node_modules/video.js/dist/video-js/video.js"></script>
<script src="../../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
<script src="../../src/videojs-hls.js"></script>
<script src="../../src/stream.js"></script>
<script src="../../src/m3u8/m3u8-parser.js"></script>
<script src="../../src/playlist-loader.js"></script>
<script src=js/switcher.js></script>
<script src="js/switcher.js"></script>
</body>
</html>
......
(function(window, document) {
'use strict';
var duration = 9 * 100,
var segmentDuration = 9, // seconds
duration = segmentDuration * 100, // 100 segments
clock,
fakeXhr,
requests,
runSimulation,
player,
runButton,
parameters,
addTimePeriod,
......@@ -12,6 +18,20 @@
displayTimeline;
// mock out the environment and dependencies
clock = sinon.useFakeTimers();
fakeXhr = sinon.useFakeXMLHttpRequest();
requests = [];
fakeXhr.onCreate = function(xhr) {
requests.push(xhr);
};
videojs.options.flash.swf = '../../node_modules/video.js/dist/video-js/video-js.swf';
videojs.Hls.SegmentParser = function() {
this.getFlvHeader = function() {
return new Uint8Array([]);
}
};
// a dynamic number of time-bandwidth pairs may be defined to drive the simulation
addTimePeriod = document.querySelector('.add-time-period');
networkTimeline = document.querySelector('.network-timeline');
......@@ -30,37 +50,73 @@
}
networkTimeline.appendChild(fragment);
});
// collect the simulation parameters
parameters = function() {
var times = Array.prototype.slice.call(document.querySelectorAll('.time')),
bandwidths = document.querySelectorAll('input.bandwidth');
return times.reduce(function(conditions, time, i) {
return conditions.concat({
time: +time.value,
bandwidth: +bandwidths[i].value
});
}, []);
bandwidths = document.querySelectorAll('input.bandwidth'),
playlists = Array.prototype.slice.call(document.querySelectorAll('input.bitrate'));
return {
playlists: playlists.map(function(input) {
return +input.value;
}),
bandwidths: times.reduce(function(conditions, time, i) {
return conditions.concat({
time: +time.value,
bandwidth: +bandwidths[i].value
});
}, [])
};
};
// run the simulation
runSimulation = function(options) {
var results = [],
bandwidths = options.bandwidths,
fixture = document.getElementById('fixture'),
video,
t,
i;
options.sort(function(left, right) {
// clean up the last run if necessary
if (player) {
player.dispose();
};
// initialize the HLS tech
fixture.innerHTML = '';
video = document.createElement('video');
fixture.appendChild(video);
player = videojs(video, {
techOrder: ['hls'],
sources: [{
src: 'http://example.com/master.m3u8',
type: 'application/x-mpegurl'
}]
});
player.ready(function() {
var master = '#EXTM3U\n' +
options.playlists.reduce(function(playlists, value) {
return playlists +
'#EXT-X-STREAM-INF:' + value + '\n' +
value + '\n';
}, '');
requests.pop().respond(200, null, master);
});
// bandwidth
bandwidths.sort(function(left, right) {
return left.time - right.time;
});
for (t = i = 0; t < duration; t++) {
while (options[i + 1] && options[i + 1].time <= t) {
while (bandwidths[i + 1] && bandwidths[i + 1].time <= t) {
i++;
}
results.push({
time: t,
bandwidth: options[i].bandwidth
bandwidth: bandwidths[i].bandwidth
});
}
return results;
......@@ -137,7 +193,7 @@
};
})();
displayTimeline(runSimulation(parameters()));
})(window, document);
......