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 @@ ...@@ -37,6 +37,11 @@
37 can helpful to understand how tweaks to the switching 37 can helpful to understand how tweaks to the switching
38 logic will affect playback. 38 logic will affect playback.
39 </p> 39 </p>
40 <p>
41 Flash security restrictions prevent this page from running
42 over the file protocol. Run <code>grunt connect</code> and
43 then <a href="http://localhost:9999/test/switcher">reload.</a>
44 </p>
40 </header> 45 </header>
41 <section> 46 <section>
42 <h2>Timeline</h2> 47 <h2>Timeline</h2>
...@@ -63,9 +68,14 @@ ...@@ -63,9 +68,14 @@
63 capacity. 68 capacity.
64 <button type=button class=add-time-period>Add time period</button> 69 <button type=button class=add-time-period>Add time period</button>
65 </p> 70 </p>
66 <label> 71 The video is available at
67 The video bitrate is <input type=number min=1 value=1024> bits per second 72 <ul>
68 </label> 73 <li><input class=bitrate type=number min=1 value=65536> bits per second</li>
74 <li><input class=bitrate type=number min=1 value=153600> bits per second</li>
75 <li><input class=bitrate type=number min=1 value=450560> bits per second</li>
76 <li><input class=bitrate type=number min=1 value=921600> bits per second</li>
77 <li><input class=bitrate type=number min=1 value=1536000> bits per second</li>
78 </ul>
69 </form> 79 </form>
70 </section> 80 </section>
71 </article> 81 </article>
...@@ -78,13 +88,21 @@ ...@@ -78,13 +88,21 @@
78 <h3>videojs-contrib-hls</h3> 88 <h3>videojs-contrib-hls</h3>
79 </footer> 89 </footer>
80 </div> 90 </div>
91 <div id=fixture></div>
81 <script src="../../node_modules/sinon/lib/sinon.js"></script> 92 <script src="../../node_modules/sinon/lib/sinon.js"></script>
82 <script src="../../node_modules/sinon/lib/sinon/util/event.js"></script> 93 <script src="../../node_modules/sinon/lib/sinon/util/event.js"></script>
83 <script src="../../node_modules/sinon/lib/sinon/util/fake_xml_http_request.js"></script> 94 <script src="../../node_modules/sinon/lib/sinon/util/fake_xml_http_request.js"></script>
84 <script src="../../node_modules/sinon/lib/sinon/util/xhr_ie.js"></script> 95 <script src="../../node_modules/sinon/lib/sinon/util/xhr_ie.js"></script>
85 <script src="../../node_modules/sinon/lib/sinon/util/fake_timers.js"></script> 96 <script src="../../node_modules/sinon/lib/sinon/util/fake_timers.js"></script>
86 <script src=js/vendor/d3.min.js></script> 97 <script src="js/vendor/d3.min.js"></script>
98
99 <script src="../../node_modules/video.js/dist/video-js/video.js"></script>
100 <script src="../../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
101 <script src="../../src/videojs-hls.js"></script>
102 <script src="../../src/stream.js"></script>
103 <script src="../../src/m3u8/m3u8-parser.js"></script>
104 <script src="../../src/playlist-loader.js"></script>
87 105
88 <script src=js/switcher.js></script> 106 <script src="js/switcher.js"></script>
89 </body> 107 </body>
90 </html> 108 </html>
......
1 (function(window, document) { 1 (function(window, document) {
2 'use strict'; 2 'use strict';
3 var duration = 9 * 100, 3 var segmentDuration = 9, // seconds
4 duration = segmentDuration * 100, // 100 segments
5
6 clock,
7 fakeXhr,
8 requests,
4 9
5 runSimulation, 10 runSimulation,
11 player,
6 runButton, 12 runButton,
7 parameters, 13 parameters,
8 addTimePeriod, 14 addTimePeriod,
...@@ -12,6 +18,20 @@ ...@@ -12,6 +18,20 @@
12 18
13 displayTimeline; 19 displayTimeline;
14 20
21 // mock out the environment and dependencies
22 clock = sinon.useFakeTimers();
23 fakeXhr = sinon.useFakeXMLHttpRequest();
24 requests = [];
25 fakeXhr.onCreate = function(xhr) {
26 requests.push(xhr);
27 };
28 videojs.options.flash.swf = '../../node_modules/video.js/dist/video-js/video-js.swf';
29 videojs.Hls.SegmentParser = function() {
30 this.getFlvHeader = function() {
31 return new Uint8Array([]);
32 }
33 };
34
15 // a dynamic number of time-bandwidth pairs may be defined to drive the simulation 35 // a dynamic number of time-bandwidth pairs may be defined to drive the simulation
16 addTimePeriod = document.querySelector('.add-time-period'); 36 addTimePeriod = document.querySelector('.add-time-period');
17 networkTimeline = document.querySelector('.network-timeline'); 37 networkTimeline = document.querySelector('.network-timeline');
...@@ -30,37 +50,73 @@ ...@@ -30,37 +50,73 @@
30 } 50 }
31 networkTimeline.appendChild(fragment); 51 networkTimeline.appendChild(fragment);
32 }); 52 });
33 53
34 // collect the simulation parameters 54 // collect the simulation parameters
35 parameters = function() { 55 parameters = function() {
36 var times = Array.prototype.slice.call(document.querySelectorAll('.time')), 56 var times = Array.prototype.slice.call(document.querySelectorAll('.time')),
37 bandwidths = document.querySelectorAll('input.bandwidth'); 57 bandwidths = document.querySelectorAll('input.bandwidth'),
38 58 playlists = Array.prototype.slice.call(document.querySelectorAll('input.bitrate'));
39 return times.reduce(function(conditions, time, i) { 59
40 return conditions.concat({ 60 return {
41 time: +time.value, 61 playlists: playlists.map(function(input) {
42 bandwidth: +bandwidths[i].value 62 return +input.value;
43 }); 63 }),
44 }, []); 64 bandwidths: times.reduce(function(conditions, time, i) {
65 return conditions.concat({
66 time: +time.value,
67 bandwidth: +bandwidths[i].value
68 });
69 }, [])
70 };
45 }; 71 };
46 72
47 // run the simulation 73 // run the simulation
48 runSimulation = function(options) { 74 runSimulation = function(options) {
49 var results = [], 75 var results = [],
76 bandwidths = options.bandwidths,
77 fixture = document.getElementById('fixture'),
78 video,
50 t, 79 t,
51 i; 80 i;
52 81
53 options.sort(function(left, right) { 82 // clean up the last run if necessary
83 if (player) {
84 player.dispose();
85 };
86
87 // initialize the HLS tech
88 fixture.innerHTML = '';
89 video = document.createElement('video');
90 fixture.appendChild(video);
91 player = videojs(video, {
92 techOrder: ['hls'],
93 sources: [{
94 src: 'http://example.com/master.m3u8',
95 type: 'application/x-mpegurl'
96 }]
97 });
98 player.ready(function() {
99 var master = '#EXTM3U\n' +
100 options.playlists.reduce(function(playlists, value) {
101 return playlists +
102 '#EXT-X-STREAM-INF:' + value + '\n' +
103 value + '\n';
104 }, '');
105 requests.pop().respond(200, null, master);
106 });
107
108 // bandwidth
109 bandwidths.sort(function(left, right) {
54 return left.time - right.time; 110 return left.time - right.time;
55 }); 111 });
56 112
57 for (t = i = 0; t < duration; t++) { 113 for (t = i = 0; t < duration; t++) {
58 while (options[i + 1] && options[i + 1].time <= t) { 114 while (bandwidths[i + 1] && bandwidths[i + 1].time <= t) {
59 i++; 115 i++;
60 } 116 }
61 results.push({ 117 results.push({
62 time: t, 118 time: t,
63 bandwidth: options[i].bandwidth 119 bandwidth: bandwidths[i].bandwidth
64 }); 120 });
65 } 121 }
66 return results; 122 return results;
...@@ -137,7 +193,7 @@ ...@@ -137,7 +193,7 @@
137 }; 193 };
138 })(); 194 })();
139 195
140 196
141 displayTimeline(runSimulation(parameters())); 197 displayTimeline(runSimulation(parameters()));
142 198
143 })(window, document); 199 })(window, document);
......