Merge pull request #62 from videojs/tech2
HLS Tech
Showing
20 changed files
with
103 additions
and
69 deletions
... | @@ -45,9 +45,6 @@ module.exports = function(grunt) { | ... | @@ -45,9 +45,6 @@ module.exports = function(grunt) { |
45 | dest: 'dist/videojs.hls.min.js' | 45 | dest: 'dist/videojs.hls.min.js' |
46 | } | 46 | } |
47 | }, | 47 | }, |
48 | qunit: { | ||
49 | files: ['test/**/*.html', '!test/perf.html', '!test/muxer/**'] | ||
50 | }, | ||
51 | jshint: { | 48 | jshint: { |
52 | gruntfile: { | 49 | gruntfile: { |
53 | options: { | 50 | options: { |
... | @@ -93,11 +90,11 @@ module.exports = function(grunt) { | ... | @@ -93,11 +90,11 @@ module.exports = function(grunt) { |
93 | }, | 90 | }, |
94 | src: { | 91 | src: { |
95 | files: '<%= jshint.src.src %>', | 92 | files: '<%= jshint.src.src %>', |
96 | tasks: ['jshint:src', 'qunit'] | 93 | tasks: ['jshint:src', 'test'] |
97 | }, | 94 | }, |
98 | test: { | 95 | test: { |
99 | files: '<%= jshint.test.src %>', | 96 | files: '<%= jshint.test.src %>', |
100 | tasks: ['jshint:test', 'qunit'] | 97 | tasks: ['jshint:test', 'test'] |
101 | } | 98 | } |
102 | }, | 99 | }, |
103 | concurrent: { | 100 | concurrent: { |
... | @@ -194,7 +191,6 @@ module.exports = function(grunt) { | ... | @@ -194,7 +191,6 @@ module.exports = function(grunt) { |
194 | grunt.loadNpmTasks('grunt-contrib-clean'); | 191 | grunt.loadNpmTasks('grunt-contrib-clean'); |
195 | grunt.loadNpmTasks('grunt-contrib-concat'); | 192 | grunt.loadNpmTasks('grunt-contrib-concat'); |
196 | grunt.loadNpmTasks('grunt-contrib-uglify'); | 193 | grunt.loadNpmTasks('grunt-contrib-uglify'); |
197 | grunt.loadNpmTasks('grunt-contrib-qunit'); | ||
198 | grunt.loadNpmTasks('grunt-contrib-jshint'); | 194 | grunt.loadNpmTasks('grunt-contrib-jshint'); |
199 | grunt.loadNpmTasks('grunt-contrib-watch'); | 195 | grunt.loadNpmTasks('grunt-contrib-watch'); |
200 | grunt.loadNpmTasks('grunt-contrib-connect'); | 196 | grunt.loadNpmTasks('grunt-contrib-connect'); |
... | @@ -255,7 +251,7 @@ module.exports = function(grunt) { | ... | @@ -255,7 +251,7 @@ module.exports = function(grunt) { |
255 | ['clean', | 251 | ['clean', |
256 | 'jshint', | 252 | 'jshint', |
257 | 'manifests-to-js', | 253 | 'manifests-to-js', |
258 | 'qunit', | 254 | 'test', |
259 | 'concat', | 255 | 'concat', |
260 | 'uglify']); | 256 | 'uglify']); |
261 | 257 | ... | ... |
... | @@ -31,7 +31,7 @@ | ... | @@ -31,7 +31,7 @@ |
31 | <!-- bipbop --> | 31 | <!-- bipbop --> |
32 | <!-- <script src="test/tsSegment.js"></script> --> | 32 | <!-- <script src="test/tsSegment.js"></script> --> |
33 | <!-- bunnies --> | 33 | <!-- bunnies --> |
34 | <script src="test/tsSegment-bc.js"></script> | 34 | <!--<script src="test/tsSegment-bc.js"></script>--> |
35 | 35 | ||
36 | <style> | 36 | <style> |
37 | body { | 37 | body { |
... | @@ -63,10 +63,12 @@ | ... | @@ -63,10 +63,12 @@ |
63 | <script> | 63 | <script> |
64 | videojs.options.flash.swf = 'node_modules/video.js/dist/video-js/video-js.swf'; | 64 | videojs.options.flash.swf = 'node_modules/video.js/dist/video-js/video-js.swf'; |
65 | // initialize the player | 65 | // initialize the player |
66 | var player = videojs('video'); | 66 | var player = videojs('video', { |
67 | techOrder: ['hls'] | ||
68 | }); | ||
67 | 69 | ||
68 | // initialize the plugin | 70 | // initialize the plugin |
69 | player.hls(); | 71 | //player.hls() |
70 | </script> | 72 | </script> |
71 | </body> | 73 | </body> |
72 | </html> | 74 | </html> | ... | ... |
... | @@ -19,7 +19,6 @@ | ... | @@ -19,7 +19,6 @@ |
19 | "grunt-contrib-concat": "~0.3.0", | 19 | "grunt-contrib-concat": "~0.3.0", |
20 | "grunt-contrib-connect": "~0.6.0", | 20 | "grunt-contrib-connect": "~0.6.0", |
21 | "grunt-contrib-jshint": "~0.6.0", | 21 | "grunt-contrib-jshint": "~0.6.0", |
22 | "grunt-contrib-qunit": "~0.2.0", | ||
23 | "grunt-contrib-uglify": "~0.2.0", | 22 | "grunt-contrib-uglify": "~0.2.0", |
24 | "grunt-contrib-watch": "~0.4.0", | 23 | "grunt-contrib-watch": "~0.4.0", |
25 | "grunt-karma": "~0.6.2", | 24 | "grunt-karma": "~0.6.2", | ... | ... |
... | @@ -8,7 +8,7 @@ | ... | @@ -8,7 +8,7 @@ |
8 | 8 | ||
9 | (function(window) { | 9 | (function(window) { |
10 | var | 10 | var |
11 | FlvTag = window.videojs.hls.FlvTag, | 11 | FlvTag = window.videojs.Hls.FlvTag, |
12 | adtsSampleingRates = [ | 12 | adtsSampleingRates = [ |
13 | 96000, 88200, | 13 | 96000, 88200, |
14 | 64000, 48000, | 14 | 64000, 48000, |
... | @@ -17,7 +17,7 @@ var | ... | @@ -17,7 +17,7 @@ var |
17 | 16000, 12000 | 17 | 16000, 12000 |
18 | ]; | 18 | ]; |
19 | 19 | ||
20 | window.videojs.hls.AacStream = function() { | 20 | window.videojs.Hls.AacStream = function() { |
21 | var | 21 | var |
22 | next_pts, // :uint | 22 | next_pts, // :uint |
23 | pts_offset, // :int | 23 | pts_offset, // :int | ... | ... |
... | @@ -4,7 +4,7 @@ | ... | @@ -4,7 +4,7 @@ |
4 | * Parser for exponential Golomb codes, a variable-bitwidth number encoding | 4 | * Parser for exponential Golomb codes, a variable-bitwidth number encoding |
5 | * scheme used by h264. | 5 | * scheme used by h264. |
6 | */ | 6 | */ |
7 | window.videojs.hls.ExpGolomb = function(workingData) { | 7 | window.videojs.Hls.ExpGolomb = function(workingData) { |
8 | var | 8 | var |
9 | // the number of bytes left to examine in workingData | 9 | // the number of bytes left to examine in workingData |
10 | workingBytesAvailable = workingData.byteLength, | 10 | workingBytesAvailable = workingData.byteLength, | ... | ... |
1 | (function(window) { | 1 | (function(window) { |
2 | 2 | ||
3 | window.videojs = window.videojs || {}; | 3 | window.videojs = window.videojs || {}; |
4 | window.videojs.hls = window.videojs.hls || {}; | 4 | window.videojs.Hls = window.videojs.Hls || {}; |
5 | 5 | ||
6 | var hls = window.videojs.hls; | 6 | var hls = window.videojs.Hls; |
7 | 7 | ||
8 | // (type:uint, extraData:Boolean = false) extends ByteArray | 8 | // (type:uint, extraData:Boolean = false) extends ByteArray |
9 | hls.FlvTag = function(type, extraData) { | 9 | hls.FlvTag = function(type, extraData) { | ... | ... |
... | @@ -8,8 +8,8 @@ | ... | @@ -8,8 +8,8 @@ |
8 | 8 | ||
9 | (function(window) { | 9 | (function(window) { |
10 | var | 10 | var |
11 | ExpGolomb = window.videojs.hls.ExpGolomb, | 11 | ExpGolomb = window.videojs.Hls.ExpGolomb, |
12 | FlvTag = window.videojs.hls.FlvTag, | 12 | FlvTag = window.videojs.Hls.FlvTag, |
13 | 13 | ||
14 | H264ExtraData = function() { | 14 | H264ExtraData = function() { |
15 | this.sps = []; // :Array | 15 | this.sps = []; // :Array |
... | @@ -234,7 +234,7 @@ | ... | @@ -234,7 +234,7 @@ |
234 | * an h264 stream. Exactly one byte. | 234 | * an h264 stream. Exactly one byte. |
235 | */ | 235 | */ |
236 | // incomplete, see Table 7.1 of ITU-T H.264 for 12-32 | 236 | // incomplete, see Table 7.1 of ITU-T H.264 for 12-32 |
237 | window.videojs.hls.NALUnitType = NALUnitType = { | 237 | window.videojs.Hls.NALUnitType = NALUnitType = { |
238 | unspecified: 0, | 238 | unspecified: 0, |
239 | slice_layer_without_partitioning_rbsp_non_idr: 1, | 239 | slice_layer_without_partitioning_rbsp_non_idr: 1, |
240 | slice_data_partition_a_layer_rbsp: 2, | 240 | slice_data_partition_a_layer_rbsp: 2, |
... | @@ -249,7 +249,7 @@ | ... | @@ -249,7 +249,7 @@ |
249 | end_of_stream_rbsp: 11 | 249 | end_of_stream_rbsp: 11 |
250 | }; | 250 | }; |
251 | 251 | ||
252 | window.videojs.hls.H264Stream = function() { | 252 | window.videojs.Hls.H264Stream = function() { |
253 | var | 253 | var |
254 | next_pts, // :uint; | 254 | next_pts, // :uint; |
255 | next_dts, // :uint; | 255 | next_dts, // :uint; | ... | ... |
... | @@ -5,8 +5,8 @@ | ... | @@ -5,8 +5,8 @@ |
5 | (function(window, videojs) { | 5 | (function(window, videojs) { |
6 | 'use strict'; | 6 | 'use strict'; |
7 | var | 7 | var |
8 | resolveUrl = videojs.hls.resolveUrl, | 8 | resolveUrl = videojs.Hls.resolveUrl, |
9 | xhr = videojs.hls.xhr, | 9 | xhr = videojs.Hls.xhr, |
10 | 10 | ||
11 | /** | 11 | /** |
12 | * Returns a new master playlist that is the result of merging an | 12 | * Returns a new master playlist that is the result of merging an |
... | @@ -51,6 +51,7 @@ | ... | @@ -51,6 +51,7 @@ |
51 | var | 51 | var |
52 | loader = this, | 52 | loader = this, |
53 | media, | 53 | media, |
54 | mediaUpdateTimeout, | ||
54 | request, | 55 | request, |
55 | 56 | ||
56 | haveMetadata = function(error, xhr, url) { | 57 | haveMetadata = function(error, xhr, url) { |
... | @@ -88,7 +89,7 @@ | ... | @@ -88,7 +89,7 @@ |
88 | 89 | ||
89 | // refresh live playlists after a target duration passes | 90 | // refresh live playlists after a target duration passes |
90 | if (!loader.media().endList) { | 91 | if (!loader.media().endList) { |
91 | window.setTimeout(function() { | 92 | mediaUpdateTimeout = window.setTimeout(function() { |
92 | loader.trigger('mediaupdatetimeout'); | 93 | loader.trigger('mediaupdatetimeout'); |
93 | }, refreshDelay); | 94 | }, refreshDelay); |
94 | } | 95 | } |
... | @@ -104,6 +105,13 @@ | ... | @@ -104,6 +105,13 @@ |
104 | 105 | ||
105 | loader.state = 'HAVE_NOTHING'; | 106 | loader.state = 'HAVE_NOTHING'; |
106 | 107 | ||
108 | loader.dispose = function() { | ||
109 | if (request) { | ||
110 | request.abort(); | ||
111 | } | ||
112 | window.clearTimeout(mediaUpdateTimeout); | ||
113 | }; | ||
114 | |||
107 | /** | 115 | /** |
108 | * When called without any arguments, returns the currently | 116 | * When called without any arguments, returns the currently |
109 | * active media playlist. When called with a single argument, | 117 | * active media playlist. When called with a single argument, |
... | @@ -213,7 +221,9 @@ | ... | @@ -213,7 +221,9 @@ |
213 | haveMetadata(error, | 221 | haveMetadata(error, |
214 | this, | 222 | this, |
215 | parser.manifest.playlists[0].uri); | 223 | parser.manifest.playlists[0].uri); |
216 | loader.trigger('loadedmetadata'); | 224 | if (!error) { |
225 | loader.trigger('loadedmetadata'); | ||
226 | } | ||
217 | }); | 227 | }); |
218 | return loader.trigger('loadedplaylist'); | 228 | return loader.trigger('loadedplaylist'); |
219 | } | 229 | } |
... | @@ -231,7 +241,7 @@ | ... | @@ -231,7 +241,7 @@ |
231 | return loader.trigger('loadedmetadata'); | 241 | return loader.trigger('loadedmetadata'); |
232 | }); | 242 | }); |
233 | }; | 243 | }; |
234 | PlaylistLoader.prototype = new videojs.hls.Stream(); | 244 | PlaylistLoader.prototype = new videojs.Hls.Stream(); |
235 | 245 | ||
236 | videojs.hls.PlaylistLoader = PlaylistLoader; | 246 | videojs.Hls.PlaylistLoader = PlaylistLoader; |
237 | })(window, window.videojs); | 247 | })(window, window.videojs); | ... | ... |
1 | (function(window) { | 1 | (function(window) { |
2 | var | 2 | var |
3 | videojs = window.videojs, | 3 | videojs = window.videojs, |
4 | FlvTag = videojs.hls.FlvTag, | 4 | FlvTag = videojs.Hls.FlvTag, |
5 | H264Stream = videojs.hls.H264Stream, | 5 | H264Stream = videojs.Hls.H264Stream, |
6 | AacStream = videojs.hls.AacStream, | 6 | AacStream = videojs.Hls.AacStream, |
7 | MP2T_PACKET_LENGTH, | 7 | MP2T_PACKET_LENGTH, |
8 | STREAM_TYPES; | 8 | STREAM_TYPES; |
9 | 9 | ||
... | @@ -11,7 +11,7 @@ | ... | @@ -11,7 +11,7 @@ |
11 | * An object that incrementally transmuxes MPEG2 Trasport Stream | 11 | * An object that incrementally transmuxes MPEG2 Trasport Stream |
12 | * chunks into an FLV. | 12 | * chunks into an FLV. |
13 | */ | 13 | */ |
14 | videojs.hls.SegmentParser = function() { | 14 | videojs.Hls.SegmentParser = function() { |
15 | var | 15 | var |
16 | self = this, | 16 | self = this, |
17 | parseTSPacket, | 17 | parseTSPacket, |
... | @@ -432,8 +432,8 @@ | ... | @@ -432,8 +432,8 @@ |
432 | }; | 432 | }; |
433 | 433 | ||
434 | // MPEG2-TS constants | 434 | // MPEG2-TS constants |
435 | videojs.hls.SegmentParser.MP2T_PACKET_LENGTH = MP2T_PACKET_LENGTH = 188; | 435 | videojs.Hls.SegmentParser.MP2T_PACKET_LENGTH = MP2T_PACKET_LENGTH = 188; |
436 | videojs.hls.SegmentParser.STREAM_TYPES = STREAM_TYPES = { | 436 | videojs.Hls.SegmentParser.STREAM_TYPES = STREAM_TYPES = { |
437 | h264: 0x1b, | 437 | h264: 0x1b, |
438 | adts: 0x0f | 438 | adts: 0x0f |
439 | }; | 439 | }; | ... | ... |
This diff is collapsed.
Click to expand it.
... | @@ -21,7 +21,7 @@ | ... | @@ -21,7 +21,7 @@ |
21 | */ | 21 | */ |
22 | var | 22 | var |
23 | buffer, | 23 | buffer, |
24 | ExpGolomb = window.videojs.hls.ExpGolomb, | 24 | ExpGolomb = window.videojs.Hls.ExpGolomb, |
25 | expGolomb; | 25 | expGolomb; |
26 | 26 | ||
27 | module('Exponential Golomb coding'); | 27 | module('Exponential Golomb coding'); | ... | ... |
... | @@ -19,7 +19,7 @@ | ... | @@ -19,7 +19,7 @@ |
19 | notStrictEqual(actual, expected, [message]) | 19 | notStrictEqual(actual, expected, [message]) |
20 | throws(block, [expected], [message]) | 20 | throws(block, [expected], [message]) |
21 | */ | 21 | */ |
22 | var FlvTag = window.videojs.hls.FlvTag; | 22 | var FlvTag = window.videojs.Hls.FlvTag; |
23 | 23 | ||
24 | module('FLV tag'); | 24 | module('FLV tag'); |
25 | 25 | ... | ... |
... | @@ -2,12 +2,12 @@ | ... | @@ -2,12 +2,12 @@ |
2 | module('H264 Stream'); | 2 | module('H264 Stream'); |
3 | 3 | ||
4 | var | 4 | var |
5 | nalUnitTypes = window.videojs.hls.NALUnitType, | 5 | nalUnitTypes = window.videojs.Hls.NALUnitType, |
6 | FlvTag = window.videojs.hls.FlvTag; | 6 | FlvTag = window.videojs.Hls.FlvTag; |
7 | 7 | ||
8 | test('metadata is generated for IDRs after a full NAL unit is written', function() { | 8 | test('metadata is generated for IDRs after a full NAL unit is written', function() { |
9 | var | 9 | var |
10 | h264Stream = new videojs.hls.H264Stream(), | 10 | h264Stream = new videojs.Hls.H264Stream(), |
11 | accessUnitDelimiter = new Uint8Array([ | 11 | accessUnitDelimiter = new Uint8Array([ |
12 | 0x00, | 12 | 0x00, |
13 | 0x00, | 13 | 0x00, |
... | @@ -62,7 +62,7 @@ test('metadata is generated for IDRs after a full NAL unit is written', function | ... | @@ -62,7 +62,7 @@ test('metadata is generated for IDRs after a full NAL unit is written', function |
62 | 62 | ||
63 | test('starting PTS values can be negative', function() { | 63 | test('starting PTS values can be negative', function() { |
64 | var | 64 | var |
65 | h264Stream = new videojs.hls.H264Stream(), | 65 | h264Stream = new videojs.Hls.H264Stream(), |
66 | accessUnitDelimiter = new Uint8Array([ | 66 | accessUnitDelimiter = new Uint8Array([ |
67 | 0x00, | 67 | 0x00, |
68 | 0x00, | 68 | 0x00, | ... | ... |
... | @@ -127,7 +127,7 @@ | ... | @@ -127,7 +127,7 @@ |
127 | original.addEventListener('change', function() { | 127 | original.addEventListener('change', function() { |
128 | var reader = new FileReader(); | 128 | var reader = new FileReader(); |
129 | reader.addEventListener('loadend', function() { | 129 | reader.addEventListener('loadend', function() { |
130 | var parser = new videojs.hls.SegmentParser(), | 130 | var parser = new videojs.Hls.SegmentParser(), |
131 | tags = [parser.getFlvHeader()], | 131 | tags = [parser.getFlvHeader()], |
132 | tag, | 132 | tag, |
133 | hex, | 133 | hex, |
... | @@ -164,7 +164,7 @@ | ... | @@ -164,7 +164,7 @@ |
164 | } | 164 | } |
165 | 165 | ||
166 | hex = '<pre>' | 166 | hex = '<pre>' |
167 | hex += videojs.hls.utils.hexDump(data); | 167 | hex += videojs.Hls.utils.hexDump(data); |
168 | hex += '</pre>' | 168 | hex += '</pre>' |
169 | 169 | ||
170 | vjsOutput.innerHTML = hex; | 170 | vjsOutput.innerHTML = hex; |
... | @@ -201,7 +201,7 @@ | ... | @@ -201,7 +201,7 @@ |
201 | } | 201 | } |
202 | 202 | ||
203 | // output the hex dump | 203 | // output the hex dump |
204 | hex += videojs.hls.utils.hexDump(bytes); | 204 | hex += videojs.Hls.utils.hexDump(bytes); |
205 | hex += '</pre>'; | 205 | hex += '</pre>'; |
206 | workingOutput.innerHTML = hex; | 206 | workingOutput.innerHTML = hex; |
207 | }); | 207 | }); | ... | ... |
... | @@ -36,26 +36,26 @@ | ... | @@ -36,26 +36,26 @@ |
36 | 36 | ||
37 | test('throws if the playlist url is empty or undefined', function() { | 37 | test('throws if the playlist url is empty or undefined', function() { |
38 | throws(function() { | 38 | throws(function() { |
39 | videojs.hls.PlaylistLoader(); | 39 | videojs.Hls.PlaylistLoader(); |
40 | }, 'requires an argument'); | 40 | }, 'requires an argument'); |
41 | throws(function() { | 41 | throws(function() { |
42 | videojs.hls.PlaylistLoader(''); | 42 | videojs.Hls.PlaylistLoader(''); |
43 | }, 'does not accept the empty string'); | 43 | }, 'does not accept the empty string'); |
44 | }); | 44 | }); |
45 | 45 | ||
46 | test('starts without any metadata', function() { | 46 | test('starts without any metadata', function() { |
47 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 47 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
48 | strictEqual(loader.state, 'HAVE_NOTHING', 'no metadata has loaded yet'); | 48 | strictEqual(loader.state, 'HAVE_NOTHING', 'no metadata has loaded yet'); |
49 | }); | 49 | }); |
50 | 50 | ||
51 | test('requests the initial playlist immediately', function() { | 51 | test('requests the initial playlist immediately', function() { |
52 | new videojs.hls.PlaylistLoader('master.m3u8'); | 52 | new videojs.Hls.PlaylistLoader('master.m3u8'); |
53 | strictEqual(requests.length, 1, 'made a request'); | 53 | strictEqual(requests.length, 1, 'made a request'); |
54 | strictEqual(requests[0].url, 'master.m3u8', 'requested the initial playlist'); | 54 | strictEqual(requests[0].url, 'master.m3u8', 'requested the initial playlist'); |
55 | }); | 55 | }); |
56 | 56 | ||
57 | test('moves to HAVE_MASTER after loading a master playlist', function() { | 57 | test('moves to HAVE_MASTER after loading a master playlist', function() { |
58 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 58 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
59 | requests.pop().respond(200, null, | 59 | requests.pop().respond(200, null, |
60 | '#EXTM3U\n' + | 60 | '#EXTM3U\n' + |
61 | '#EXT-X-STREAM-INF:\n' + | 61 | '#EXT-X-STREAM-INF:\n' + |
... | @@ -67,7 +67,7 @@ | ... | @@ -67,7 +67,7 @@ |
67 | test('jumps to HAVE_METADATA when initialized with a media playlist', function() { | 67 | test('jumps to HAVE_METADATA when initialized with a media playlist', function() { |
68 | var | 68 | var |
69 | loadedmetadatas = 0, | 69 | loadedmetadatas = 0, |
70 | loader = new videojs.hls.PlaylistLoader('media.m3u8'); | 70 | loader = new videojs.Hls.PlaylistLoader('media.m3u8'); |
71 | loader.on('loadedmetadata', function() { | 71 | loader.on('loadedmetadata', function() { |
72 | loadedmetadatas++; | 72 | loadedmetadatas++; |
73 | }); | 73 | }); |
... | @@ -85,7 +85,7 @@ | ... | @@ -85,7 +85,7 @@ |
85 | }); | 85 | }); |
86 | 86 | ||
87 | test('jumps to HAVE_METADATA when initialized with a live media playlist', function() { | 87 | test('jumps to HAVE_METADATA when initialized with a live media playlist', function() { |
88 | var loader = new videojs.hls.PlaylistLoader('media.m3u8'); | 88 | var loader = new videojs.Hls.PlaylistLoader('media.m3u8'); |
89 | requests.pop().respond(200, null, | 89 | requests.pop().respond(200, null, |
90 | '#EXTM3U\n' + | 90 | '#EXTM3U\n' + |
91 | '#EXTINF:10,\n' + | 91 | '#EXTINF:10,\n' + |
... | @@ -99,7 +99,7 @@ | ... | @@ -99,7 +99,7 @@ |
99 | var | 99 | var |
100 | loadedPlaylist = 0, | 100 | loadedPlaylist = 0, |
101 | loadedMetadata = 0, | 101 | loadedMetadata = 0, |
102 | loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 102 | loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
103 | loader.on('loadedplaylist', function() { | 103 | loader.on('loadedplaylist', function() { |
104 | loadedPlaylist++; | 104 | loadedPlaylist++; |
105 | }); | 105 | }); |
... | @@ -131,7 +131,7 @@ | ... | @@ -131,7 +131,7 @@ |
131 | }); | 131 | }); |
132 | 132 | ||
133 | test('moves to HAVE_CURRENT_METADATA when refreshing the playlist', function() { | 133 | test('moves to HAVE_CURRENT_METADATA when refreshing the playlist', function() { |
134 | var loader = new videojs.hls.PlaylistLoader('live.m3u8'); | 134 | var loader = new videojs.Hls.PlaylistLoader('live.m3u8'); |
135 | requests.pop().respond(200, null, | 135 | requests.pop().respond(200, null, |
136 | '#EXTM3U\n' + | 136 | '#EXTM3U\n' + |
137 | '#EXTINF:10,\n' + | 137 | '#EXTINF:10,\n' + |
... | @@ -145,7 +145,7 @@ | ... | @@ -145,7 +145,7 @@ |
145 | }); | 145 | }); |
146 | 146 | ||
147 | test('returns to HAVE_METADATA after refreshing the playlist', function() { | 147 | test('returns to HAVE_METADATA after refreshing the playlist', function() { |
148 | var loader = new videojs.hls.PlaylistLoader('live.m3u8'); | 148 | var loader = new videojs.Hls.PlaylistLoader('live.m3u8'); |
149 | requests.pop().respond(200, null, | 149 | requests.pop().respond(200, null, |
150 | '#EXTM3U\n' + | 150 | '#EXTM3U\n' + |
151 | '#EXTINF:10,\n' + | 151 | '#EXTINF:10,\n' + |
... | @@ -161,7 +161,7 @@ | ... | @@ -161,7 +161,7 @@ |
161 | test('emits an error when an initial playlist request fails', function() { | 161 | test('emits an error when an initial playlist request fails', function() { |
162 | var | 162 | var |
163 | errors = [], | 163 | errors = [], |
164 | loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 164 | loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
165 | 165 | ||
166 | loader.on('error', function() { | 166 | loader.on('error', function() { |
167 | errors.push(loader.error); | 167 | errors.push(loader.error); |
... | @@ -175,7 +175,7 @@ | ... | @@ -175,7 +175,7 @@ |
175 | test('errors when an initial media playlist request fails', function() { | 175 | test('errors when an initial media playlist request fails', function() { |
176 | var | 176 | var |
177 | errors = [], | 177 | errors = [], |
178 | loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 178 | loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
179 | 179 | ||
180 | loader.on('error', function() { | 180 | loader.on('error', function() { |
181 | errors.push(loader.error); | 181 | errors.push(loader.error); |
... | @@ -197,7 +197,7 @@ | ... | @@ -197,7 +197,7 @@ |
197 | // http://tools.ietf.org/html/draft-pantos-http-live-streaming-12#section-6.3.4 | 197 | // http://tools.ietf.org/html/draft-pantos-http-live-streaming-12#section-6.3.4 |
198 | test('halves the refresh timeout if a playlist is unchanged' + | 198 | test('halves the refresh timeout if a playlist is unchanged' + |
199 | 'since the last reload', function() { | 199 | 'since the last reload', function() { |
200 | new videojs.hls.PlaylistLoader('live.m3u8'); | 200 | new videojs.Hls.PlaylistLoader('live.m3u8'); |
201 | requests.pop().respond(200, null, | 201 | requests.pop().respond(200, null, |
202 | '#EXTM3U\n' + | 202 | '#EXTM3U\n' + |
203 | '#EXT-X-MEDIA-SEQUENCE:0\n' + | 203 | '#EXT-X-MEDIA-SEQUENCE:0\n' + |
... | @@ -218,7 +218,7 @@ | ... | @@ -218,7 +218,7 @@ |
218 | }); | 218 | }); |
219 | 219 | ||
220 | test('media-sequence updates are considered a playlist change', function() { | 220 | test('media-sequence updates are considered a playlist change', function() { |
221 | new videojs.hls.PlaylistLoader('live.m3u8'); | 221 | new videojs.Hls.PlaylistLoader('live.m3u8'); |
222 | requests.pop().respond(200, null, | 222 | requests.pop().respond(200, null, |
223 | '#EXTM3U\n' + | 223 | '#EXTM3U\n' + |
224 | '#EXT-X-MEDIA-SEQUENCE:0\n' + | 224 | '#EXT-X-MEDIA-SEQUENCE:0\n' + |
... | @@ -238,7 +238,7 @@ | ... | @@ -238,7 +238,7 @@ |
238 | test('emits an error if a media refresh fails', function() { | 238 | test('emits an error if a media refresh fails', function() { |
239 | var | 239 | var |
240 | errors = 0, | 240 | errors = 0, |
241 | loader = new videojs.hls.PlaylistLoader('live.m3u8'); | 241 | loader = new videojs.Hls.PlaylistLoader('live.m3u8'); |
242 | 242 | ||
243 | loader.on('error', function() { | 243 | loader.on('error', function() { |
244 | errors++; | 244 | errors++; |
... | @@ -256,7 +256,7 @@ | ... | @@ -256,7 +256,7 @@ |
256 | }); | 256 | }); |
257 | 257 | ||
258 | test('switches media playlists when requested', function() { | 258 | test('switches media playlists when requested', function() { |
259 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 259 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
260 | requests.pop().respond(200, null, | 260 | requests.pop().respond(200, null, |
261 | '#EXTM3U\n' + | 261 | '#EXTM3U\n' + |
262 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + | 262 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + |
... | @@ -284,7 +284,7 @@ | ... | @@ -284,7 +284,7 @@ |
284 | }); | 284 | }); |
285 | 285 | ||
286 | test('can switch media playlists based on URI', function() { | 286 | test('can switch media playlists based on URI', function() { |
287 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 287 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
288 | requests.pop().respond(200, null, | 288 | requests.pop().respond(200, null, |
289 | '#EXTM3U\n' + | 289 | '#EXTM3U\n' + |
290 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + | 290 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + |
... | @@ -312,7 +312,7 @@ | ... | @@ -312,7 +312,7 @@ |
312 | }); | 312 | }); |
313 | 313 | ||
314 | test('aborts in-flight playlist refreshes when switching', function() { | 314 | test('aborts in-flight playlist refreshes when switching', function() { |
315 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 315 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
316 | requests.pop().respond(200, null, | 316 | requests.pop().respond(200, null, |
317 | '#EXTM3U\n' + | 317 | '#EXTM3U\n' + |
318 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + | 318 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + |
... | @@ -331,7 +331,7 @@ | ... | @@ -331,7 +331,7 @@ |
331 | }); | 331 | }); |
332 | 332 | ||
333 | test('switching to the active playlist is a no-op', function() { | 333 | test('switching to the active playlist is a no-op', function() { |
334 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 334 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
335 | requests.pop().respond(200, null, | 335 | requests.pop().respond(200, null, |
336 | '#EXTM3U\n' + | 336 | '#EXTM3U\n' + |
337 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + | 337 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + |
... | @@ -350,7 +350,7 @@ | ... | @@ -350,7 +350,7 @@ |
350 | }); | 350 | }); |
351 | 351 | ||
352 | test('throws an error if a media switch is initiated too early', function() { | 352 | test('throws an error if a media switch is initiated too early', function() { |
353 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 353 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
354 | 354 | ||
355 | throws(function() { | 355 | throws(function() { |
356 | loader.media('high.m3u8'); | 356 | loader.media('high.m3u8'); |
... | @@ -368,7 +368,7 @@ | ... | @@ -368,7 +368,7 @@ |
368 | }); | 368 | }); |
369 | 369 | ||
370 | test('throws an error if a switch to an unrecognized playlist is requested', function() { | 370 | test('throws an error if a switch to an unrecognized playlist is requested', function() { |
371 | var loader = new videojs.hls.PlaylistLoader('master.m3u8'); | 371 | var loader = new videojs.Hls.PlaylistLoader('master.m3u8'); |
372 | requests.pop().respond(200, null, | 372 | requests.pop().respond(200, null, |
373 | '#EXTM3U\n' + | 373 | '#EXTM3U\n' + |
374 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + | 374 | '#EXT-X-STREAM-INF:BANDWIDTH=1\n' + |
... | @@ -378,4 +378,31 @@ | ... | @@ -378,4 +378,31 @@ |
378 | loader.media('unrecognized.m3u8'); | 378 | loader.media('unrecognized.m3u8'); |
379 | }, 'throws an error'); | 379 | }, 'throws an error'); |
380 | }); | 380 | }); |
381 | |||
382 | test('dispose cancels the refresh timeout', function() { | ||
383 | var loader = new videojs.Hls.PlaylistLoader('live.m3u8'); | ||
384 | requests.pop().respond(200, null, | ||
385 | '#EXTM3U\n' + | ||
386 | '#EXT-X-MEDIA-SEQUENCE:0\n' + | ||
387 | '#EXTINF:10,\n' + | ||
388 | '0.ts\n'); | ||
389 | loader.dispose(); | ||
390 | // a lot of time passes... | ||
391 | clock.tick(15 * 1000); | ||
392 | |||
393 | strictEqual(requests.length, 0, 'no refresh request was made'); | ||
394 | }); | ||
395 | |||
396 | test('dispose aborts pending refresh requests', function() { | ||
397 | var loader = new videojs.Hls.PlaylistLoader('live.m3u8'); | ||
398 | requests.pop().respond(200, null, | ||
399 | '#EXTM3U\n' + | ||
400 | '#EXT-X-MEDIA-SEQUENCE:0\n' + | ||
401 | '#EXTINF:10,\n' + | ||
402 | '0.ts\n'); | ||
403 | clock.tick(10 * 1000); | ||
404 | |||
405 | loader.dispose(); | ||
406 | ok(requests[0].aborted, 'refresh request aborted'); | ||
407 | }); | ||
381 | })(window); | 408 | })(window); | ... | ... |
... | @@ -39,7 +39,7 @@ | ... | @@ -39,7 +39,7 @@ |
39 | 39 | ||
40 | module('segment parser', { | 40 | module('segment parser', { |
41 | setup: function() { | 41 | setup: function() { |
42 | parser = new window.videojs.hls.SegmentParser(); | 42 | parser = new window.videojs.Hls.SegmentParser(); |
43 | } | 43 | } |
44 | }); | 44 | }); |
45 | 45 | ||
... | @@ -168,11 +168,11 @@ | ... | @@ -168,11 +168,11 @@ |
168 | result = result.concat(makePsi(settings)); | 168 | result = result.concat(makePsi(settings)); |
169 | 169 | ||
170 | // ensure the resulting packet is the correct size | 170 | // ensure the resulting packet is the correct size |
171 | result.length = window.videojs.hls.SegmentParser.MP2T_PACKET_LENGTH; | 171 | result.length = window.videojs.Hls.SegmentParser.MP2T_PACKET_LENGTH; |
172 | return result; | 172 | return result; |
173 | }, | 173 | }, |
174 | h264Type = window.videojs.hls.SegmentParser.STREAM_TYPES.h264, | 174 | h264Type = window.videojs.Hls.SegmentParser.STREAM_TYPES.h264, |
175 | adtsType = window.videojs.hls.SegmentParser.STREAM_TYPES.adts; | 175 | adtsType = window.videojs.Hls.SegmentParser.STREAM_TYPES.adts; |
176 | 176 | ||
177 | parser.parseSegmentBinaryData(new Uint8Array(makePacket({ | 177 | parser.parseSegmentBinaryData(new Uint8Array(makePacket({ |
178 | programs: { | 178 | programs: { | ... | ... |
This diff is collapsed.
Click to expand it.
-
Please register or sign in to post a comment