Skip to content

Commit

Permalink
feat(HLS): Improve HLS parsing time (shaka-project#5264)
Browse files Browse the repository at this point in the history
Related to shaka-project#5261

This PR delays the creation of the final urls of the segments so that
they are not calculated in each media playlist parsing.
  • Loading branch information
avelad committed Jun 8, 2023
1 parent 5a5a7ac commit 2ca7d0b
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
41 changes: 33 additions & 8 deletions lib/hls/hls_classes.js
Expand Up @@ -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');


Expand Down Expand Up @@ -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.<shaka.hls.Tag>} tags
* @param {!Array.<shaka.hls.Tag>=} partialSegments
*/
constructor(absoluteUri, tags, partialSegments=[]) {
constructor(absoluteMediaPlaylistUri, verbatimSegmentUri, tags,
partialSegments=[]) {
/** @const {!Array.<shaka.hls.Tag>} */
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.<shaka.hls.Tag>} */
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_ || '';
}
};


Expand Down
8 changes: 3 additions & 5 deletions lib/hls/manifest_text_parser.js
Expand Up @@ -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 = [];
Expand All @@ -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);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/util/manifest_parser_utils.js
Expand Up @@ -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.<string>} baseUris
* @param {!Array.<string>} relativeUris
* @return {!Array.<string>}
Expand Down
31 changes: 18 additions & 13 deletions test/hls/manifest_text_parser_unit.js
Expand Up @@ -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'),
]),
Expand All @@ -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',
Expand Down Expand Up @@ -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',
[
Expand Down Expand Up @@ -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'),
]),
Expand Down Expand Up @@ -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')]),
],
},
Expand All @@ -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')]),
],
},
Expand Down Expand Up @@ -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),
],
Expand Down Expand Up @@ -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),
],
Expand Down

0 comments on commit 2ca7d0b

Please sign in to comment.