c694b4b7 by David LaPalomento

Merge pull request #544 from BrandonOCasey/browserify-p4

browserify-p4: playlist*, xhr, and resolve-url
2 parents e3c93f60 4c27b9d1
...@@ -48,10 +48,7 @@ ...@@ -48,10 +48,7 @@
48 <script src="/node_modules/video.js/dist/video.js"></script> 48 <script src="/node_modules/video.js/dist/video.js"></script>
49 <script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script> 49 <script src="/node_modules/videojs-contrib-media-sources/dist/videojs-media-sources.js"></script>
50 <script src="/src/videojs-contrib-hls.js"></script> 50 <script src="/src/videojs-contrib-hls.js"></script>
51 <script src="/src/xhr.js"></script>
52 <script src="/dist/videojs-contrib-hls.js"></script> 51 <script src="/dist/videojs-contrib-hls.js"></script>
53 <script src="/src/playlist.js"></script>
54 <script src="/src/playlist-loader.js"></script>
55 <script src="/src/bin-utils.js"></script> 52 <script src="/src/bin-utils.js"></script>
56 <script> 53 <script>
57 (function(window, videojs) { 54 (function(window, videojs) {
......
...@@ -2,7 +2,7 @@ var browserify = require('browserify'); ...@@ -2,7 +2,7 @@ var browserify = require('browserify');
2 var fs = require('fs'); 2 var fs = require('fs');
3 var glob = require('glob'); 3 var glob = require('glob');
4 4
5 glob('test/{decryper,m3u8,stub}.test.js', function(err, files) { 5 glob('test/{playlist*,decryper,m3u8,stub}.test.js', function(err, files) {
6 browserify(files) 6 browserify(files)
7 .transform('babelify') 7 .transform('babelify')
8 .bundle() 8 .bundle()
......
...@@ -3,7 +3,7 @@ var fs = require('fs'); ...@@ -3,7 +3,7 @@ var fs = require('fs');
3 var glob = require('glob'); 3 var glob = require('glob');
4 var watchify = require('watchify'); 4 var watchify = require('watchify');
5 5
6 glob('test/{decrypter,m3u8,stub}.test.js', function(err, files) { 6 glob('test/{playlist*,decrypter,m3u8,stub}.test.js', function(err, files) {
7 var b = browserify(files, { 7 var b = browserify(files, {
8 cache: {}, 8 cache: {},
9 packageCache: {}, 9 packageCache: {},
......
...@@ -5,14 +5,13 @@ ...@@ -5,14 +5,13 @@
5 * M3U8 playlists. 5 * M3U8 playlists.
6 * 6 *
7 */ 7 */
8 (function(window, videojs) { 8 import resolveUrl from './resolve-url';
9 'use strict'; 9 import XhrModule from './xhr';
10 var 10 import {mergeOptions} from 'video.js';
11 resolveUrl = videojs.Hls.resolveUrl, 11 import Stream from './stream';
12 xhr = videojs.Hls.xhr, 12 import m3u8 from './m3u8';
13 mergeOptions = videojs.mergeOptions,
14 13
15 /** 14 /**
16 * Returns a new master playlist that is the result of merging an 15 * Returns a new master playlist that is the result of merging an
17 * updated media playlist into the original version. If the 16 * updated media playlist into the original version. If the
18 * updated media playlist does not match any of the playlist 17 * updated media playlist does not match any of the playlist
...@@ -23,14 +22,12 @@ ...@@ -23,14 +22,12 @@
23 * master playlist with the updated media playlist merged in, or 22 * master playlist with the updated media playlist merged in, or
24 * null if the merge produced no change. 23 * null if the merge produced no change.
25 */ 24 */
26 updateMaster = function(master, media) { 25 const updateMaster = function(master, media) {
27 var 26 let changed = false;
28 changed = false, 27 let result = mergeOptions(master, {});
29 result = mergeOptions(master, {}), 28 let i = master.playlists.length;
30 i, 29 let playlist;
31 playlist; 30
32
33 i = master.playlists.length;
34 while (i--) { 31 while (i--) {
35 playlist = result.playlists[i]; 32 playlist = result.playlists[i];
36 if (playlist.uri === media.uri) { 33 if (playlist.uri === media.uri) {
...@@ -51,15 +48,16 @@ ...@@ -51,15 +48,16 @@
51 if (playlist.segments) { 48 if (playlist.segments) {
52 result.playlists[i].segments = updateSegments(playlist.segments, 49 result.playlists[i].segments = updateSegments(playlist.segments,
53 media.segments, 50 media.segments,
54 media.mediaSequence - playlist.mediaSequence); 51 media.mediaSequence -
52 playlist.mediaSequence);
55 } 53 }
56 changed = true; 54 changed = true;
57 } 55 }
58 } 56 }
59 return changed ? result : null; 57 return changed ? result : null;
60 }, 58 };
61 59
62 /** 60 /**
63 * Returns a new array of segments that is the result of merging 61 * Returns a new array of segments that is the result of merging
64 * properties from an older list of segments onto an updated 62 * properties from an older list of segments onto an updated
65 * list. No properties on the updated playlist will be overridden. 63 * list. No properties on the updated playlist will be overridden.
...@@ -73,8 +71,11 @@ ...@@ -73,8 +71,11 @@
73 * playlists. 71 * playlists.
74 * @return a list of merged segment objects 72 * @return a list of merged segment objects
75 */ 73 */
76 updateSegments = function(original, update, offset) { 74 const updateSegments = function(original, update, offset) {
77 var result = update.slice(), length, i; 75 let result = update.slice();
76 let length;
77 let i;
78
78 offset = offset || 0; 79 offset = offset || 0;
79 length = Math.min(original.length, update.length + offset); 80 length = Math.min(original.length, update.length + offset);
80 81
...@@ -82,18 +83,17 @@ ...@@ -82,18 +83,17 @@
82 result[i - offset] = mergeOptions(original[i], result[i - offset]); 83 result[i - offset] = mergeOptions(original[i], result[i - offset]);
83 } 84 }
84 return result; 85 return result;
85 }, 86 };
86 87
87 PlaylistLoader = function(srcUrl, withCredentials) { 88 export default class PlaylistLoader extends Stream {
88 var 89 constructor(srcUrl, withCredentials) {
89 loader = this, 90 super();
90 dispose, 91 let loader = this;
91 mediaUpdateTimeout, 92 let dispose;
92 request, 93 let mediaUpdateTimeout;
93 playlistRequestError, 94 let request;
94 haveMetadata; 95 let playlistRequestError;
95 96 let haveMetadata;
96 PlaylistLoader.prototype.init.call(this);
97 97
98 // a flag that disables "expired time"-tracking this setting has 98 // a flag that disables "expired time"-tracking this setting has
99 // no effect when not playing a live stream 99 // no effect when not playing a live stream
...@@ -127,7 +127,9 @@ ...@@ -127,7 +127,9 @@
127 // updated playlist. 127 // updated playlist.
128 128
129 haveMetadata = function(xhr, url) { 129 haveMetadata = function(xhr, url) {
130 var parser, refreshDelay, update; 130 let parser;
131 let refreshDelay;
132 let update;
131 133
132 loader.setBandwidth(request || xhr); 134 loader.setBandwidth(request || xhr);
133 135
...@@ -135,7 +137,7 @@ ...@@ -135,7 +137,7 @@
135 request = null; 137 request = null;
136 loader.state = 'HAVE_METADATA'; 138 loader.state = 'HAVE_METADATA';
137 139
138 parser = new videojs.m3u8.Parser(); 140 parser = new m3u8.Parser();
139 parser.push(xhr.responseText); 141 parser.push(xhr.responseText);
140 parser.end(); 142 parser.end();
141 parser.manifest.uri = url; 143 parser.manifest.uri = url;
...@@ -198,7 +200,8 @@ ...@@ -198,7 +200,8 @@
198 * object to switch to 200 * object to switch to
199 */ 201 */
200 loader.media = function(playlist) { 202 loader.media = function(playlist) {
201 var startingState = loader.state, mediaChange; 203 let startingState = loader.state;
204 let mediaChange;
202 // getter 205 // getter
203 if (!playlist) { 206 if (!playlist) {
204 return loader.media_; 207 return loader.media_;
...@@ -258,9 +261,9 @@ ...@@ -258,9 +261,9 @@
258 } 261 }
259 262
260 // request the new playlist 263 // request the new playlist
261 request = xhr({ 264 request = XhrModule({
262 uri: resolveUrl(loader.master.uri, playlist.uri), 265 uri: resolveUrl(loader.master.uri, playlist.uri),
263 withCredentials: withCredentials 266 withCredentials
264 }, function(error, request) { 267 }, function(error, request) {
265 if (error) { 268 if (error) {
266 return playlistRequestError(request, playlist.uri, startingState); 269 return playlistRequestError(request, playlist.uri, startingState);
...@@ -295,9 +298,9 @@ ...@@ -295,9 +298,9 @@
295 } 298 }
296 299
297 loader.state = 'HAVE_CURRENT_METADATA'; 300 loader.state = 'HAVE_CURRENT_METADATA';
298 request = xhr({ 301 request = XhrModule({
299 uri: resolveUrl(loader.master.uri, loader.media().uri), 302 uri: resolveUrl(loader.master.uri, loader.media().uri),
300 withCredentials: withCredentials 303 withCredentials
301 }, function(error, request) { 304 }, function(error, request) {
302 if (error) { 305 if (error) {
303 return playlistRequestError(request, loader.media().uri); 306 return playlistRequestError(request, loader.media().uri);
...@@ -307,11 +310,12 @@ ...@@ -307,11 +310,12 @@
307 }); 310 });
308 311
309 // request the specified URL 312 // request the specified URL
310 request = xhr({ 313 request = XhrModule({
311 uri: srcUrl, 314 uri: srcUrl,
312 withCredentials: withCredentials 315 withCredentials
313 }, function(error, req) { 316 }, function(error, req) {
314 var parser, i; 317 let parser;
318 let i;
315 319
316 // clear the loader's request reference 320 // clear the loader's request reference
317 request = null; 321 request = null;
...@@ -321,12 +325,13 @@ ...@@ -321,12 +325,13 @@
321 status: req.status, 325 status: req.status,
322 message: 'HLS playlist request error at URL: ' + srcUrl, 326 message: 'HLS playlist request error at URL: ' + srcUrl,
323 responseText: req.responseText, 327 responseText: req.responseText,
324 code: 2 // MEDIA_ERR_NETWORK 328 // MEDIA_ERR_NETWORK
329 code: 2
325 }; 330 };
326 return loader.trigger('error'); 331 return loader.trigger('error');
327 } 332 }
328 333
329 parser = new videojs.m3u8.Parser(); 334 parser = new m3u8.Parser();
330 parser.push(req.responseText); 335 parser.push(req.responseText);
331 parser.end(); 336 parser.end();
332 337
...@@ -365,16 +370,16 @@ ...@@ -365,16 +370,16 @@
365 haveMetadata(req, srcUrl); 370 haveMetadata(req, srcUrl);
366 return loader.trigger('loadedmetadata'); 371 return loader.trigger('loadedmetadata');
367 }); 372 });
368 }; 373 }
369 PlaylistLoader.prototype = new videojs.Hls.Stream();
370
371 /** 374 /**
372 * Update the PlaylistLoader state to reflect the changes in an 375 * Update the PlaylistLoader state to reflect the changes in an
373 * update to the current media playlist. 376 * update to the current media playlist.
374 * @param update {object} the updated media playlist object 377 * @param update {object} the updated media playlist object
375 */ 378 */
376 PlaylistLoader.prototype.updateMediaPlaylist_ = function(update) { 379 updateMediaPlaylist_(update) {
377 var outdated, i, segment; 380 let outdated;
381 let i;
382 let segment;
378 383
379 outdated = this.media_; 384 outdated = this.media_;
380 this.media_ = this.master.playlists[update.uri]; 385 this.media_ = this.master.playlists[update.uri];
...@@ -432,7 +437,7 @@ ...@@ -432,7 +437,7 @@
432 } 437 }
433 this.expired_ += segment.duration; 438 this.expired_ += segment.duration;
434 } 439 }
435 }; 440 }
436 441
437 /** 442 /**
438 * Determine the index of the segment that contains a specified 443 * Determine the index of the segment that contains a specified
...@@ -452,17 +457,16 @@ ...@@ -452,17 +457,16 @@
452 * value will be clamped to the index of the segment containing the 457 * value will be clamped to the index of the segment containing the
453 * closest playback position that is currently available. 458 * closest playback position that is currently available.
454 */ 459 */
455 PlaylistLoader.prototype.getMediaIndexForTime_ = function(time) { 460 getMediaIndexForTime_(time) {
456 var 461 let i;
457 i, 462 let segment;
458 segment, 463 let originalTime = time;
459 originalTime = time, 464 let numSegments = this.media_.segments.length;
460 numSegments = this.media_.segments.length, 465 let lastSegment = numSegments - 1;
461 lastSegment = numSegments - 1, 466 let startIndex;
462 startIndex, 467 let endIndex;
463 endIndex, 468 let knownStart;
464 knownStart, 469 let knownEnd;
465 knownEnd;
466 470
467 if (!this.media_) { 471 if (!this.media_) {
468 return 0; 472 return 0;
...@@ -558,7 +562,5 @@ ...@@ -558,7 +562,5 @@
558 // the one most likely to tell us something about the timeline 562 // the one most likely to tell us something about the timeline
559 return lastSegment; 563 return lastSegment;
560 } 564 }
561 }; 565 }
562 566 }
563 videojs.Hls.PlaylistLoader = PlaylistLoader;
564 })(window, window.videojs);
......
1 /** 1 /**
2 * Playlist related utilities. 2 * Playlist related utilities.
3 */ 3 */
4 (function(window, videojs) { 4 import {createTimeRange} from 'video.js';
5 'use strict';
6 5
7 var duration, intervalDuration, backwardDuration, forwardDuration, seekable; 6 const backwardDuration = function(playlist, endSequence) {
8 7 let result = 0;
9 backwardDuration = function(playlist, endSequence) { 8 let i = endSequence - playlist.mediaSequence;
10 var result = 0, segment, i;
11
12 i = endSequence - playlist.mediaSequence;
13 // if a start time is available for segment immediately following 9 // if a start time is available for segment immediately following
14 // the interval, use it 10 // the interval, use it
15 segment = playlist.segments[i]; 11 let segment = playlist.segments[i];
12
16 // Walk backward until we find the latest segment with timeline 13 // Walk backward until we find the latest segment with timeline
17 // information that is earlier than endSequence 14 // information that is earlier than endSequence
18 if (segment) { 15 if (segment) {
19 if (segment.start !== undefined) { 16 if (typeof segment.start !== 'undefined') {
20 return { result: segment.start, precise: true }; 17 return { result: segment.start, precise: true };
21 } 18 }
22 if (segment.end !== undefined) { 19 if (typeof segment.end !== 'undefined') {
23 return { 20 return {
24 result: segment.end - segment.duration, 21 result: segment.end - segment.duration,
25 precise: true 22 precise: true
...@@ -28,28 +25,29 @@ ...@@ -28,28 +25,29 @@
28 } 25 }
29 while (i--) { 26 while (i--) {
30 segment = playlist.segments[i]; 27 segment = playlist.segments[i];
31 if (segment.end !== undefined) { 28 if (typeof segment.end !== 'undefined') {
32 return { result: result + segment.end, precise: true }; 29 return { result: result + segment.end, precise: true };
33 } 30 }
34 31
35 result += segment.duration; 32 result += segment.duration;
36 33
37 if (segment.start !== undefined) { 34 if (typeof segment.start !== 'undefined') {
38 return { result: result + segment.start, precise: true }; 35 return { result: result + segment.start, precise: true };
39 } 36 }
40 } 37 }
41 return { result: result, precise: false }; 38 return { result, precise: false };
42 }; 39 };
43
44 forwardDuration = function(playlist, endSequence) {
45 var result = 0, segment, i;
46 40
47 i = endSequence - playlist.mediaSequence; 41 const forwardDuration = function(playlist, endSequence) {
42 let result = 0;
43 let segment;
44 let i = endSequence - playlist.mediaSequence;
48 // Walk forward until we find the earliest segment with timeline 45 // Walk forward until we find the earliest segment with timeline
49 // information 46 // information
47
50 for (; i < playlist.segments.length; i++) { 48 for (; i < playlist.segments.length; i++) {
51 segment = playlist.segments[i]; 49 segment = playlist.segments[i];
52 if (segment.start !== undefined) { 50 if (typeof segment.start !== 'undefined') {
53 return { 51 return {
54 result: segment.start - result, 52 result: segment.start - result,
55 precise: true 53 precise: true
...@@ -58,7 +56,7 @@ ...@@ -58,7 +56,7 @@
58 56
59 result += segment.duration; 57 result += segment.duration;
60 58
61 if (segment.end !== undefined) { 59 if (typeof segment.end !== 'undefined') {
62 return { 60 return {
63 result: segment.end - result, 61 result: segment.end - result,
64 precise: true 62 precise: true
...@@ -68,9 +66,9 @@ ...@@ -68,9 +66,9 @@
68 } 66 }
69 // indicate we didn't find a useful duration estimate 67 // indicate we didn't find a useful duration estimate
70 return { result: -1, precise: false }; 68 return { result: -1, precise: false };
71 }; 69 };
72 70
73 /** 71 /**
74 * Calculate the media duration from the segments associated with a 72 * Calculate the media duration from the segments associated with a
75 * playlist. The duration of a subinterval of the available segments 73 * playlist. The duration of a subinterval of the available segments
76 * may be calculated by specifying an end index. 74 * may be calculated by specifying an end index.
...@@ -81,10 +79,11 @@ ...@@ -81,10 +79,11 @@
81 * @return {number} the duration between the first available segment 79 * @return {number} the duration between the first available segment
82 * and end index. 80 * and end index.
83 */ 81 */
84 intervalDuration = function(playlist, endSequence) { 82 const intervalDuration = function(playlist, endSequence) {
85 var backward, forward; 83 let backward;
84 let forward;
86 85
87 if (endSequence === undefined) { 86 if (typeof endSequence === 'undefined') {
88 endSequence = playlist.mediaSequence + playlist.segments.length; 87 endSequence = playlist.mediaSequence + playlist.segments.length;
89 } 88 }
90 89
...@@ -112,9 +111,9 @@ ...@@ -112,9 +111,9 @@
112 111
113 // return the less-precise, playlist-based duration estimate 112 // return the less-precise, playlist-based duration estimate
114 return backward.result; 113 return backward.result;
115 }; 114 };
116 115
117 /** 116 /**
118 * Calculates the duration of a playlist. If a start and end index 117 * Calculates the duration of a playlist. If a start and end index
119 * are specified, the duration will be for the subset of the media 118 * are specified, the duration will be for the subset of the media
120 * timeline between those two indices. The total duration for live 119 * timeline between those two indices. The total duration for live
...@@ -129,18 +128,18 @@ ...@@ -129,18 +128,18 @@
129 * @return {number} the duration between the start index and end 128 * @return {number} the duration between the start index and end
130 * index. 129 * index.
131 */ 130 */
132 duration = function(playlist, endSequence, includeTrailingTime) { 131 export const duration = function(playlist, endSequence, includeTrailingTime) {
133 if (!playlist) { 132 if (!playlist) {
134 return 0; 133 return 0;
135 } 134 }
136 135
137 if (includeTrailingTime === undefined) { 136 if (typeof includeTrailingTime === 'undefined') {
138 includeTrailingTime = true; 137 includeTrailingTime = true;
139 } 138 }
140 139
141 // if a slice of the total duration is not requested, use 140 // if a slice of the total duration is not requested, use
142 // playlist-level duration indicators when they're present 141 // playlist-level duration indicators when they're present
143 if (endSequence === undefined) { 142 if (typeof endSequence === 'undefined') {
144 // if present, use the duration specified in the playlist 143 // if present, use the duration specified in the playlist
145 if (playlist.totalDuration) { 144 if (playlist.totalDuration) {
146 return playlist.totalDuration; 145 return playlist.totalDuration;
...@@ -156,9 +155,9 @@ ...@@ -156,9 +155,9 @@
156 return intervalDuration(playlist, 155 return intervalDuration(playlist,
157 endSequence, 156 endSequence,
158 includeTrailingTime); 157 includeTrailingTime);
159 }; 158 };
160 159
161 /** 160 /**
162 * Calculates the interval of time that is currently seekable in a 161 * Calculates the interval of time that is currently seekable in a
163 * playlist. The returned time ranges are relative to the earliest 162 * playlist. The returned time ranges are relative to the earliest
164 * moment in the specified playlist that is still available. A full 163 * moment in the specified playlist that is still available. A full
...@@ -169,16 +168,17 @@ ...@@ -169,16 +168,17 @@
169 * @return {TimeRanges} the periods of time that are valid targets 168 * @return {TimeRanges} the periods of time that are valid targets
170 * for seeking 169 * for seeking
171 */ 170 */
172 seekable = function(playlist) { 171 export const seekable = function(playlist) {
173 var start, end; 172 let start;
173 let end;
174 174
175 // without segments, there are no seekable ranges 175 // without segments, there are no seekable ranges
176 if (!playlist.segments) { 176 if (!playlist.segments) {
177 return videojs.createTimeRange(); 177 return createTimeRange();
178 } 178 }
179 // when the playlist is complete, the entire duration is seekable 179 // when the playlist is complete, the entire duration is seekable
180 if (playlist.endList) { 180 if (playlist.endList) {
181 return videojs.createTimeRange(0, duration(playlist)); 181 return createTimeRange(0, duration(playlist));
182 } 182 }
183 183
184 // live playlists should not expose three segment durations worth 184 // live playlists should not expose three segment durations worth
...@@ -186,13 +186,13 @@ ...@@ -186,13 +186,13 @@
186 // https://tools.ietf.org/html/draft-pantos-http-live-streaming-16#section-6.3.3 186 // https://tools.ietf.org/html/draft-pantos-http-live-streaming-16#section-6.3.3
187 start = intervalDuration(playlist, playlist.mediaSequence); 187 start = intervalDuration(playlist, playlist.mediaSequence);
188 end = intervalDuration(playlist, 188 end = intervalDuration(playlist,
189 playlist.mediaSequence + Math.max(0, playlist.segments.length - 3)); 189 playlist.mediaSequence +
190 return videojs.createTimeRange(start, end); 190 Math.max(0, playlist.segments.length - 3));
191 }; 191 return createTimeRange(start, end);
192 192 };
193 // exports 193
194 videojs.Hls.Playlist = { 194 // exports
195 duration: duration, 195 export default {
196 seekable: seekable 196 duration,
197 }; 197 seekable
198 })(window, window.videojs); 198 };
......
1 import document from 'global/document';
2 /* eslint-disable max-len */
3 /**
4 * Constructs a new URI by interpreting a path relative to another
5 * URI.
6 * @param basePath {string} a relative or absolute URI
7 * @param path {string} a path part to combine with the base
8 * @return {string} a URI that is equivalent to composing `base`
9 * with `path`
10 * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue
11 */
12 /* eslint-enable max-len */
13 const resolveUrl = function(basePath, path) {
14 // use the base element to get the browser to handle URI resolution
15 let oldBase = document.querySelector('base');
16 let docHead = document.querySelector('head');
17 let a = document.createElement('a');
18 let base = oldBase;
19 let oldHref;
20 let result;
21
22 // prep the document
23 if (oldBase) {
24 oldHref = oldBase.href;
25 } else {
26 base = docHead.appendChild(document.createElement('base'));
27 }
28
29 base.href = basePath;
30 a.href = path;
31 result = a.href;
32
33 // clean up
34 if (oldBase) {
35 oldBase.href = oldHref;
36 } else {
37 docHead.removeChild(base);
38 }
39 return result;
40 };
41
42 export default resolveUrl;
...@@ -2,6 +2,10 @@ import m3u8 from './m3u8'; ...@@ -2,6 +2,10 @@ import m3u8 from './m3u8';
2 import Stream from './stream'; 2 import Stream from './stream';
3 import videojs from 'video.js'; 3 import videojs from 'video.js';
4 import {Decrypter, decrypt, AsyncStream} from './decrypter'; 4 import {Decrypter, decrypt, AsyncStream} from './decrypter';
5 import Playlist from './playlist';
6 import PlaylistLoader from './playlist-loader';
7 import xhr from './xhr';
8
5 9
6 if(typeof window.videojs.Hls === 'undefined') { 10 if(typeof window.videojs.Hls === 'undefined') {
7 videojs.Hls = {}; 11 videojs.Hls = {};
...@@ -11,3 +15,6 @@ videojs.m3u8 = m3u8; ...@@ -11,3 +15,6 @@ videojs.m3u8 = m3u8;
11 videojs.Hls.decrypt = decrypt; 15 videojs.Hls.decrypt = decrypt;
12 videojs.Hls.Decrypter = Decrypter; 16 videojs.Hls.Decrypter = Decrypter;
13 videojs.Hls.AsyncStream = AsyncStream; 17 videojs.Hls.AsyncStream = AsyncStream;
18 videojs.Hls.xhr = xhr;
19 videojs.Hls.Playlist = Playlist;
20 videojs.Hls.PlaylistLoader = PlaylistLoader;
......
1 (function(videojs) { 1 /**
2 'use strict';
3
4 /**
5 * A wrapper for videojs.xhr that tracks bandwidth. 2 * A wrapper for videojs.xhr that tracks bandwidth.
6 */ 3 */
7 videojs.Hls.xhr = function(options, callback) { 4 import {xhr as videojsXHR, mergeOptions} from 'video.js';
5 const xhr = function(options, callback) {
8 // Add a default timeout for all hls requests 6 // Add a default timeout for all hls requests
9 options = videojs.mergeOptions({ 7 options = mergeOptions({
10 timeout: 45e3 8 timeout: 45e3
11 }, options); 9 }, options);
12 10
13 var request = videojs.xhr(options, function(error, response) { 11 let request = videojsXHR(options, function(error, response) {
14 if (!error && request.response) { 12 if (!error && request.response) {
15 request.responseTime = (new Date()).getTime(); 13 request.responseTime = (new Date()).getTime();
16 request.roundTripTime = request.responseTime - request.requestTime; 14 request.roundTripTime = request.responseTime - request.requestTime;
17 request.bytesReceived = request.response.byteLength || request.response.length; 15 request.bytesReceived = request.response.byteLength || request.response.length;
18 if (!request.bandwidth) { 16 if (!request.bandwidth) {
19 request.bandwidth = Math.floor((request.bytesReceived / request.roundTripTime) * 8 * 1000); 17 request.bandwidth =
18 Math.floor((request.bytesReceived / request.roundTripTime) * 8 * 1000);
20 } 19 }
21 } 20 }
22 21
23 // videojs.xhr now uses a specific code on the error object to signal that a request has 22 // videojs.xhr now uses a specific code
23 // on the error object to signal that a request has
24 // timed out errors of setting a boolean on the request object 24 // timed out errors of setting a boolean on the request object
25 if (error || request.timedout) { 25 if (error || request.timedout) {
26 request.timedout = request.timedout || (error.code === 'ETIMEDOUT'); 26 request.timedout = request.timedout || (error.code === 'ETIMEDOUT');
...@@ -44,5 +44,6 @@ ...@@ -44,5 +44,6 @@
44 44
45 request.requestTime = (new Date()).getTime(); 45 request.requestTime = (new Date()).getTime();
46 return request; 46 return request;
47 }; 47 };
48 })(window.videojs); 48
49 export default xhr;
......
...@@ -16,16 +16,11 @@ ...@@ -16,16 +16,11 @@
16 <script src="/node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script> 16 <script src="/node_modules/videojs-contrib-media-sources/src/videojs-media-sources.js"></script>
17 17
18 <script src="/src/videojs-contrib-hls.js"></script> 18 <script src="/src/videojs-contrib-hls.js"></script>
19 <script src="/src/xhr.js"></script>
20 <script src="/dist/videojs-contrib-hls.js"></script> 19 <script src="/dist/videojs-contrib-hls.js"></script>
21 <script src="/src/playlist.js"></script>
22 <script src="/src/playlist-loader.js"></script>
23 <script src="/src/bin-utils.js"></script> 20 <script src="/src/bin-utils.js"></script>
24 21
25 <script src="/test/videojs-contrib-hls.test.js"></script> 22 <script src="/test/videojs-contrib-hls.test.js"></script>
26 <script src="/dist-test/videojs-contrib-hls.js"></script> 23 <script src="/dist-test/videojs-contrib-hls.js"></script>
27 <script src="/test/playlist.test.js"></script>
28 <script src="/test/playlist-loader.test.js"></script>
29 24
30 </body> 25 </body>
31 </html> 26 </html>
......
...@@ -16,11 +16,8 @@ var DEFAULTS = { ...@@ -16,11 +16,8 @@ var DEFAULTS = {
16 16
17 // these two stub old functionality 17 // these two stub old functionality
18 'src/videojs-contrib-hls.js', 18 'src/videojs-contrib-hls.js',
19 'src/xhr.js',
20 'dist/videojs-contrib-hls.js', 19 'dist/videojs-contrib-hls.js',
21 20
22 'src/playlist.js',
23 'src/playlist-loader.js',
24 'src/bin-utils.js', 21 'src/bin-utils.js',
25 22
26 'test/stub.test.js', 23 'test/stub.test.js',
...@@ -45,7 +42,7 @@ var DEFAULTS = { ...@@ -45,7 +42,7 @@ var DEFAULTS = {
45 ], 42 ],
46 43
47 preprocessors: { 44 preprocessors: {
48 'test/{decrypter,stub,m3u8}.test.js': ['browserify'] 45 'test/{playlist*,decrypter,stub,m3u8}.test.js': ['browserify']
49 }, 46 },
50 47
51 reporters: ['dots'], 48 reporters: ['dots'],
......