Update HLS:
dispose tech, playlist loader don't trigger loadedmetadata if there was an error no need for duration update workarounds, add duration to tech update all the tests remove irrelevant tests
Showing
4 changed files
with
178 additions
and
185 deletions
... | @@ -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 | } | ... | ... |
... | @@ -153,7 +153,13 @@ var | ... | @@ -153,7 +153,13 @@ var |
153 | var | 153 | var |
154 | duration = 0, | 154 | duration = 0, |
155 | segment, | 155 | segment, |
156 | i = (playlist.segments || []).length; | 156 | i; |
157 | |||
158 | if (!playlist) { | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | i = (playlist.segments || []).length; | ||
157 | 163 | ||
158 | // if present, use the duration specified in the playlist | 164 | // if present, use the duration specified in the playlist |
159 | if (playlist.totalDuration) { | 165 | if (playlist.totalDuration) { |
... | @@ -205,16 +211,8 @@ var | ... | @@ -205,16 +211,8 @@ var |
205 | * Update the player duration | 211 | * Update the player duration |
206 | */ | 212 | */ |
207 | updateDuration = function(playlist) { | 213 | updateDuration = function(playlist) { |
208 | var tech; | ||
209 | // update the duration | 214 | // update the duration |
210 | player.duration(totalDuration(playlist)); | 215 | player.duration(totalDuration(playlist)); |
211 | // tell the flash tech of the new duration | ||
212 | tech = player.el().querySelector('.vjs-tech'); | ||
213 | if(tech.vjs_setProperty) { | ||
214 | tech.vjs_setProperty('duration', player.duration()); | ||
215 | } | ||
216 | // manually fire the duration change | ||
217 | player.trigger('durationchange'); | ||
218 | }; | 216 | }; |
219 | 217 | ||
220 | /** | 218 | /** |
... | @@ -310,7 +308,8 @@ var | ... | @@ -310,7 +308,8 @@ var |
310 | } | 308 | } |
311 | 309 | ||
312 | // if no segments are available, do nothing | 310 | // if no segments are available, do nothing |
313 | if (!player.hls.playlists.media().segments) { | 311 | if (player.hls.playlists.state === "HAVE_NOTHING" || |
312 | !player.hls.playlists.media().segments) { | ||
314 | return; | 313 | return; |
315 | } | 314 | } |
316 | 315 | ||
... | @@ -456,12 +455,12 @@ videojs.Hls = videojs.Flash.extend({ | ... | @@ -456,12 +455,12 @@ videojs.Hls = videojs.Flash.extend({ |
456 | source = options.source, | 455 | source = options.source, |
457 | settings = player.options(); | 456 | settings = player.options(); |
458 | 457 | ||
458 | player.hls = this; | ||
459 | delete options.source; | 459 | delete options.source; |
460 | options.swf = settings.flash.swf; | 460 | options.swf = settings.flash.swf; |
461 | videojs.Flash.call(this, player, options, ready); | 461 | videojs.Flash.call(this, player, options, ready); |
462 | player.hls = {}; | ||
463 | options.source = source; | 462 | options.source = source; |
464 | videojs.Hls.prototype.src.call(player, options.source && options.source.src); | 463 | videojs.Hls.prototype.src.call(this, options.source && options.source.src); |
465 | } | 464 | } |
466 | }); | 465 | }); |
467 | 466 | ||
... | @@ -472,7 +471,7 @@ videojs.Hls.prototype.src = function(src) { | ... | @@ -472,7 +471,7 @@ videojs.Hls.prototype.src = function(src) { |
472 | source; | 471 | source; |
473 | 472 | ||
474 | if (src) { | 473 | if (src) { |
475 | mediaSource = new videojs.MediaSource(), | 474 | mediaSource = new videojs.MediaSource(); |
476 | source = { | 475 | source = { |
477 | src: videojs.URL.createObjectURL(mediaSource), | 476 | src: videojs.URL.createObjectURL(mediaSource), |
478 | type: "video/flv" | 477 | type: "video/flv" |
... | @@ -480,10 +479,25 @@ videojs.Hls.prototype.src = function(src) { | ... | @@ -480,10 +479,25 @@ videojs.Hls.prototype.src = function(src) { |
480 | player.hls.mediaSource = mediaSource; | 479 | player.hls.mediaSource = mediaSource; |
481 | initSource(player, mediaSource, src); | 480 | initSource(player, mediaSource, src); |
482 | this.ready(function() { | 481 | this.ready(function() { |
483 | this.el().querySelector('.vjs-tech').vjs_src(source.src); | 482 | this.el().vjs_src(source.src); |
484 | }); | 483 | }); |
485 | } | 484 | } |
486 | } | 485 | }; |
486 | |||
487 | videojs.Hls.prototype.duration = function() { | ||
488 | var playlists = this.player().hls.playlists; | ||
489 | if (playlists) { | ||
490 | return totalDuration(playlists.media()); | ||
491 | } | ||
492 | return 0; | ||
493 | }; | ||
494 | |||
495 | videojs.Hls.prototype.dispose = function() { | ||
496 | if (this.player().hls.playlists) { | ||
497 | this.player().hls.playlists.dispose(); | ||
498 | } | ||
499 | videojs.Flash.prototype.dispose.call(this); | ||
500 | }; | ||
487 | 501 | ||
488 | //for (var prop in videojs.Flash) { | 502 | //for (var prop in videojs.Flash) { |
489 | //videojs.Hls[prop] = videojs.Flash[prop]; | 503 | //videojs.Hls[prop] = videojs.Flash[prop]; | ... | ... |
... | @@ -15,7 +15,7 @@ | ... | @@ -15,7 +15,7 @@ |
15 | <script src="../libs/qunit/qunit.js"></script> | 15 | <script src="../libs/qunit/qunit.js"></script> |
16 | 16 | ||
17 | <!-- video.js --> | 17 | <!-- video.js --> |
18 | <script src="../node_modules/video.js/dist/video-js/video.dev.js"></script> | 18 | <script src="../node_modules/video.js/dist/video-js/video.js"></script> |
19 | <script src="../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> | 19 | <script src="../node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> |
20 | 20 | ||
21 | <!-- HLS plugin --> | 21 | <!-- HLS plugin --> | ... | ... |
... | @@ -22,12 +22,11 @@ | ... | @@ -22,12 +22,11 @@ |
22 | 22 | ||
23 | var | 23 | var |
24 | player, | 24 | player, |
25 | oldFlashSupported, | 25 | oldMediaSourceOpen, |
26 | oldSegmentParser, | 26 | oldSegmentParser, |
27 | oldSetTimeout, | 27 | oldSetTimeout, |
28 | oldSourceBuffer, | 28 | oldSourceBuffer, |
29 | oldSupportsNativeHls, | 29 | oldFlashSupported, |
30 | xhrUrls, | ||
31 | requests, | 30 | requests, |
32 | xhr, | 31 | xhr, |
33 | 32 | ||
... | @@ -82,37 +81,37 @@ var | ... | @@ -82,37 +81,37 @@ var |
82 | 81 | ||
83 | module('HLS', { | 82 | module('HLS', { |
84 | setup: function() { | 83 | setup: function() { |
84 | oldMediaSourceOpen = videojs.MediaSource.open; | ||
85 | videojs.MediaSource.open = function() {}; | ||
85 | 86 | ||
86 | // mock out Flash features for phantomjs | 87 | // mock out Flash features for phantomjs |
87 | oldFlashSupported = videojs.Flash.isSupported; | 88 | oldFlashSupported = videojs.Flash.isSupported; |
88 | videojs.Flash.isSupported = function() { | 89 | videojs.Flash.isSupported = function() { |
89 | return true; | 90 | return true; |
90 | }; | 91 | }; |
92 | |||
91 | oldSourceBuffer = window.videojs.SourceBuffer; | 93 | oldSourceBuffer = window.videojs.SourceBuffer; |
92 | window.videojs.SourceBuffer = function() { | 94 | window.videojs.SourceBuffer = function() { |
93 | this.appendBuffer = function() {}; | 95 | this.appendBuffer = function() {}; |
94 | this.abort = function() {}; | 96 | this.abort = function() {}; |
95 | }; | 97 | }; |
96 | 98 | ||
97 | // force native HLS to be ignored | ||
98 | oldSupportsNativeHls = videojs.hls.supportsNativeHls; | ||
99 | videojs.hls.supportsNativeHls = false; | ||
100 | |||
101 | // create the test player | 99 | // create the test player |
102 | var video = document.createElement('video'); | 100 | var video = document.createElement('video'); |
103 | document.querySelector('#qunit-fixture').appendChild(video); | 101 | document.querySelector('#qunit-fixture').appendChild(video); |
104 | player = videojs(video, { | 102 | player = videojs(video, { |
105 | flash: { | 103 | flash: { |
106 | swf: '../node_modules/video.js/dist/video-js/video-js.swf' | 104 | swf: ''//'../node_modules/video.js/dist/video-js/video-js.swf' |
107 | }, | 105 | }, |
108 | techOrder: ['flash'] | 106 | techOrder: ['hls'] |
109 | }); | 107 | }); |
108 | |||
110 | player.buffered = function() { | 109 | player.buffered = function() { |
111 | return videojs.createTimeRange(0, 0); | 110 | return videojs.createTimeRange(0, 0); |
112 | }; | 111 | }; |
113 | 112 | ||
114 | // store functionality that some tests need to mock | 113 | // store functionality that some tests need to mock |
115 | oldSegmentParser = videojs.hls.SegmentParser; | 114 | oldSegmentParser = videojs.Hls.SegmentParser; |
116 | oldSetTimeout = window.setTimeout; | 115 | oldSetTimeout = window.setTimeout; |
117 | 116 | ||
118 | // fake XHRs | 117 | // fake XHRs |
... | @@ -121,13 +120,18 @@ module('HLS', { | ... | @@ -121,13 +120,18 @@ module('HLS', { |
121 | xhr.onCreate = function(xhr) { | 120 | xhr.onCreate = function(xhr) { |
122 | requests.push(xhr); | 121 | requests.push(xhr); |
123 | }; | 122 | }; |
124 | xhrUrls = []; | 123 | |
124 | var tech = player.el().querySelector('.vjs-tech'); | ||
125 | tech.vjs_getProperty = function() {}; | ||
126 | tech.vjs_src = function() {}; | ||
127 | videojs.Flash.onReady(tech.id); | ||
125 | }, | 128 | }, |
126 | 129 | ||
127 | teardown: function() { | 130 | teardown: function() { |
131 | player.dispose(); | ||
128 | videojs.Flash.isSupported = oldFlashSupported; | 132 | videojs.Flash.isSupported = oldFlashSupported; |
129 | videojs.hls.supportsNativeHls = oldSupportsNativeHls; | 133 | videojs.MediaSource.open = oldMediaSourceOpen; |
130 | videojs.hls.SegmentParser = oldSegmentParser; | 134 | videojs.Hls.SegmentParser = oldSegmentParser; |
131 | videojs.SourceBuffer = oldSourceBuffer; | 135 | videojs.SourceBuffer = oldSourceBuffer; |
132 | window.setTimeout = oldSetTimeout; | 136 | window.setTimeout = oldSetTimeout; |
133 | xhr.restore(); | 137 | xhr.restore(); |
... | @@ -140,8 +144,8 @@ test('starts playing if autoplay is specified', function() { | ... | @@ -140,8 +144,8 @@ test('starts playing if autoplay is specified', function() { |
140 | plays++; | 144 | plays++; |
141 | }; | 145 | }; |
142 | player.options().autoplay = true; | 146 | player.options().autoplay = true; |
143 | player.hls('manifest/playlist.m3u8'); | 147 | player.src({src: 'manifest/playlist.m3u8', type: 'application/vnd.apple.mpegurl'}); |
144 | videojs.mediaSources[player.currentSrc()].trigger({ | 148 | player.hls.mediaSource.trigger({ |
145 | type: 'sourceopen' | 149 | type: 'sourceopen' |
146 | }); | 150 | }); |
147 | 151 | ||
... | @@ -155,9 +159,9 @@ test('creates a PlaylistLoader on init', function() { | ... | @@ -155,9 +159,9 @@ test('creates a PlaylistLoader on init', function() { |
155 | loadedmetadata = true; | 159 | loadedmetadata = true; |
156 | }); | 160 | }); |
157 | 161 | ||
158 | player.hls('manifest/playlist.m3u8'); | 162 | ok(!player.hls.playlists, 'waits for set src to create the loader'); |
159 | ok(!player.hls.playlists, 'waits for sourceopen to create the loader'); | 163 | player.src({src:'manifest/playlist.m3u8', type: 'application/vnd.apple.mpegurl'}); |
160 | videojs.mediaSources[player.currentSrc()].trigger({ | 164 | player.hls.mediaSource.trigger({ |
161 | type: 'sourceopen' | 165 | type: 'sourceopen' |
162 | }); | 166 | }); |
163 | standardXHRResponse(requests[0]); | 167 | standardXHRResponse(requests[0]); |
... | @@ -178,8 +182,8 @@ test('sets the duration if one is available on the playlist', function() { | ... | @@ -178,8 +182,8 @@ test('sets the duration if one is available on the playlist', function() { |
178 | } | 182 | } |
179 | calls++; | 183 | calls++; |
180 | }; | 184 | }; |
181 | player.hls('manifest/media.m3u8'); | 185 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
182 | videojs.mediaSources[player.currentSrc()].trigger({ | 186 | player.hls.mediaSource.trigger({ |
183 | type: 'sourceopen' | 187 | type: 'sourceopen' |
184 | }); | 188 | }); |
185 | 189 | ||
... | @@ -197,8 +201,8 @@ test('calculates the duration if needed', function() { | ... | @@ -197,8 +201,8 @@ test('calculates the duration if needed', function() { |
197 | } | 201 | } |
198 | durations.push(duration); | 202 | durations.push(duration); |
199 | }; | 203 | }; |
200 | player.hls('http://example.com/manifest/missingExtinf.m3u8'); | 204 | player.src({src: 'http://example.com/manifest/missingExtinf.m3u8', type: 'application/vnd.apple.mpegurl'}); |
201 | videojs.mediaSources[player.currentSrc()].trigger({ | 205 | player.hls.mediaSource.trigger({ |
202 | type: 'sourceopen' | 206 | type: 'sourceopen' |
203 | }); | 207 | }); |
204 | 208 | ||
... | @@ -210,11 +214,11 @@ test('calculates the duration if needed', function() { | ... | @@ -210,11 +214,11 @@ test('calculates the duration if needed', function() { |
210 | }); | 214 | }); |
211 | 215 | ||
212 | test('starts downloading a segment on loadedmetadata', function() { | 216 | test('starts downloading a segment on loadedmetadata', function() { |
213 | player.hls('manifest/media.m3u8'); | 217 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
214 | player.buffered = function() { | 218 | player.buffered = function() { |
215 | return videojs.createTimeRange(0, 0); | 219 | return videojs.createTimeRange(0, 0); |
216 | }; | 220 | }; |
217 | videojs.mediaSources[player.currentSrc()].trigger({ | 221 | player.hls.mediaSource.trigger({ |
218 | type: 'sourceopen' | 222 | type: 'sourceopen' |
219 | }); | 223 | }); |
220 | 224 | ||
... | @@ -228,8 +232,8 @@ test('starts downloading a segment on loadedmetadata', function() { | ... | @@ -228,8 +232,8 @@ test('starts downloading a segment on loadedmetadata', function() { |
228 | }); | 232 | }); |
229 | 233 | ||
230 | test('recognizes absolute URIs and requests them unmodified', function() { | 234 | test('recognizes absolute URIs and requests them unmodified', function() { |
231 | player.hls('manifest/absoluteUris.m3u8'); | 235 | player.src({src: 'manifest/absoluteUris.m3u8', type: 'application/vnd.apple.mpegurl'}); |
232 | videojs.mediaSources[player.currentSrc()].trigger({ | 236 | player.hls.mediaSource.trigger({ |
233 | type: 'sourceopen' | 237 | type: 'sourceopen' |
234 | }); | 238 | }); |
235 | 239 | ||
... | @@ -241,8 +245,8 @@ test('recognizes absolute URIs and requests them unmodified', function() { | ... | @@ -241,8 +245,8 @@ test('recognizes absolute URIs and requests them unmodified', function() { |
241 | }); | 245 | }); |
242 | 246 | ||
243 | test('recognizes domain-relative URLs', function() { | 247 | test('recognizes domain-relative URLs', function() { |
244 | player.hls('manifest/domainUris.m3u8'); | 248 | player.src({src: 'manifest/domainUris.m3u8', type: 'application/vnd.apple.mpegurl'}); |
245 | videojs.mediaSources[player.currentSrc()].trigger({ | 249 | player.hls.mediaSource.trigger({ |
246 | type: 'sourceopen' | 250 | type: 'sourceopen' |
247 | }); | 251 | }); |
248 | 252 | ||
... | @@ -253,14 +257,25 @@ test('recognizes domain-relative URLs', function() { | ... | @@ -253,14 +257,25 @@ test('recognizes domain-relative URLs', function() { |
253 | 'the first segment is requested'); | 257 | 'the first segment is requested'); |
254 | }); | 258 | }); |
255 | 259 | ||
256 | test('re-initializes the plugin for each source', function() { | 260 | test('re-initializes the tech for each source', function() { |
257 | var firstInit, secondInit; | 261 | var firstPlaylists, secondPlaylists, firstMSE, secondMSE; |
258 | player.hls('manifest/master.m3u8'); | 262 | |
259 | firstInit = player.hls; | 263 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
260 | player.hls('manifest/master.m3u8'); | 264 | player.hls.mediaSource.trigger({ |
261 | secondInit = player.hls; | 265 | type: 'sourceopen' |
266 | }); | ||
267 | firstPlaylists = player.hls.playlists; | ||
268 | firstMSE = player.hls.mediaSource; | ||
269 | |||
270 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); | ||
271 | player.hls.mediaSource.trigger({ | ||
272 | type: 'sourceopen' | ||
273 | }); | ||
274 | secondPlaylists = player.hls.playlists; | ||
275 | secondMSE = player.hls.mediaSource; | ||
262 | 276 | ||
263 | notStrictEqual(firstInit, secondInit, 'the plugin object is replaced'); | 277 | notStrictEqual(firstPlaylists, secondPlaylists, 'the playlist object is not reused'); |
278 | notStrictEqual(firstMSE, secondMSE, 'the media source object is not reused'); | ||
264 | }); | 279 | }); |
265 | 280 | ||
266 | test('triggers an error when a master playlist request errors', function() { | 281 | test('triggers an error when a master playlist request errors', function() { |
... | @@ -268,8 +283,8 @@ test('triggers an error when a master playlist request errors', function() { | ... | @@ -268,8 +283,8 @@ test('triggers an error when a master playlist request errors', function() { |
268 | player.on('error', function() { | 283 | player.on('error', function() { |
269 | error = player.hls.error; | 284 | error = player.hls.error; |
270 | }); | 285 | }); |
271 | player.hls('manifest/master.m3u8'); | 286 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
272 | videojs.mediaSources[player.currentSrc()].trigger({ | 287 | player.hls.mediaSource.trigger({ |
273 | type: 'sourceopen' | 288 | type: 'sourceopen' |
274 | }); | 289 | }); |
275 | requests.pop().respond(500); | 290 | requests.pop().respond(500); |
... | @@ -279,8 +294,8 @@ test('triggers an error when a master playlist request errors', function() { | ... | @@ -279,8 +294,8 @@ test('triggers an error when a master playlist request errors', function() { |
279 | }); | 294 | }); |
280 | 295 | ||
281 | test('downloads media playlists after loading the master', function() { | 296 | test('downloads media playlists after loading the master', function() { |
282 | player.hls('manifest/master.m3u8'); | 297 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
283 | videojs.mediaSources[player.currentSrc()].trigger({ | 298 | player.hls.mediaSource.trigger({ |
284 | type: 'sourceopen' | 299 | type: 'sourceopen' |
285 | }); | 300 | }); |
286 | 301 | ||
... | @@ -309,8 +324,8 @@ test('timeupdates do not check to fill the buffer until a media playlist is read | ... | @@ -309,8 +324,8 @@ test('timeupdates do not check to fill the buffer until a media playlist is read |
309 | }; | 324 | }; |
310 | this.send = function() {}; | 325 | this.send = function() {}; |
311 | }; | 326 | }; |
312 | player.hls('manifest/media.m3u8'); | 327 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
313 | videojs.mediaSources[player.currentSrc()].trigger({ | 328 | player.hls.mediaSource.trigger({ |
314 | type: 'sourceopen' | 329 | type: 'sourceopen' |
315 | }); | 330 | }); |
316 | player.trigger('timeupdate'); | 331 | player.trigger('timeupdate'); |
... | @@ -320,8 +335,8 @@ test('timeupdates do not check to fill the buffer until a media playlist is read | ... | @@ -320,8 +335,8 @@ test('timeupdates do not check to fill the buffer until a media playlist is read |
320 | }); | 335 | }); |
321 | 336 | ||
322 | test('calculates the bandwidth after downloading a segment', function() { | 337 | test('calculates the bandwidth after downloading a segment', function() { |
323 | player.hls('manifest/media.m3u8'); | 338 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
324 | videojs.mediaSources[player.currentSrc()].trigger({ | 339 | player.hls.mediaSource.trigger({ |
325 | type: 'sourceopen' | 340 | type: 'sourceopen' |
326 | }); | 341 | }); |
327 | 342 | ||
... | @@ -337,12 +352,12 @@ test('calculates the bandwidth after downloading a segment', function() { | ... | @@ -337,12 +352,12 @@ test('calculates the bandwidth after downloading a segment', function() { |
337 | 352 | ||
338 | test('selects a playlist after segment downloads', function() { | 353 | test('selects a playlist after segment downloads', function() { |
339 | var calls = 0; | 354 | var calls = 0; |
340 | player.hls('manifest/master.m3u8'); | 355 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
341 | player.hls.selectPlaylist = function() { | 356 | player.hls.selectPlaylist = function() { |
342 | calls++; | 357 | calls++; |
343 | return player.hls.playlists.master.playlists[0]; | 358 | return player.hls.playlists.master.playlists[0]; |
344 | }; | 359 | }; |
345 | videojs.mediaSources[player.currentSrc()].trigger({ | 360 | player.hls.mediaSource.trigger({ |
346 | type: 'sourceopen' | 361 | type: 'sourceopen' |
347 | }); | 362 | }); |
348 | 363 | ||
... | @@ -367,8 +382,8 @@ test('selects a playlist after segment downloads', function() { | ... | @@ -367,8 +382,8 @@ test('selects a playlist after segment downloads', function() { |
367 | test('moves to the next segment if there is a network error', function() { | 382 | test('moves to the next segment if there is a network error', function() { |
368 | var mediaIndex; | 383 | var mediaIndex; |
369 | 384 | ||
370 | player.hls('manifest/master.m3u8'); | 385 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
371 | videojs.mediaSources[player.currentSrc()].trigger({ | 386 | player.hls.mediaSource.trigger({ |
372 | type: 'sourceopen' | 387 | type: 'sourceopen' |
373 | }); | 388 | }); |
374 | 389 | ||
... | @@ -386,7 +401,7 @@ test('updates the duration after switching playlists', function() { | ... | @@ -386,7 +401,7 @@ test('updates the duration after switching playlists', function() { |
386 | var | 401 | var |
387 | calls = 0, | 402 | calls = 0, |
388 | selectedPlaylist = false; | 403 | selectedPlaylist = false; |
389 | player.hls('manifest/master.m3u8'); | 404 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
390 | player.hls.selectPlaylist = function() { | 405 | player.hls.selectPlaylist = function() { |
391 | selectedPlaylist = true; | 406 | selectedPlaylist = true; |
392 | return player.hls.playlists.master.playlists[1]; | 407 | return player.hls.playlists.master.playlists[1]; |
... | @@ -400,7 +415,7 @@ test('updates the duration after switching playlists', function() { | ... | @@ -400,7 +415,7 @@ test('updates the duration after switching playlists', function() { |
400 | calls++; | 415 | calls++; |
401 | } | 416 | } |
402 | }; | 417 | }; |
403 | videojs.mediaSources[player.currentSrc()].trigger({ | 418 | player.hls.mediaSource.trigger({ |
404 | type: 'sourceopen' | 419 | type: 'sourceopen' |
405 | }); | 420 | }); |
406 | 421 | ||
... | @@ -418,8 +433,8 @@ test('downloads additional playlists if required', function() { | ... | @@ -418,8 +433,8 @@ test('downloads additional playlists if required', function() { |
418 | playlist = { | 433 | playlist = { |
419 | uri: 'media3.m3u8' | 434 | uri: 'media3.m3u8' |
420 | }; | 435 | }; |
421 | player.hls('manifest/master.m3u8'); | 436 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
422 | videojs.mediaSources[player.currentSrc()].trigger({ | 437 | player.hls.mediaSource.trigger({ |
423 | type: 'sourceopen' | 438 | type: 'sourceopen' |
424 | }); | 439 | }); |
425 | 440 | ||
... | @@ -456,8 +471,8 @@ test('downloads additional playlists if required', function() { | ... | @@ -456,8 +471,8 @@ test('downloads additional playlists if required', function() { |
456 | 471 | ||
457 | test('selects a playlist below the current bandwidth', function() { | 472 | test('selects a playlist below the current bandwidth', function() { |
458 | var playlist; | 473 | var playlist; |
459 | player.hls('manifest/master.m3u8'); | 474 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
460 | videojs.mediaSources[player.currentSrc()].trigger({ | 475 | player.hls.mediaSource.trigger({ |
461 | type: 'sourceopen' | 476 | type: 'sourceopen' |
462 | }); | 477 | }); |
463 | 478 | ||
... | @@ -478,8 +493,8 @@ test('selects a playlist below the current bandwidth', function() { | ... | @@ -478,8 +493,8 @@ test('selects a playlist below the current bandwidth', function() { |
478 | 493 | ||
479 | test('raises the minimum bitrate for a stream proportionially', function() { | 494 | test('raises the minimum bitrate for a stream proportionially', function() { |
480 | var playlist; | 495 | var playlist; |
481 | player.hls('manifest/master.m3u8'); | 496 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
482 | videojs.mediaSources[player.currentSrc()].trigger({ | 497 | player.hls.mediaSource.trigger({ |
483 | type: 'sourceopen' | 498 | type: 'sourceopen' |
484 | }); | 499 | }); |
485 | 500 | ||
... | @@ -500,8 +515,8 @@ test('raises the minimum bitrate for a stream proportionially', function() { | ... | @@ -500,8 +515,8 @@ test('raises the minimum bitrate for a stream proportionially', function() { |
500 | 515 | ||
501 | test('uses the lowest bitrate if no other is suitable', function() { | 516 | test('uses the lowest bitrate if no other is suitable', function() { |
502 | var playlist; | 517 | var playlist; |
503 | player.hls('manifest/master.m3u8'); | 518 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
504 | videojs.mediaSources[player.currentSrc()].trigger({ | 519 | player.hls.mediaSource.trigger({ |
505 | type: 'sourceopen' | 520 | type: 'sourceopen' |
506 | }); | 521 | }); |
507 | 522 | ||
... | @@ -520,9 +535,9 @@ test('uses the lowest bitrate if no other is suitable', function() { | ... | @@ -520,9 +535,9 @@ test('uses the lowest bitrate if no other is suitable', function() { |
520 | test('selects the correct rendition by player dimensions', function() { | 535 | test('selects the correct rendition by player dimensions', function() { |
521 | var playlist; | 536 | var playlist; |
522 | 537 | ||
523 | player.hls('manifest/master.m3u8'); | 538 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
524 | 539 | ||
525 | videojs.mediaSources[player.currentSrc()].trigger({ | 540 | player.hls.mediaSource.trigger({ |
526 | type: 'sourceopen' | 541 | type: 'sourceopen' |
527 | }); | 542 | }); |
528 | 543 | ||
... | @@ -550,14 +565,14 @@ test('selects the correct rendition by player dimensions', function() { | ... | @@ -550,14 +565,14 @@ test('selects the correct rendition by player dimensions', function() { |
550 | 565 | ||
551 | 566 | ||
552 | test('does not download the next segment if the buffer is full', function() { | 567 | test('does not download the next segment if the buffer is full', function() { |
553 | player.hls('manifest/media.m3u8'); | 568 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
554 | player.currentTime = function() { | 569 | player.currentTime = function() { |
555 | return 15; | 570 | return 15; |
556 | }; | 571 | }; |
557 | player.buffered = function() { | 572 | player.buffered = function() { |
558 | return videojs.createTimeRange(0, 20); | 573 | return videojs.createTimeRange(0, 20); |
559 | }; | 574 | }; |
560 | videojs.mediaSources[player.currentSrc()].trigger({ | 575 | player.hls.mediaSource.trigger({ |
561 | type: 'sourceopen' | 576 | type: 'sourceopen' |
562 | }); | 577 | }); |
563 | 578 | ||
... | @@ -569,8 +584,8 @@ test('does not download the next segment if the buffer is full', function() { | ... | @@ -569,8 +584,8 @@ test('does not download the next segment if the buffer is full', function() { |
569 | }); | 584 | }); |
570 | 585 | ||
571 | test('downloads the next segment if the buffer is getting low', function() { | 586 | test('downloads the next segment if the buffer is getting low', function() { |
572 | player.hls('manifest/media.m3u8'); | 587 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
573 | videojs.mediaSources[player.currentSrc()].trigger({ | 588 | player.hls.mediaSource.trigger({ |
574 | type: 'sourceopen' | 589 | type: 'sourceopen' |
575 | }); | 590 | }); |
576 | 591 | ||
... | @@ -597,8 +612,8 @@ test('downloads the next segment if the buffer is getting low', function() { | ... | @@ -597,8 +612,8 @@ test('downloads the next segment if the buffer is getting low', function() { |
597 | }); | 612 | }); |
598 | 613 | ||
599 | test('stops downloading segments at the end of the playlist', function() { | 614 | test('stops downloading segments at the end of the playlist', function() { |
600 | player.hls('manifest/media.m3u8'); | 615 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
601 | videojs.mediaSources[player.currentSrc()].trigger({ | 616 | player.hls.mediaSource.trigger({ |
602 | type: 'sourceopen' | 617 | type: 'sourceopen' |
603 | }); | 618 | }); |
604 | standardXHRResponse(requests[0]); | 619 | standardXHRResponse(requests[0]); |
... | @@ -606,13 +621,13 @@ test('stops downloading segments at the end of the playlist', function() { | ... | @@ -606,13 +621,13 @@ test('stops downloading segments at the end of the playlist', function() { |
606 | player.hls.mediaIndex = 4; | 621 | player.hls.mediaIndex = 4; |
607 | player.trigger('timeupdate'); | 622 | player.trigger('timeupdate'); |
608 | 623 | ||
609 | strictEqual(xhrUrls.length, 0, 'no request is made'); | 624 | strictEqual(requests.length, 0, 'no request is made'); |
610 | }); | 625 | }); |
611 | 626 | ||
612 | test('only makes one segment request at a time', function() { | 627 | test('only makes one segment request at a time', function() { |
613 | var openedXhrs = 0; | 628 | var openedXhrs = 0; |
614 | player.hls('manifest/media.m3u8'); | 629 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
615 | videojs.mediaSources[player.currentSrc()].trigger({ | 630 | player.hls.mediaSource.trigger({ |
616 | type: 'sourceopen' | 631 | type: 'sourceopen' |
617 | }); | 632 | }); |
618 | xhr.restore(); | 633 | xhr.restore(); |
... | @@ -634,68 +649,9 @@ test('only makes one segment request at a time', function() { | ... | @@ -634,68 +649,9 @@ test('only makes one segment request at a time', function() { |
634 | xhr = sinon.useFakeXMLHttpRequest(); | 649 | xhr = sinon.useFakeXMLHttpRequest(); |
635 | }); | 650 | }); |
636 | 651 | ||
637 | test('uses the src attribute if no options are provided and it ends in ".m3u8"', function() { | ||
638 | var url = 'http://example.com/services/mobile/streaming/index/master.m3u8?videoId=1824650741001'; | ||
639 | player.el().querySelector('.vjs-tech').src = url; | ||
640 | player.hls(); | ||
641 | videojs.mediaSources[player.currentSrc()].trigger({ | ||
642 | type: 'sourceopen' | ||
643 | }); | ||
644 | |||
645 | strictEqual(requests[0].url, url, 'currentSrc is used'); | ||
646 | }); | ||
647 | |||
648 | test('ignores src attribute if it doesn\'t have the "m3u8" extension', function() { | ||
649 | var tech = player.el().querySelector('.vjs-tech'); | ||
650 | tech.src = 'basdfasdfasdfliel//.m3u9'; | ||
651 | player.hls(); | ||
652 | ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created'); | ||
653 | strictEqual(requests.length, 0, 'no request is made'); | ||
654 | |||
655 | tech.src = ''; | ||
656 | player.hls(); | ||
657 | ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created'); | ||
658 | strictEqual(requests.length, 0, 'no request is made'); | ||
659 | |||
660 | tech.src = 'http://example.com/movie.mp4?q=why.m3u8'; | ||
661 | player.hls(); | ||
662 | ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created'); | ||
663 | strictEqual(requests.length, 0, 'no request is made'); | ||
664 | |||
665 | tech.src = 'http://example.m3u8/movie.mp4'; | ||
666 | player.hls(); | ||
667 | ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created'); | ||
668 | strictEqual(requests.length, 0, 'no request is made'); | ||
669 | |||
670 | tech.src = '//example.com/movie.mp4#http://tricky.com/master.m3u8'; | ||
671 | player.hls(); | ||
672 | ok(!(player.currentSrc() in videojs.mediaSources), 'no media source is created'); | ||
673 | strictEqual(requests.length, 0, 'no request is made'); | ||
674 | }); | ||
675 | |||
676 | test('activates if the first playable source is HLS', function() { | ||
677 | var video; | ||
678 | document.querySelector('#qunit-fixture').innerHTML = | ||
679 | '<video controls>' + | ||
680 | '<source type="slartibartfast$%" src="movie.slarti">' + | ||
681 | '<source type="application/x-mpegURL" src="movie.m3u8">' + | ||
682 | '<source type="video/mp4" src="movie.mp4">' + | ||
683 | '</video>'; | ||
684 | video = document.querySelector('#qunit-fixture video'); | ||
685 | player = videojs(video, { | ||
686 | flash: { | ||
687 | swf: '../node_modules/video.js/dist/video-js/video-js.swf' | ||
688 | }, | ||
689 | techOrder: ['flash'] | ||
690 | }); | ||
691 | player.hls(); | ||
692 | |||
693 | ok(player.currentSrc() in videojs.mediaSources, 'media source created'); | ||
694 | }); | ||
695 | |||
696 | test('cancels outstanding XHRs when seeking', function() { | 652 | test('cancels outstanding XHRs when seeking', function() { |
697 | player.hls('manifest/media.m3u8'); | 653 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
698 | videojs.mediaSources[player.currentSrc()].trigger({ | 654 | player.hls.mediaSource.trigger({ |
699 | type: 'sourceopen' | 655 | type: 'sourceopen' |
700 | }); | 656 | }); |
701 | standardXHRResponse(requests[0]); | 657 | standardXHRResponse(requests[0]); |
... | @@ -721,7 +677,7 @@ test('cancels outstanding XHRs when seeking', function() { | ... | @@ -721,7 +677,7 @@ test('cancels outstanding XHRs when seeking', function() { |
721 | test('flushes the parser after each segment', function() { | 677 | test('flushes the parser after each segment', function() { |
722 | var flushes = 0; | 678 | var flushes = 0; |
723 | // mock out the segment parser | 679 | // mock out the segment parser |
724 | videojs.hls.SegmentParser = function() { | 680 | videojs.Hls.SegmentParser = function() { |
725 | this.getFlvHeader = function() { | 681 | this.getFlvHeader = function() { |
726 | return []; | 682 | return []; |
727 | }; | 683 | }; |
... | @@ -732,8 +688,8 @@ test('flushes the parser after each segment', function() { | ... | @@ -732,8 +688,8 @@ test('flushes the parser after each segment', function() { |
732 | this.tagsAvailable = function() {}; | 688 | this.tagsAvailable = function() {}; |
733 | }; | 689 | }; |
734 | 690 | ||
735 | player.hls('manifest/media.m3u8'); | 691 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
736 | videojs.mediaSources[player.currentSrc()].trigger({ | 692 | player.hls.mediaSource.trigger({ |
737 | type: 'sourceopen' | 693 | type: 'sourceopen' |
738 | }); | 694 | }); |
739 | 695 | ||
... | @@ -749,7 +705,7 @@ test('drops tags before the target timestamp when seeking', function() { | ... | @@ -749,7 +705,7 @@ test('drops tags before the target timestamp when seeking', function() { |
749 | bytes = []; | 705 | bytes = []; |
750 | 706 | ||
751 | // mock out the parser and source buffer | 707 | // mock out the parser and source buffer |
752 | videojs.hls.SegmentParser = mockSegmentParser(tags); | 708 | videojs.Hls.SegmentParser = mockSegmentParser(tags); |
753 | window.videojs.SourceBuffer = function() { | 709 | window.videojs.SourceBuffer = function() { |
754 | this.appendBuffer = function(chunk) { | 710 | this.appendBuffer = function(chunk) { |
755 | bytes.push(chunk); | 711 | bytes.push(chunk); |
... | @@ -764,8 +720,8 @@ test('drops tags before the target timestamp when seeking', function() { | ... | @@ -764,8 +720,8 @@ test('drops tags before the target timestamp when seeking', function() { |
764 | // push a tag into the buffer | 720 | // push a tag into the buffer |
765 | tags.push({ pts: 0, bytes: 0 }); | 721 | tags.push({ pts: 0, bytes: 0 }); |
766 | 722 | ||
767 | player.hls('manifest/media.m3u8'); | 723 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
768 | videojs.mediaSources[player.currentSrc()].trigger({ | 724 | player.hls.mediaSource.trigger({ |
769 | type: 'sourceopen' | 725 | type: 'sourceopen' |
770 | }); | 726 | }); |
771 | standardXHRResponse(requests[0]); | 727 | standardXHRResponse(requests[0]); |
... | @@ -803,7 +759,7 @@ test('clears pending buffer updates when seeking', function() { | ... | @@ -803,7 +759,7 @@ test('clears pending buffer updates when seeking', function() { |
803 | tags = [{ pts: 0, bytes: 0 }]; | 759 | tags = [{ pts: 0, bytes: 0 }]; |
804 | 760 | ||
805 | // mock out the parser and source buffer | 761 | // mock out the parser and source buffer |
806 | videojs.hls.SegmentParser = mockSegmentParser(tags); | 762 | videojs.Hls.SegmentParser = mockSegmentParser(tags); |
807 | window.videojs.SourceBuffer = function() { | 763 | window.videojs.SourceBuffer = function() { |
808 | this.appendBuffer = function(chunk) { | 764 | this.appendBuffer = function(chunk) { |
809 | bytes.push(chunk); | 765 | bytes.push(chunk); |
... | @@ -818,8 +774,8 @@ test('clears pending buffer updates when seeking', function() { | ... | @@ -818,8 +774,8 @@ test('clears pending buffer updates when seeking', function() { |
818 | }; | 774 | }; |
819 | 775 | ||
820 | // queue up a tag to be pushed into the buffer (but don't push it yet!) | 776 | // queue up a tag to be pushed into the buffer (but don't push it yet!) |
821 | player.hls('manifest/media.m3u8'); | 777 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
822 | videojs.mediaSources[player.currentSrc()].trigger({ | 778 | player.hls.mediaSource.trigger({ |
823 | type: 'sourceopen' | 779 | type: 'sourceopen' |
824 | }); | 780 | }); |
825 | 781 | ||
... | @@ -846,8 +802,8 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { | ... | @@ -846,8 +802,8 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { |
846 | player.on('error', function() { | 802 | player.on('error', function() { |
847 | errorTriggered = true; | 803 | errorTriggered = true; |
848 | }); | 804 | }); |
849 | player.hls('manifest/media.m3u8'); | 805 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
850 | videojs.mediaSources[player.currentSrc()].trigger({ | 806 | player.hls.mediaSource.trigger({ |
851 | type: 'sourceopen' | 807 | type: 'sourceopen' |
852 | }); | 808 | }); |
853 | requests.pop().respond(404); | 809 | requests.pop().respond(404); |
... | @@ -862,9 +818,9 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { | ... | @@ -862,9 +818,9 @@ test('playlist 404 should trigger MEDIA_ERR_NETWORK', function() { |
862 | }); | 818 | }); |
863 | 819 | ||
864 | test('segment 404 should trigger MEDIA_ERR_NETWORK', function () { | 820 | test('segment 404 should trigger MEDIA_ERR_NETWORK', function () { |
865 | player.hls('manifest/media.m3u8'); | 821 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
866 | 822 | ||
867 | videojs.mediaSources[player.currentSrc()].trigger({ | 823 | player.hls.mediaSource.trigger({ |
868 | type: 'sourceopen' | 824 | type: 'sourceopen' |
869 | }); | 825 | }); |
870 | 826 | ||
... | @@ -875,9 +831,9 @@ test('segment 404 should trigger MEDIA_ERR_NETWORK', function () { | ... | @@ -875,9 +831,9 @@ test('segment 404 should trigger MEDIA_ERR_NETWORK', function () { |
875 | }); | 831 | }); |
876 | 832 | ||
877 | test('segment 500 should trigger MEDIA_ERR_ABORTED', function () { | 833 | test('segment 500 should trigger MEDIA_ERR_ABORTED', function () { |
878 | player.hls('manifest/media.m3u8'); | 834 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
879 | 835 | ||
880 | videojs.mediaSources[player.currentSrc()].trigger({ | 836 | player.hls.mediaSource.trigger({ |
881 | type: 'sourceopen' | 837 | type: 'sourceopen' |
882 | }); | 838 | }); |
883 | 839 | ||
... | @@ -888,16 +844,16 @@ test('segment 500 should trigger MEDIA_ERR_ABORTED', function () { | ... | @@ -888,16 +844,16 @@ test('segment 500 should trigger MEDIA_ERR_ABORTED', function () { |
888 | }); | 844 | }); |
889 | 845 | ||
890 | test('has no effect if native HLS is available', function() { | 846 | test('has no effect if native HLS is available', function() { |
891 | videojs.hls.supportsNativeHls = true; | 847 | videojs.Hls.supportsNativeHls = true; |
892 | player.hls('http://example.com/manifest/master.m3u8'); | 848 | player.src({src: 'http://example.com/manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
893 | 849 | ||
894 | ok(!(player.currentSrc() in videojs.mediaSources), | 850 | ok(!(player.currentSrc() in videojs.mediaSources), |
895 | 'no media source was opened'); | 851 | 'no media source was opened'); |
896 | }); | 852 | }); |
897 | 853 | ||
898 | test('duration is Infinity for live playlists', function() { | 854 | test('duration is Infinity for live playlists', function() { |
899 | player.hls('http://example.com/manifest/missingEndlist.m3u8'); | 855 | player.src({src: 'http://example.com/manifest/missingEndlist.m3u8', type: 'application/vnd.apple.mpegurl'}); |
900 | videojs.mediaSources[player.currentSrc()].trigger({ | 856 | player.hls.mediaSource.trigger({ |
901 | type: 'sourceopen' | 857 | type: 'sourceopen' |
902 | }); | 858 | }); |
903 | 859 | ||
... | @@ -912,8 +868,8 @@ test('does not reload playlists with an endlist tag', function() { | ... | @@ -912,8 +868,8 @@ test('does not reload playlists with an endlist tag', function() { |
912 | window.setTimeout = function(callback, timeout) { | 868 | window.setTimeout = function(callback, timeout) { |
913 | callbacks.push({ callback: callback, timeout: timeout }); | 869 | callbacks.push({ callback: callback, timeout: timeout }); |
914 | }; | 870 | }; |
915 | player.hls('manifest/media.m3u8'); | 871 | player.src({src: 'manifest/media.m3u8', type: 'application/vnd.apple.mpegurl'}); |
916 | videojs.mediaSources[player.currentSrc()].trigger({ | 872 | player.hls.mediaSource.trigger({ |
917 | type: 'sourceopen' | 873 | type: 'sourceopen' |
918 | }); | 874 | }); |
919 | 875 | ||
... | @@ -921,8 +877,8 @@ test('does not reload playlists with an endlist tag', function() { | ... | @@ -921,8 +877,8 @@ test('does not reload playlists with an endlist tag', function() { |
921 | }); | 877 | }); |
922 | 878 | ||
923 | test('updates the media index when a playlist reloads', function() { | 879 | test('updates the media index when a playlist reloads', function() { |
924 | player.hls('http://example.com/live-updating.m3u8'); | 880 | player.src({src: 'http://example.com/live-updating.m3u8', type: 'application/vnd.apple.mpegurl'}); |
925 | videojs.mediaSources[player.currentSrc()].trigger({ | 881 | player.hls.mediaSource.trigger({ |
926 | type: 'sourceopen' | 882 | type: 'sourceopen' |
927 | }); | 883 | }); |
928 | 884 | ||
... | @@ -964,8 +920,8 @@ test('mediaIndex is zero before the first segment loads', function() { | ... | @@ -964,8 +920,8 @@ test('mediaIndex is zero before the first segment loads', function() { |
964 | this.open = function() {}; | 920 | this.open = function() {}; |
965 | this.send = function() {}; | 921 | this.send = function() {}; |
966 | }; | 922 | }; |
967 | player.hls('http://example.com/first-seg-load.m3u8'); | 923 | player.src({src: 'http://example.com/first-seg-load.m3u8', type: 'application/vnd.apple.mpegurl'}); |
968 | videojs.mediaSources[player.currentSrc()].trigger({ | 924 | player.hls.mediaSource.trigger({ |
969 | type: 'sourceopen' | 925 | type: 'sourceopen' |
970 | }); | 926 | }); |
971 | 927 | ||
... | @@ -973,8 +929,8 @@ test('mediaIndex is zero before the first segment loads', function() { | ... | @@ -973,8 +929,8 @@ test('mediaIndex is zero before the first segment loads', function() { |
973 | }); | 929 | }); |
974 | 930 | ||
975 | test('reloads out-of-date live playlists when switching variants', function() { | 931 | test('reloads out-of-date live playlists when switching variants', function() { |
976 | player.hls('http://example.com/master.m3u8'); | 932 | player.src({src: 'http://example.com/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
977 | videojs.mediaSources[player.currentSrc()].trigger({ | 933 | player.hls.mediaSource.trigger({ |
978 | type: 'sourceopen' | 934 | type: 'sourceopen' |
979 | }); | 935 | }); |
980 | 936 | ||
... | @@ -1014,8 +970,8 @@ test('does not reload master playlists', function() { | ... | @@ -1014,8 +970,8 @@ test('does not reload master playlists', function() { |
1014 | callbacks.push(callback); | 970 | callbacks.push(callback); |
1015 | }; | 971 | }; |
1016 | 972 | ||
1017 | player.hls('http://example.com/master.m3u8'); | 973 | player.src({src: 'http://example.com/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
1018 | videojs.mediaSources[player.currentSrc()].trigger({ | 974 | player.hls.mediaSource.trigger({ |
1019 | type: 'sourceopen' | 975 | type: 'sourceopen' |
1020 | }); | 976 | }); |
1021 | 977 | ||
... | @@ -1023,20 +979,33 @@ test('does not reload master playlists', function() { | ... | @@ -1023,20 +979,33 @@ test('does not reload master playlists', function() { |
1023 | }); | 979 | }); |
1024 | 980 | ||
1025 | test('if withCredentials option is used, withCredentials is set on the XHR object', function() { | 981 | test('if withCredentials option is used, withCredentials is set on the XHR object', function() { |
1026 | player.hls({ | 982 | stop(); |
1027 | url: 'http://example.com/media.m3u8', | 983 | player.dispose(); |
1028 | withCredentials: true | 984 | var video = document.createElement('video'); |
1029 | }); | 985 | |
1030 | videojs.mediaSources[player.currentSrc()].trigger({ | 986 | document.querySelector('#qunit-fixture').appendChild(video); |
1031 | type: 'sourceopen' | 987 | player = videojs(video, { |
988 | flash: { | ||
989 | swf: '../node_modules/video.js/dist/video-js/video-js.swf' | ||
990 | }, | ||
991 | hls: { | ||
992 | withCredentials: true | ||
993 | }, | ||
994 | techOrder: ['hls'] | ||
995 | }, function() { | ||
996 | player.src({src: 'http://example.com/media.m3u8', type: 'application/vnd.apple.mpegurl'}); | ||
997 | player.hls.mediaSource.trigger({ | ||
998 | type: 'sourceopen' | ||
999 | }); | ||
1000 | ok(requests[0].withCredentials, "with credentials should be set to true if that option is passed in"); | ||
1001 | start(); | ||
1032 | }); | 1002 | }); |
1033 | ok(requests[0].withCredentials, "with credentials should be set to true if that option is passed in"); | ||
1034 | }); | 1003 | }); |
1035 | 1004 | ||
1036 | test('does not break if the playlist has no segments', function() { | 1005 | test('does not break if the playlist has no segments', function() { |
1037 | player.hls('manifest/master.m3u8'); | 1006 | player.src({src: 'manifest/master.m3u8', type: 'application/vnd.apple.mpegurl'}); |
1038 | try { | 1007 | try { |
1039 | videojs.mediaSources[player.currentSrc()].trigger({ | 1008 | player.hls.mediaSource.trigger({ |
1040 | type: 'sourceopen' | 1009 | type: 'sourceopen' |
1041 | }); | 1010 | }); |
1042 | requests[0].respond(200, null, | 1011 | requests[0].respond(200, null, | ... | ... |
-
Please register or sign in to post a comment