diff --git a/lib/hls/hls_classes.js b/lib/hls/hls_classes.js index 683e8163ca..d6f5d3d5dd 100644 --- a/lib/hls/hls_classes.js +++ b/lib/hls/hls_classes.js @@ -11,6 +11,7 @@ goog.provide('shaka.hls.Segment'); goog.provide('shaka.hls.Tag'); goog.require('goog.asserts'); +goog.require('shaka.hls.Utils'); goog.require('shaka.util.Error'); @@ -202,24 +203,48 @@ shaka.hls.Segment = class { /** * Creates an HLS segment object. * - * @param {string} absoluteUri An absolute URI. + * @param {string} absoluteMediaPlaylistUri An absolute Media Playlist URI. + * @param {string} verbatimSegmentUri verbatim segment URI. * @param {!Array.} tags * @param {!Array.=} partialSegments */ - constructor(absoluteUri, tags, partialSegments=[]) { + constructor(absoluteMediaPlaylistUri, verbatimSegmentUri, tags, + partialSegments=[]) { /** @const {!Array.} */ this.tags = tags; - /** - * An absolute URI. - * - * @const {string} - */ - this.absoluteUri = absoluteUri; + /** @type {?string} */ + this.absoluteUri_ = null; + + /** @type {?string} */ + this.absoluteMediaPlaylistUri_ = absoluteMediaPlaylistUri; + + /** @type {?string} */ + this.verbatimSegmentUri_ = verbatimSegmentUri; /** @type {!Array.} */ this.partialSegments = partialSegments; } + + /** + * Returns an absolute URI. + * + * @return {string} + */ + get absoluteUri() { + if (!this.absoluteUri_ && + this.absoluteMediaPlaylistUri_ && this.verbatimSegmentUri_) { + goog.asserts.assert(this.absoluteMediaPlaylistUri_, + 'An absolute Media Playlist URI should be defined!'); + goog.asserts.assert(this.verbatimSegmentUri_, + 'An verbatim segment URI should be defined!'); + this.absoluteUri_ = shaka.hls.Utils.constructAbsoluteUri( + this.absoluteMediaPlaylistUri_, this.verbatimSegmentUri_); + this.absoluteMediaPlaylistUri_ = null; + this.verbatimSegmentUri_ = null; + } + return this.absoluteUri_ || ''; + } }; diff --git a/lib/hls/manifest_text_parser.js b/lib/hls/manifest_text_parser.js index 15c487716b..b37cc99949 100644 --- a/lib/hls/manifest_text_parser.js +++ b/lib/hls/manifest_text_parser.js @@ -172,15 +172,13 @@ shaka.hls.ManifestTextParser = class { // Skip comments. } else { const verbatimSegmentUri = line.trim(); - const absoluteSegmentUri = shaka.hls.Utils.constructAbsoluteUri( - absoluteMediaPlaylistUri, verbatimSegmentUri); // Attach the last parsed EXT-X-MAP tag to the segment. if (currentMapTag) { segmentTags.push(currentMapTag); } // The URI appears after all of the tags describing the segment. - const segment = new shaka.hls.Segment(absoluteSegmentUri, segmentTags, - partialSegmentTags); + const segment = new shaka.hls.Segment(absoluteMediaPlaylistUri, + verbatimSegmentUri, segmentTags, partialSegmentTags); segments.push(segment); segmentTags = []; partialSegmentTags = []; @@ -195,7 +193,7 @@ shaka.hls.ManifestTextParser = class { if (currentMapTag) { segmentTags.push(currentMapTag); } - const segment = new shaka.hls.Segment('', segmentTags, + const segment = new shaka.hls.Segment('', '', segmentTags, partialSegmentTags); segments.push(segment); } diff --git a/lib/util/manifest_parser_utils.js b/lib/util/manifest_parser_utils.js index 33c9b31775..e23e7768d7 100644 --- a/lib/util/manifest_parser_utils.js +++ b/lib/util/manifest_parser_utils.js @@ -19,6 +19,9 @@ shaka.util.ManifestParserUtils = class { * Resolves an array of relative URIs to the given base URIs. This will result * in M*N number of URIs. * + * Note: This method is slow in SmartTVs and Consoles. It should only be + * called when necessary. + * * @param {!Array.} baseUris * @param {!Array.} relativeUris * @return {!Array.} diff --git a/test/hls/manifest_text_parser_unit.js b/test/hls/manifest_text_parser_unit.js index c653d5e651..248ea2ad48 100644 --- a/test/hls/manifest_text_parser_unit.js +++ b/test/hls/manifest_text_parser_unit.js @@ -307,7 +307,7 @@ describe('ManifestTextParser', () => { new shaka.hls.Tag(/* id= */ 0, 'EXT-X-MEDIA-SEQUENCE', [], '1'), ], segments: [ - new shaka.hls.Segment('https://test/test.mp4', + new shaka.hls.Segment('https://test/manifest.m3u8', 'https://test/test.mp4', [ new shaka.hls.Tag(/* id= */ 2, 'EXTINF', [], '5.99467'), ]), @@ -332,7 +332,7 @@ describe('ManifestTextParser', () => { new shaka.hls.Tag(/* id= */ 0, 'EXT-X-MEDIA-SEQUENCE', [], '1'), ], segments: [ - new shaka.hls.Segment('https://test/test.mp4', [ + new shaka.hls.Segment('https://test/manifest.m3u8', 'https://test/test.mp4', [ new shaka.hls.Tag( /* id= */ 2, 'EXTINF', @@ -360,7 +360,7 @@ describe('ManifestTextParser', () => { new shaka.hls.Tag(/* id= */ 2, 'EXT-X-TARGETDURATION', [], '6'), ], segments: [ - new shaka.hls.Segment('https://test/test.mp4', + new shaka.hls.Segment('https://test/manifest.m3u8', 'https://test/test.mp4', [ new shaka.hls.Tag(/* id= */ 1, 'EXT-X-KEY', [ @@ -393,7 +393,7 @@ describe('ManifestTextParser', () => { new shaka.hls.Tag(/* id= */ 0, 'EXT-X-MEDIA-SEQUENCE', [], '1'), ], segments: [ - new shaka.hls.Segment('https://test/test.mp4', + new shaka.hls.Segment('https://test/manifest.m3u8', 'test.mp4', [ new shaka.hls.Tag(/* id= */ 2, 'EXTINF', [], '5.99467'), ]), @@ -427,9 +427,9 @@ describe('ManifestTextParser', () => { new shaka.hls.Tag(/* id= */ 0, 'EXT-X-TARGETDURATION', [], '6'), ], segments: [ - new shaka.hls.Segment('https://test/uri', + new shaka.hls.Segment('https://test/manifest.m3u8', 'uri', [new shaka.hls.Tag(2, 'EXTINF', [], '5')]), - new shaka.hls.Segment('https://test/uri2', + new shaka.hls.Segment('https://test/manifest.m3u8', 'uri2', [new shaka.hls.Tag(3, 'EXTINF', [], '4')]), ], }, @@ -449,9 +449,9 @@ describe('ManifestTextParser', () => { new shaka.hls.Tag(/* id= */ 4, 'EXT-X-ENDLIST', []), ], segments: [ - new shaka.hls.Segment('https://test/uri', + new shaka.hls.Segment('https://test/manifest.m3u8', 'uri', [new shaka.hls.Tag(2, 'EXTINF', [], '5')]), - new shaka.hls.Segment('https://test/uri2', + new shaka.hls.Segment('https://test/manifest.m3u8', 'uri2', [new shaka.hls.Tag(3, 'EXTINF', [], '4')]), ], }, @@ -508,20 +508,23 @@ describe('ManifestTextParser', () => { ], segments: [ new shaka.hls.Segment( - /* absoluteUri= */ 'https://test/uri', + /* absoluteMediaPlaylistUri= */ 'https://test/manifest.m3u8', + /* verbatimSegmentUri= */ 'uri', /* tags= */ [ new shaka.hls.Tag(3, 'EXTINF', [], '5'), mapTag, ]), new shaka.hls.Segment( - /* absoluteUri= */ 'https://test/uri2', + /* absoluteMediaPlaylistUri= */ 'https://test/manifest.m3u8', + /* verbatimSegmentUri= */ 'uri2', /* tags= */ [ new shaka.hls.Tag(6, 'EXTINF', [], '2'), mapTag, ], /* partialSegments= */ partialSegments1), new shaka.hls.Segment( - /* absoluteUri= */ '', + /* absoluteMediaPlaylistUri= */ '', + /* verbatimSegmentUri= */ '', /* tags= */ [mapTag], /* partialSegments= */ partialSegments2), ], @@ -574,13 +577,15 @@ describe('ManifestTextParser', () => { ], segments: [ new shaka.hls.Segment( - /* absoluteUri= */ 'https://test/uri', + /* absoluteMediaPlaylistUri= */ 'https://test/manifest.m3u8', + /* verbatimSegmentUri= */ 'uri', /* tags= */ [ new shaka.hls.Tag(3, 'EXTINF', [], '5'), mapTag, ]), new shaka.hls.Segment( - /* absoluteUri= */ '', + /* absoluteMediaPlaylistUri= */ '', + /* verbatimSegmentUri= */ '', /* tags= */ [preloadMapTag], /* partialSegments= */ preloadSegment), ],