faaa60ef by David LaPalomento

Merge pull request #46 from videojs/hotfix/mse-upgrade

Update to vjs-MSE 0.2.0
2 parents 84ea0e16 7f3f609b
...@@ -10,11 +10,10 @@ ...@@ -10,11 +10,10 @@
10 <script src="node_modules/video.js/dist/video-js/video.js"></script> 10 <script src="node_modules/video.js/dist/video-js/video.js"></script>
11 11
12 <!-- Media Sources plugin --> 12 <!-- Media Sources plugin -->
13 <script src="node_modules/videojs-contrib-media-sources/videojs-media-sources.js"></script> 13 <script src="node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
14 14
15 <!-- HLS plugin --> 15 <!-- HLS plugin -->
16 <script src="src/videojs-hls.js"></script> 16 <script src="src/videojs-hls.js"></script>
17 <script src="src/async-queue.js"></script>
18 17
19 <!-- segment handling --> 18 <!-- segment handling -->
20 <script src="src/flv-tag.js"></script> 19 <script src="src/flv-tag.js"></script>
......
...@@ -40,6 +40,6 @@ ...@@ -40,6 +40,6 @@
40 "video.js": "^4.5" 40 "video.js": "^4.5"
41 }, 41 },
42 "dependencies": { 42 "dependencies": {
43 "videojs-contrib-media-sources": "git+https://github.com/videojs/videojs-contrib-media-sources.git" 43 "videojs-contrib-media-sources": "^0.2"
44 } 44 }
45 } 45 }
......
1 (function(window, videojs, undefined) {
2 'use strict';
3 /**
4 * A queue object that manages tasks that should be processed
5 * serially but asynchronously. Loosely adapted from
6 * https://github.com/caolan/async#queue.
7 * @param worker {function} the callback to invoke with each value
8 * pushed onto the queue
9 * @return {object} an object with an array of `tasks` that remain to
10 * be processed and function `push` to add new tasks
11 */
12 videojs.hls.queue = function(worker) {
13 var
14 q = {
15 tasks: [],
16 running: false,
17 push: function(task) {
18 q.tasks.push(task);
19 if (!q.running) {
20 window.setTimeout(process, 0);
21 q.running = true;
22 }
23 }
24 },
25 process = function() {
26 var task;
27 if (q.tasks.length) {
28 task = q.tasks.shift();
29 worker.call(this, task);
30 window.setTimeout(process, 0);
31 } else {
32 q.running = false;
33 }
34 };
35 return q;
36 };
37 })(window, window.videojs);
...@@ -272,15 +272,6 @@ var ...@@ -272,15 +272,6 @@ var
272 mediaSource = new videojs.MediaSource(), 272 mediaSource = new videojs.MediaSource(),
273 segmentParser = new videojs.hls.SegmentParser(), 273 segmentParser = new videojs.hls.SegmentParser(),
274 player = this, 274 player = this,
275
276 // async queue of Uint8Arrays to be appended to the SourceBuffer
277 tags = videojs.hls.queue(function(tag) {
278 player.hls.sourceBuffer.appendBuffer(tag, player);
279
280 if (player.hls.mediaIndex === player.hls.media.segments.length) {
281 mediaSource.endOfStream();
282 }
283 }),
284 srcUrl, 275 srcUrl,
285 276
286 playlistXhr, 277 playlistXhr,
...@@ -366,11 +357,13 @@ var ...@@ -366,11 +357,13 @@ var
366 var currentTime = player.currentTime(); 357 var currentTime = player.currentTime();
367 player.hls.mediaIndex = getMediaIndexByTime(player.hls.media, currentTime); 358 player.hls.mediaIndex = getMediaIndexByTime(player.hls.media, currentTime);
368 359
360 // abort any segments still being decoded
361 player.hls.sourceBuffer.abort();
362
369 // cancel outstanding requests and buffer appends 363 // cancel outstanding requests and buffer appends
370 if (segmentXhr) { 364 if (segmentXhr) {
371 segmentXhr.abort(); 365 segmentXhr.abort();
372 } 366 }
373 tags.tasks = [];
374 367
375 // begin filling the buffer at the new position 368 // begin filling the buffer at the new position
376 fillBuffer(currentTime * 1000); 369 fillBuffer(currentTime * 1000);
...@@ -686,11 +679,18 @@ var ...@@ -686,11 +679,18 @@ var
686 // queue up the bytes to be appended to the SourceBuffer 679 // queue up the bytes to be appended to the SourceBuffer
687 // the queue gives control back to the browser between tags 680 // the queue gives control back to the browser between tags
688 // so that large segments don't cause a "hiccup" in playback 681 // so that large segments don't cause a "hiccup" in playback
689 tags.push(segmentParser.getNextTag().bytes); 682
683 player.hls.sourceBuffer.appendBuffer(segmentParser.getNextTag().bytes,
684 player);
685
690 } 686 }
691 687
692 player.hls.mediaIndex++; 688 player.hls.mediaIndex++;
693 689
690 if (player.hls.mediaIndex === player.hls.media.segments.length) {
691 mediaSource.endOfStream();
692 }
693
694 // figure out what stream the next segment should be downloaded from 694 // figure out what stream the next segment should be downloaded from
695 // with the updated bandwidth information 695 // with the updated bandwidth information
696 updateCurrentPlaylist(); 696 updateCurrentPlaylist();
......
1 (function(window, queue, undefined) {
2 var
3 oldSetTimeout,
4 callbacks;
5 module('async queue', {
6 setup: function() {
7 oldSetTimeout = window.setTimeout;
8 callbacks = [];
9 window.setTimeout = function(callback) {
10 callbacks.push(callback);
11 };
12 },
13 teardown: function() {
14 window.setTimeout = oldSetTimeout;
15 }
16 });
17
18 test('runs tasks asynchronously', function() {
19 var
20 run = false,
21 q = queue(function() {
22 run = true;
23 });
24 q.push(1);
25
26 ok(!run, 'tasks are not run immediately');
27
28 callbacks[0]();
29 ok(run, 'tasks are run asynchronously');
30 });
31
32 test('runs one task at a time', function() {
33 var q = queue(function() {});
34 q.push(1);
35 q.push(2);
36 q.push(3);
37 q.push(4);
38 q.push(5);
39
40 strictEqual(q.tasks.length, 5, 'all tasks are queued');
41 strictEqual(1, callbacks.length, 'one callback is registered');
42 });
43
44 test('tasks are scheduled until the queue is empty', function() {
45 var q = queue(function() {});
46 q.push(1);
47 q.push(2);
48
49 callbacks.shift()();
50 strictEqual(1, callbacks.length, 'the next task is scheduled');
51
52 callbacks.shift()();
53 strictEqual(1, callbacks.length, 'nothing is scheduled on an empty queue');
54 });
55
56 test('can be emptied at any time', function() {
57 var
58 runs = 0,
59 q = queue(function() {
60 runs++;
61 });
62 q.push(1);
63 q.push(2);
64
65 callbacks.shift()();
66 strictEqual(1, runs, 'task one is run');
67
68 q.tasks = [];
69 callbacks.shift()();
70 strictEqual(1, runs, 'the remaining tasks are cancelled');
71 });
72 })(window, window.videojs.hls.queue);
...@@ -40,7 +40,7 @@ module.exports = function(config) { ...@@ -40,7 +40,7 @@ module.exports = function(config) {
40 40
41 files: [ 41 files: [
42 '../node_modules/video.js/dist/video-js/video.js', 42 '../node_modules/video.js/dist/video-js/video.js',
43 '../node_modules/videojs-contrib-media-sources/videojs-media-sources.js', 43 '../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
44 '../test/karma-qunit-shim.js', 44 '../test/karma-qunit-shim.js',
45 "../src/videojs-hls.js", 45 "../src/videojs-hls.js",
46 "../src/flv-tag.js", 46 "../src/flv-tag.js",
......
...@@ -35,7 +35,7 @@ module.exports = function(config) { ...@@ -35,7 +35,7 @@ module.exports = function(config) {
35 35
36 files: [ 36 files: [
37 '../node_modules/video.js/dist/video-js/video.js', 37 '../node_modules/video.js/dist/video-js/video.js',
38 '../node_modules/videojs-contrib-media-sources/videojs-media-sources.js', 38 '../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js',
39 '../test/karma-qunit-shim.js', 39 '../test/karma-qunit-shim.js',
40 "../src/videojs-hls.js", 40 "../src/videojs-hls.js",
41 "../src/flv-tag.js", 41 "../src/flv-tag.js",
...@@ -93,4 +93,4 @@ module.exports = function(config) { ...@@ -93,4 +93,4 @@ module.exports = function(config) {
93 // If browser does not capture in given timeout [ms], kill it 93 // If browser does not capture in given timeout [ms], kill it
94 captureTimeout: 60000 94 captureTimeout: 60000
95 }); 95 });
96 };
...\ No newline at end of file ...\ No newline at end of file
96 };
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
9 9
10 <!-- video.js --> 10 <!-- video.js -->
11 <script src="../node_modules/video.js/dist/video-js/video.js"></script> 11 <script src="../node_modules/video.js/dist/video-js/video.js"></script>
12 <script src="../node_modules/videojs-contrib-media-sources/videojs-media-sources.js"></script> 12 <script src="../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
13 13
14 <!-- HLS plugin --> 14 <!-- HLS plugin -->
15 <script src="../src/videojs-hls.js"></script> 15 <script src="../src/videojs-hls.js"></script>
...@@ -31,9 +31,6 @@ ...@@ -31,9 +31,6 @@
31 <script src="tsSegment-bc.js"></script> 31 <script src="tsSegment-bc.js"></script>
32 <script src="../src/bin-utils.js"></script> 32 <script src="../src/bin-utils.js"></script>
33 33
34 <!-- async queue -->
35 <script src="../src/async-queue.js"></script>
36
37 <!-- Test cases --> 34 <!-- Test cases -->
38 <script> 35 <script>
39 module('environment'); 36 module('environment');
...@@ -48,7 +45,6 @@ ...@@ -48,7 +45,6 @@
48 <script src="exp-golomb_test.js"></script> 45 <script src="exp-golomb_test.js"></script>
49 <script src="flv-tag_test.js"></script> 46 <script src="flv-tag_test.js"></script>
50 <script src="m3u8_test.js"></script> 47 <script src="m3u8_test.js"></script>
51 <script src="async-queue_test.js"></script>
52 </head> 48 </head>
53 <body> 49 <body>
54 <div id="qunit"></div> 50 <div id="qunit"></div>
......
...@@ -63,6 +63,7 @@ module('HLS', { ...@@ -63,6 +63,7 @@ module('HLS', {
63 oldSourceBuffer = window.videojs.SourceBuffer; 63 oldSourceBuffer = window.videojs.SourceBuffer;
64 window.videojs.SourceBuffer = function() { 64 window.videojs.SourceBuffer = function() {
65 this.appendBuffer = function() {}; 65 this.appendBuffer = function() {};
66 this.abort = function() {};
66 }; 67 };
67 68
68 // force native HLS to be ignored 69 // force native HLS to be ignored
...@@ -714,6 +715,7 @@ test('drops tags before the target timestamp when seeking', function() { ...@@ -714,6 +715,7 @@ test('drops tags before the target timestamp when seeking', function() {
714 this.appendBuffer = function(chunk) { 715 this.appendBuffer = function(chunk) {
715 bytes.push(chunk); 716 bytes.push(chunk);
716 }; 717 };
718 this.abort = function() {};
717 }; 719 };
718 // capture timeouts 720 // capture timeouts
719 window.setTimeout = function(callback) { 721 window.setTimeout = function(callback) {
...@@ -755,6 +757,7 @@ test('clears pending buffer updates when seeking', function() { ...@@ -755,6 +757,7 @@ test('clears pending buffer updates when seeking', function() {
755 var 757 var
756 bytes = [], 758 bytes = [],
757 callbacks = [], 759 callbacks = [],
760 aborts = 0,
758 tags = [{ pts: 0, bytes: 0 }]; 761 tags = [{ pts: 0, bytes: 0 }];
759 // mock out the parser and source buffer 762 // mock out the parser and source buffer
760 videojs.hls.SegmentParser = mockSegmentParser(tags); 763 videojs.hls.SegmentParser = mockSegmentParser(tags);
...@@ -762,6 +765,9 @@ test('clears pending buffer updates when seeking', function() { ...@@ -762,6 +765,9 @@ test('clears pending buffer updates when seeking', function() {
762 this.appendBuffer = function(chunk) { 765 this.appendBuffer = function(chunk) {
763 bytes.push(chunk); 766 bytes.push(chunk);
764 }; 767 };
768 this.abort = function() {
769 aborts++;
770 };
765 }; 771 };
766 // capture timeouts 772 // capture timeouts
767 window.setTimeout = function(callback) { 773 window.setTimeout = function(callback) {
...@@ -785,7 +791,7 @@ test('clears pending buffer updates when seeking', function() { ...@@ -785,7 +791,7 @@ test('clears pending buffer updates when seeking', function() {
785 callbacks.shift()(); 791 callbacks.shift()();
786 } 792 }
787 793
788 deepEqual(bytes, ['flv', 7], 'tags queued to be appended should be cancelled'); 794 strictEqual(1, aborts, 'aborted pending buffer');
789 }); 795 });
790 796
791 test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { 797 test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() {
...@@ -1067,6 +1073,7 @@ test('only reloads the active media playlist', function() { ...@@ -1067,6 +1073,7 @@ test('only reloads the active media playlist', function() {
1067 videojs.mediaSources[player.currentSrc()].trigger({ 1073 videojs.mediaSources[player.currentSrc()].trigger({
1068 type: 'sourceopen' 1074 type: 'sourceopen'
1069 }); 1075 });
1076 videojs.mediaSources[player.currentSrc()].endOfStream = function() {};
1070 1077
1071 window.XMLHttpRequest = function() { 1078 window.XMLHttpRequest = function() {
1072 this.open = function(method, url) { 1079 this.open = function(method, url) {
......