Merge pull request #385 from dmlap/custom-codecs
Pass codecs along into source buffer creation
Showing
6 changed files
with
105 additions
and
46 deletions
1 | language: node_js | 1 | language: node_js |
2 | sudo: false | ||
2 | node_js: | 3 | node_js: |
3 | - '0.10' | 4 | - "stable" |
4 | install: | 5 | install: |
5 | - npm install -g grunt-cli && npm install | 6 | - npm install -g grunt-cli && npm install |
6 | notifications: | 7 | notifications: |
... | @@ -11,6 +12,9 @@ notifications: | ... | @@ -11,6 +12,9 @@ notifications: |
11 | channels: | 12 | channels: |
12 | - "chat.freenode.net#videojs" | 13 | - "chat.freenode.net#videojs" |
13 | use_notice: true | 14 | use_notice: true |
15 | before_script: | ||
16 | - export DISPLAY=:99.0 | ||
17 | - sh -e /etc/init.d/xvfb start | ||
14 | env: | 18 | env: |
15 | global: | 19 | global: |
16 | - secure: dM7svnHPPu5IiUMeFWW5zg+iuWNpwt6SSDi3MmVvhSclNMRLesQoRB+7Qq5J/LiKhmjpv1/GlNVV0CTsHMRhZNwQ3fo38eEuTXv99aAflEITXwSEh/VntKViHbGFubn06EnVkJoH6MX3zJ6kbiwc2QdSQbywKzS6l6quUEpWpd0= | 20 | - secure: dM7svnHPPu5IiUMeFWW5zg+iuWNpwt6SSDi3MmVvhSclNMRLesQoRB+7Qq5J/LiKhmjpv1/GlNVV0CTsHMRhZNwQ3fo38eEuTXv99aAflEITXwSEh/VntKViHbGFubn06EnVkJoH6MX3zJ6kbiwc2QdSQbywKzS6l6quUEpWpd0= | ... | ... |
... | @@ -357,7 +357,7 @@ module.exports = function(grunt) { | ... | @@ -357,7 +357,7 @@ module.exports = function(grunt) { |
357 | grunt.task.run(['karma:saucelabs']); | 357 | grunt.task.run(['karma:saucelabs']); |
358 | grunt.task.run(['connect:test', 'protractor:saucelabs']); | 358 | grunt.task.run(['connect:test', 'protractor:saucelabs']); |
359 | } else { | 359 | } else { |
360 | grunt.task.run(['karma:phantomjs']); | 360 | grunt.task.run(['karma:firefox']); |
361 | } | 361 | } |
362 | } else { | 362 | } else { |
363 | if (tasks.length === 0) { | 363 | if (tasks.length === 0) { | ... | ... |
... | @@ -11,8 +11,6 @@ | ... | @@ -11,8 +11,6 @@ |
11 | 11 | ||
12 | <!-- transmuxing --> | 12 | <!-- transmuxing --> |
13 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/stream.js"></script> | 13 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/stream.js"></script> |
14 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/mp4-generator.js"></script> | ||
15 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/lib/transmuxer.js"></script> | ||
16 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/flv-tag.js"></script> | 14 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/flv-tag.js"></script> |
17 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/exp-golomb.js"></script> | 15 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/exp-golomb.js"></script> |
18 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/h264-extradata.js"></script> | 16 | <script src="node_modules/videojs-contrib-media-sources/node_modules/mux.js/legacy/h264-extradata.js"></script> |
... | @@ -23,6 +21,9 @@ | ... | @@ -23,6 +21,9 @@ |
23 | 21 | ||
24 | <!-- Media Sources plugin --> | 22 | <!-- Media Sources plugin --> |
25 | <script src="node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> | 23 | <script src="node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> |
24 | <script> | ||
25 | videojs.MediaSource.webWorkerURI = 'node_modules/videojs-contrib-media-sources/src/transmuxer_worker.js'; | ||
26 | </script> | ||
26 | 27 | ||
27 | <!-- HLS plugin --> | 28 | <!-- HLS plugin --> |
28 | <script src="src/videojs-hls.js"></script> | 29 | <script src="src/videojs-hls.js"></script> |
... | @@ -39,12 +40,6 @@ | ... | @@ -39,12 +40,6 @@ |
39 | 40 | ||
40 | <script src="src/bin-utils.js"></script> | 41 | <script src="src/bin-utils.js"></script> |
41 | 42 | ||
42 | <!-- example MPEG2-TS segments --> | ||
43 | <!-- bipbop --> | ||
44 | <!-- <script src="test/tsSegment.js"></script> --> | ||
45 | <!-- bunnies --> | ||
46 | <!--<script src="test/tsSegment-bc.js"></script>--> | ||
47 | |||
48 | <style> | 43 | <style> |
49 | body { | 44 | body { |
50 | font-family: Arial, sans-serif; | 45 | font-family: Arial, sans-serif; | ... | ... |
... | @@ -10,10 +10,10 @@ var | ... | @@ -10,10 +10,10 @@ var |
10 | // a fudge factor to apply to advertised playlist bitrates to account for | 10 | // a fudge factor to apply to advertised playlist bitrates to account for |
11 | // temporary flucations in client bandwidth | 11 | // temporary flucations in client bandwidth |
12 | bandwidthVariance = 1.1, | 12 | bandwidthVariance = 1.1, |
13 | Component = videojs.getComponent('Component'), | ||
13 | 14 | ||
14 | // the amount of time to wait between checking the state of the buffer | 15 | // the amount of time to wait between checking the state of the buffer |
15 | bufferCheckInterval = 500, | 16 | bufferCheckInterval = 500, |
16 | Component = videojs.getComponent('Component'), | ||
17 | 17 | ||
18 | keyXhr, | 18 | keyXhr, |
19 | keyFailed, | 19 | keyFailed, |
... | @@ -133,7 +133,7 @@ videojs.Hls.prototype.src = function(src) { | ... | @@ -133,7 +133,7 @@ videojs.Hls.prototype.src = function(src) { |
133 | 133 | ||
134 | // We need to trigger this asynchronously to give others the chance | 134 | // We need to trigger this asynchronously to give others the chance |
135 | // to bind to the event when a source is set at player creation | 135 | // to bind to the event when a source is set at player creation |
136 | setTimeout(function() { | 136 | this.setTimeout(function() { |
137 | this.tech_.trigger('loadstart'); | 137 | this.tech_.trigger('loadstart'); |
138 | }.bind(this), 1); | 138 | }.bind(this), 1); |
139 | 139 | ||
... | @@ -180,6 +180,8 @@ videojs.Hls.prototype.src = function(src) { | ... | @@ -180,6 +180,8 @@ videojs.Hls.prototype.src = function(src) { |
180 | }); | 180 | }); |
181 | } | 181 | } |
182 | 182 | ||
183 | this.setupSourceBuffer_(); | ||
184 | |||
183 | selectedPlaylist = this.selectPlaylist(); | 185 | selectedPlaylist = this.selectPlaylist(); |
184 | oldBitrate = oldMediaPlaylist.attributes && | 186 | oldBitrate = oldMediaPlaylist.attributes && |
185 | oldMediaPlaylist.attributes.BANDWIDTH || 0; | 187 | oldMediaPlaylist.attributes.BANDWIDTH || 0; |
... | @@ -281,16 +283,7 @@ videojs.Hls.getMediaIndexForLive_ = function(selectedPlaylist) { | ... | @@ -281,16 +283,7 @@ videojs.Hls.getMediaIndexForLive_ = function(selectedPlaylist) { |
281 | }; | 283 | }; |
282 | 284 | ||
283 | videojs.Hls.prototype.handleSourceOpen = function() { | 285 | videojs.Hls.prototype.handleSourceOpen = function() { |
284 | this.sourceBuffer = this.mediaSource.addSourceBuffer('video/mp2t'); | 286 | this.setupSourceBuffer_(); |
285 | |||
286 | // transition the sourcebuffer to the ended state if we've hit the end of | ||
287 | // the playlist | ||
288 | this.sourceBuffer.addEventListener('updateend', function() { | ||
289 | if (this.duration() !== Infinity && | ||
290 | this.mediaIndex === this.playlists.media().segments.length) { | ||
291 | this.mediaSource.endOfStream(); | ||
292 | } | ||
293 | }.bind(this)); | ||
294 | 287 | ||
295 | // if autoplay is enabled, begin playback. This is duplicative of | 288 | // if autoplay is enabled, begin playback. This is duplicative of |
296 | // code in video.js but is required because play() must be invoked | 289 | // code in video.js but is required because play() must be invoked |
... | @@ -303,6 +296,31 @@ videojs.Hls.prototype.handleSourceOpen = function() { | ... | @@ -303,6 +296,31 @@ videojs.Hls.prototype.handleSourceOpen = function() { |
303 | } | 296 | } |
304 | }; | 297 | }; |
305 | 298 | ||
299 | videojs.Hls.prototype.setupSourceBuffer_ = function() { | ||
300 | var media = this.playlists.media(), mimeType; | ||
301 | |||
302 | // wait until a media playlist is available and the Media Source is | ||
303 | // attached | ||
304 | if (!media || this.mediaSource.readyState !== 'open') { | ||
305 | return; | ||
306 | } | ||
307 | |||
308 | mimeType = 'video/mp2t'; | ||
309 | if (media.attributes && media.attributes.CODECS) { | ||
310 | mimeType += '; codecs="' + media.attributes.CODECS + '"'; | ||
311 | } | ||
312 | this.sourceBuffer = this.mediaSource.addSourceBuffer(mimeType); | ||
313 | |||
314 | // transition the sourcebuffer to the ended state if we've hit the end of | ||
315 | // the playlist | ||
316 | this.sourceBuffer.addEventListener('updateend', function() { | ||
317 | if (this.duration() !== Infinity && | ||
318 | this.mediaIndex === this.playlists.media().segments.length) { | ||
319 | this.mediaSource.endOfStream(); | ||
320 | } | ||
321 | }.bind(this)); | ||
322 | }; | ||
323 | |||
306 | // register event listeners to transform in-band metadata events into | 324 | // register event listeners to transform in-band metadata events into |
307 | // VTTCues on a text track | 325 | // VTTCues on a text track |
308 | videojs.Hls.prototype.setupMetadataCueTranslation_ = function() { | 326 | videojs.Hls.prototype.setupMetadataCueTranslation_ = function() { |
... | @@ -310,12 +328,6 @@ videojs.Hls.prototype.setupMetadataCueTranslation_ = function() { | ... | @@ -310,12 +328,6 @@ videojs.Hls.prototype.setupMetadataCueTranslation_ = function() { |
310 | metadataStream = this.segmentParser_.metadataStream, | 328 | metadataStream = this.segmentParser_.metadataStream, |
311 | textTrack; | 329 | textTrack; |
312 | 330 | ||
313 | // only expose metadata tracks to video.js versions that support | ||
314 | // dynamic text tracks (4.12+) | ||
315 | if (!this.tech_.addTextTrack) { | ||
316 | return; | ||
317 | } | ||
318 | |||
319 | // add a metadata cue whenever a metadata event is triggered during | 331 | // add a metadata cue whenever a metadata event is triggered during |
320 | // segment parsing | 332 | // segment parsing |
321 | metadataStream.on('data', function(metadata) { | 333 | metadataStream.on('data', function(metadata) { |
... | @@ -585,6 +597,7 @@ videojs.Hls.prototype.dispose = function() { | ... | @@ -585,6 +597,7 @@ videojs.Hls.prototype.dispose = function() { |
585 | } | 597 | } |
586 | 598 | ||
587 | this.resetSrc_(); | 599 | this.resetSrc_(); |
600 | Component.prototype.dispose.call(this); | ||
588 | }; | 601 | }; |
589 | 602 | ||
590 | /** | 603 | /** | ... | ... |
... | @@ -480,6 +480,16 @@ | ... | @@ -480,6 +480,16 @@ |
480 | strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf'); | 480 | strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf'); |
481 | strictEqual(element.attributes.RESOLUTION.width, 396, 'width is parsed'); | 481 | strictEqual(element.attributes.RESOLUTION.width, 396, 'width is parsed'); |
482 | strictEqual(element.attributes.RESOLUTION.height, 224, 'heigth is parsed'); | 482 | strictEqual(element.attributes.RESOLUTION.height, 224, 'heigth is parsed'); |
483 | |||
484 | manifest = '#EXT-X-STREAM-INF:CODECS="avc1.4d400d, mp4a.40.2"\n'; | ||
485 | lineStream.push(manifest); | ||
486 | |||
487 | ok(element, 'an event was triggered'); | ||
488 | strictEqual(element.type, 'tag', 'the line type is tag'); | ||
489 | strictEqual(element.tagType, 'stream-inf', 'the tag type is stream-inf'); | ||
490 | strictEqual(element.attributes.CODECS, | ||
491 | 'avc1.4d400d, mp4a.40.2', | ||
492 | 'codecs are parsed'); | ||
483 | }); | 493 | }); |
484 | test('parses #EXT-X-STREAM-INF with arbitrary attributes', function() { | 494 | test('parses #EXT-X-STREAM-INF with arbitrary attributes', function() { |
485 | var | 495 | var | ... | ... |
... | @@ -212,7 +212,8 @@ var | ... | @@ -212,7 +212,8 @@ var |
212 | 212 | ||
213 | // return an absolute version of a page-relative URL | 213 | // return an absolute version of a page-relative URL |
214 | absoluteUrl = function(relativeUrl) { | 214 | absoluteUrl = function(relativeUrl) { |
215 | return window.location.origin + | 215 | return window.location.protocol + '//' + |
216 | window.location.host + | ||
216 | (window.location.pathname | 217 | (window.location.pathname |
217 | .split('/') | 218 | .split('/') |
218 | .slice(0, -1) | 219 | .slice(0, -1) |
... | @@ -239,6 +240,9 @@ module('HLS', { | ... | @@ -239,6 +240,9 @@ module('HLS', { |
239 | el.className = 'vjs-tech vjs-mock-flash'; | 240 | el.className = 'vjs-tech vjs-mock-flash'; |
240 | el.vjs_load = function() {}; | 241 | el.vjs_load = function() {}; |
241 | el.vjs_getProperty = function(attr) { | 242 | el.vjs_getProperty = function(attr) { |
243 | if (attr === 'buffered') { | ||
244 | return [[0,0]]; | ||
245 | } | ||
242 | return el[attr]; | 246 | return el[attr]; |
243 | }; | 247 | }; |
244 | el.vjs_setProperty = function(attr, value) { | 248 | el.vjs_setProperty = function(attr, value) { |
... | @@ -383,6 +387,26 @@ test('duration is set when the source opens after the playlist is loaded', funct | ... | @@ -383,6 +387,26 @@ test('duration is set when the source opens after the playlist is loaded', funct |
383 | equal(player.tech.hls.mediaSource.duration , 40, 'set the duration'); | 387 | equal(player.tech.hls.mediaSource.duration , 40, 'set the duration'); |
384 | }); | 388 | }); |
385 | 389 | ||
390 | test('codecs are passed to the source buffer', function() { | ||
391 | var codecs = []; | ||
392 | player.src({ | ||
393 | src: 'custom-codecs.m3u8', | ||
394 | type: 'application/vnd.apple.mpegurl' | ||
395 | }); | ||
396 | openMediaSource(player); | ||
397 | player.tech.hls.mediaSource.addSourceBuffer = function(codec) { | ||
398 | codecs.push(codec); | ||
399 | }; | ||
400 | |||
401 | requests.shift().respond(200, null, | ||
402 | '#EXTM3U\n' + | ||
403 | '#EXT-X-STREAM-INF:CODECS="video, audio"\n' + | ||
404 | 'media.m3u8\n'); | ||
405 | standardXHRResponse(requests.shift()); | ||
406 | equal(codecs.length, 1, 'created a source buffer'); | ||
407 | equal(codecs[0], 'video/mp2t; codecs="video, audio"', 'specified the codecs'); | ||
408 | }); | ||
409 | |||
386 | test('including HLS as a tech does not error', function() { | 410 | test('including HLS as a tech does not error', function() { |
387 | var player = createPlayer({ | 411 | var player = createPlayer({ |
388 | techOrder: ['hls', 'html5'] | 412 | techOrder: ['hls', 'html5'] |
... | @@ -450,14 +474,14 @@ test('re-initializes the playlist loader when switching sources', function() { | ... | @@ -450,14 +474,14 @@ test('re-initializes the playlist loader when switching sources', function() { |
450 | 474 | ||
451 | test('sets the duration if one is available on the playlist', function() { | 475 | test('sets the duration if one is available on the playlist', function() { |
452 | var events = 0; | 476 | var events = 0; |
453 | player.on('durationchange', function() { | ||
454 | events++; | ||
455 | }); | ||
456 | player.src({ | 477 | player.src({ |
457 | src: 'manifest/media.m3u8', | 478 | src: 'manifest/media.m3u8', |
458 | type: 'application/vnd.apple.mpegurl' | 479 | type: 'application/vnd.apple.mpegurl' |
459 | }); | 480 | }); |
460 | openMediaSource(player); | 481 | openMediaSource(player); |
482 | player.tech.on('durationchange', function() { | ||
483 | events++; | ||
484 | }); | ||
461 | 485 | ||
462 | standardXHRResponse(requests[0]); | 486 | standardXHRResponse(requests[0]); |
463 | equal(player.tech.hls.mediaSource.duration, 40, 'set the duration'); | 487 | equal(player.tech.hls.mediaSource.duration, 40, 'set the duration'); |
... | @@ -549,7 +573,8 @@ test('recognizes domain-relative URLs', function() { | ... | @@ -549,7 +573,8 @@ test('recognizes domain-relative URLs', function() { |
549 | standardXHRResponse(requests[0]); | 573 | standardXHRResponse(requests[0]); |
550 | standardXHRResponse(requests[1]); | 574 | standardXHRResponse(requests[1]); |
551 | strictEqual(requests[1].url, | 575 | strictEqual(requests[1].url, |
552 | window.location.origin + '/00001.ts', | 576 | window.location.protocol + '//' + window.location.host + |
577 | '/00001.ts', | ||
553 | 'the first segment is requested'); | 578 | 'the first segment is requested'); |
554 | }); | 579 | }); |
555 | 580 | ||
... | @@ -565,11 +590,11 @@ test('re-initializes the handler for each source', function() { | ... | @@ -565,11 +590,11 @@ test('re-initializes the handler for each source', function() { |
565 | openMediaSource(player); | 590 | openMediaSource(player); |
566 | firstPlaylists = player.tech.hls.playlists; | 591 | firstPlaylists = player.tech.hls.playlists; |
567 | firstMSE = player.tech.hls.mediaSource; | 592 | firstMSE = player.tech.hls.mediaSource; |
593 | standardXHRResponse(requests.shift()); | ||
594 | standardXHRResponse(requests.shift()); | ||
568 | player.tech.hls.sourceBuffer.abort = function() { | 595 | player.tech.hls.sourceBuffer.abort = function() { |
569 | aborts++; | 596 | aborts++; |
570 | }; | 597 | }; |
571 | standardXHRResponse(requests.shift()); | ||
572 | standardXHRResponse(requests.shift()); | ||
573 | 598 | ||
574 | player.src({ | 599 | player.src({ |
575 | src: 'manifest/master.m3u8', | 600 | src: 'manifest/master.m3u8', |
... | @@ -1329,9 +1354,11 @@ test('when outstanding XHRs are cancelled, they get aborted properly', function( | ... | @@ -1329,9 +1354,11 @@ test('when outstanding XHRs are cancelled, they get aborted properly', function( |
1329 | test('segmentXhr is properly nulled out when dispose is called', function() { | 1354 | test('segmentXhr is properly nulled out when dispose is called', function() { |
1330 | var | 1355 | var |
1331 | readystatechanges = 0, | 1356 | readystatechanges = 0, |
1332 | oldDispose = Flash.prototype.dispose; | 1357 | oldDispose = Flash.prototype.dispose, |
1358 | player; | ||
1333 | Flash.prototype.dispose = function() {}; | 1359 | Flash.prototype.dispose = function() {}; |
1334 | 1360 | ||
1361 | player = createPlayer(); | ||
1335 | player.src({ | 1362 | player.src({ |
1336 | src: 'manifest/media.m3u8', | 1363 | src: 'manifest/media.m3u8', |
1337 | type: 'application/vnd.apple.mpegurl' | 1364 | type: 'application/vnd.apple.mpegurl' |
... | @@ -2108,7 +2135,7 @@ test('does not break if the playlist has no segments', function() { | ... | @@ -2108,7 +2135,7 @@ test('does not break if the playlist has no segments', function() { |
2108 | }); | 2135 | }); |
2109 | 2136 | ||
2110 | test('clears the segment buffer on seek', function() { | 2137 | test('clears the segment buffer on seek', function() { |
2111 | var currentTime, bufferEnd, oldCurrentTime; | 2138 | var currentTime, oldCurrentTime; |
2112 | 2139 | ||
2113 | player.src({ | 2140 | player.src({ |
2114 | src: 'discontinuity.m3u8', | 2141 | src: 'discontinuity.m3u8', |
... | @@ -2122,8 +2149,8 @@ test('clears the segment buffer on seek', function() { | ... | @@ -2122,8 +2149,8 @@ test('clears the segment buffer on seek', function() { |
2122 | } | 2149 | } |
2123 | return currentTime; | 2150 | return currentTime; |
2124 | }; | 2151 | }; |
2125 | player.buffered = function() { | 2152 | player.tech.buffered = function() { |
2126 | return videojs.createTimeRange(0, bufferEnd); | 2153 | return videojs.createTimeRange(); |
2127 | }; | 2154 | }; |
2128 | 2155 | ||
2129 | requests.pop().respond(200, null, | 2156 | requests.pop().respond(200, null, |
... | @@ -2139,7 +2166,6 @@ test('clears the segment buffer on seek', function() { | ... | @@ -2139,7 +2166,6 @@ test('clears the segment buffer on seek', function() { |
2139 | 2166 | ||
2140 | // play to 6s to trigger the next segment request | 2167 | // play to 6s to trigger the next segment request |
2141 | currentTime = 6; | 2168 | currentTime = 6; |
2142 | bufferEnd = 10; | ||
2143 | clock.tick(6000); | 2169 | clock.tick(6000); |
2144 | 2170 | ||
2145 | standardXHRResponse(requests.pop()); // 2.ts | 2171 | standardXHRResponse(requests.pop()); // 2.ts |
... | @@ -2346,6 +2372,17 @@ test('aborts the source buffer on disposal', function() { | ... | @@ -2346,6 +2372,17 @@ test('aborts the source buffer on disposal', function() { |
2346 | type: 'application/vnd.apple.mpegurl' | 2372 | type: 'application/vnd.apple.mpegurl' |
2347 | }); | 2373 | }); |
2348 | openMediaSource(player); | 2374 | openMediaSource(player); |
2375 | player.dispose(); | ||
2376 | ok(true, 'disposed before creating the source buffer'); | ||
2377 | requests.length = 0; | ||
2378 | |||
2379 | player = createPlayer(); | ||
2380 | player.src({ | ||
2381 | src: 'manifest/media.m3u8', | ||
2382 | type: 'application/vnd.apple.mpegurl' | ||
2383 | }); | ||
2384 | openMediaSource(player); | ||
2385 | standardXHRResponse(requests.shift()); | ||
2349 | player.tech.hls.sourceBuffer.abort = function() { | 2386 | player.tech.hls.sourceBuffer.abort = function() { |
2350 | aborts++; | 2387 | aborts++; |
2351 | }; | 2388 | }; |
... | @@ -2708,9 +2745,6 @@ test('skip segments if key requests fail more than once', function() { | ... | @@ -2708,9 +2745,6 @@ test('skip segments if key requests fail more than once', function() { |
2708 | type: 'application/vnd.apple.mpegurl' | 2745 | type: 'application/vnd.apple.mpegurl' |
2709 | }); | 2746 | }); |
2710 | openMediaSource(player); | 2747 | openMediaSource(player); |
2711 | player.tech.hls.sourceBuffer.appendBuffer = function(chunk) { | ||
2712 | bytes.push(chunk); | ||
2713 | }; | ||
2714 | player.tech.trigger('play'); | 2748 | player.tech.trigger('play'); |
2715 | 2749 | ||
2716 | requests.shift().respond(200, null, | 2750 | requests.shift().respond(200, null, |
... | @@ -2721,6 +2755,9 @@ test('skip segments if key requests fail more than once', function() { | ... | @@ -2721,6 +2755,9 @@ test('skip segments if key requests fail more than once', function() { |
2721 | '#EXT-X-KEY:METHOD=AES-128,URI="htts://priv.example.com/key.php?r=53"\n' + | 2755 | '#EXT-X-KEY:METHOD=AES-128,URI="htts://priv.example.com/key.php?r=53"\n' + |
2722 | '#EXTINF:15.0,\n' + | 2756 | '#EXTINF:15.0,\n' + |
2723 | 'http://media.example.com/fileSequence53-A.ts\n'); | 2757 | 'http://media.example.com/fileSequence53-A.ts\n'); |
2758 | player.tech.hls.sourceBuffer.appendBuffer = function(chunk) { | ||
2759 | bytes.push(chunk); | ||
2760 | }; | ||
2724 | standardXHRResponse(requests.shift()); // segment 1 | 2761 | standardXHRResponse(requests.shift()); // segment 1 |
2725 | requests.shift().respond(404); // fail key | 2762 | requests.shift().respond(404); // fail key |
2726 | requests.shift().respond(404); // fail key, again | 2763 | requests.shift().respond(404); // fail key, again |
... | @@ -2878,9 +2915,6 @@ test('treats invalid keys as a key request failure', function() { | ... | @@ -2878,9 +2915,6 @@ test('treats invalid keys as a key request failure', function() { |
2878 | type: 'application/vnd.apple.mpegurl' | 2915 | type: 'application/vnd.apple.mpegurl' |
2879 | }); | 2916 | }); |
2880 | openMediaSource(player); | 2917 | openMediaSource(player); |
2881 | player.tech.hls.sourceBuffer.appendBuffer = function(chunk) { | ||
2882 | bytes.push(chunk); | ||
2883 | }; | ||
2884 | player.tech.trigger('play'); | 2918 | player.tech.trigger('play'); |
2885 | requests.shift().respond(200, null, | 2919 | requests.shift().respond(200, null, |
2886 | '#EXTM3U\n' + | 2920 | '#EXTM3U\n' + |
... | @@ -2891,6 +2925,9 @@ test('treats invalid keys as a key request failure', function() { | ... | @@ -2891,6 +2925,9 @@ test('treats invalid keys as a key request failure', function() { |
2891 | '#EXT-X-KEY:METHOD=NONE\n' + | 2925 | '#EXT-X-KEY:METHOD=NONE\n' + |
2892 | '#EXTINF:15.0,\n' + | 2926 | '#EXTINF:15.0,\n' + |
2893 | 'http://media.example.com/fileSequence52-B.ts\n'); | 2927 | 'http://media.example.com/fileSequence52-B.ts\n'); |
2928 | player.tech.hls.sourceBuffer.appendBuffer = function(chunk) { | ||
2929 | bytes.push(chunk); | ||
2930 | }; | ||
2894 | // segment request | 2931 | // segment request |
2895 | standardXHRResponse(requests.shift()); | 2932 | standardXHRResponse(requests.shift()); |
2896 | // keys should be 16 bytes long | 2933 | // keys should be 16 bytes long | ... | ... |
-
Please register or sign in to post a comment