Merge pull request #46 from videojs/hotfix/mse-upgrade
Update to vjs-MSE 0.2.0
Showing
9 changed files
with
25 additions
and
132 deletions
... | @@ -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 | } | ... | ... |
src/async-queue.js
deleted
100644 → 0
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(); | ... | ... |
test/async-queue_test.js
deleted
100644 → 0
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) { | ... | ... |
-
Please register or sign in to post a comment