rx-player 3.29.0-dev.2022091600 → 3.29.0-dev.2022103100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -10
- package/MAINTAINERS.md +2 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +4 -1
- package/dist/_esm5.processed/compat/browser_detection.js +7 -1
- package/dist/_esm5.processed/compat/can_reuse_media_keys.d.ts +12 -0
- package/dist/_esm5.processed/compat/can_reuse_media_keys.js +15 -0
- package/dist/_esm5.processed/compat/enable_audio_track.d.ts +11 -0
- package/dist/_esm5.processed/compat/enable_audio_track.js +26 -0
- package/dist/_esm5.processed/compat/index.d.ts +4 -2
- package/dist/_esm5.processed/compat/index.js +4 -2
- package/dist/_esm5.processed/compat/{should_renew_media_keys.d.ts → should_renew_media_key_system_access.d.ts} +3 -3
- package/dist/_esm5.processed/compat/{should_renew_media_keys.js → should_renew_media_key_system_access.js} +3 -3
- package/dist/_esm5.processed/config.d.ts +1 -0
- package/dist/_esm5.processed/core/api/playback_observer.d.ts +14 -5
- package/dist/_esm5.processed/core/api/playback_observer.js +54 -22
- package/dist/_esm5.processed/core/api/public_api.d.ts +7 -4
- package/dist/_esm5.processed/core/api/public_api.js +79 -61
- package/dist/_esm5.processed/core/api/tracks_management/media_element_track_choice_manager.js +9 -10
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +1 -1
- package/dist/_esm5.processed/core/decrypt/find_key_system.js +3 -3
- package/dist/_esm5.processed/core/decrypt/get_media_keys.js +4 -1
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +98 -0
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +173 -0
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +4 -4
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +2 -1
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +15 -16
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +3 -1
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +5 -2
- package/dist/_esm5.processed/core/fetchers/utils/schedule_request.d.ts +103 -0
- package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +414 -0
- package/dist/_esm5.processed/core/init/content_time_boundaries_observer.d.ts +4 -3
- package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +21 -22
- package/dist/_esm5.processed/core/init/initialize_media_source.d.ts +18 -4
- package/dist/_esm5.processed/core/init/initialize_media_source.js +10 -2
- package/dist/_esm5.processed/core/init/load_on_media_source.js +7 -1
- package/dist/_esm5.processed/core/init/stall_avoider.js +3 -1
- package/dist/_esm5.processed/default_config.d.ts +11 -0
- package/dist/_esm5.processed/default_config.js +11 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +1 -1
- package/dist/_esm5.processed/manifest/manifest.js +11 -2
- package/dist/_esm5.processed/manifest/representation.d.ts +12 -1
- package/dist/_esm5.processed/manifest/representation.js +1 -0
- package/dist/_esm5.processed/manifest/representation_index/static.d.ts +1 -1
- package/dist/_esm5.processed/manifest/representation_index/static.js +2 -2
- package/dist/_esm5.processed/manifest/representation_index/types.d.ts +32 -15
- package/dist/_esm5.processed/manifest/update_period_in_place.js +1 -0
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +10 -9
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +11 -11
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_init_segment.js +3 -3
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/get_segments_from_timeline.js +4 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +7 -7
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +12 -8
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +5 -6
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +16 -16
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +11 -10
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +14 -13
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.d.ts +3 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/tokens.js +4 -12
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_mpd.js +2 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representation_index.js +1 -3
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +6 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.d.ts +1 -2
- package/dist/_esm5.processed/parsers/manifest/dash/common/resolve_base_urls.js +3 -8
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.d.ts +1 -1
- package/dist/_esm5.processed/parsers/manifest/dash/js-parser/node_parsers/BaseURL.js +2 -20
- package/dist/_esm5.processed/parsers/manifest/dash/node_parser_types.d.ts +0 -6
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.js +0 -11
- package/dist/_esm5.processed/parsers/manifest/dash/wasm-parser/ts/types.d.ts +5 -1
- package/dist/_esm5.processed/parsers/manifest/local/parse_local_manifest.js +2 -1
- package/dist/_esm5.processed/parsers/manifest/local/representation_index.js +2 -2
- package/dist/_esm5.processed/parsers/manifest/metaplaylist/metaplaylist_parser.js +7 -1
- package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +17 -11
- package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.js +2 -2
- package/dist/_esm5.processed/parsers/manifest/types.d.ts +24 -0
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_extent.js +8 -1
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/apply_origin.js +9 -1
- package/dist/_esm5.processed/parsers/texttracks/ttml/html/create_element.js +2 -1
- package/dist/_esm5.processed/transports/dash/construct_segment_url.d.ts +18 -0
- package/dist/_esm5.processed/transports/dash/construct_segment_url.js +21 -0
- package/dist/_esm5.processed/transports/dash/image_pipelines.d.ts +3 -2
- package/dist/_esm5.processed/transports/dash/image_pipelines.js +5 -3
- package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -2
- package/dist/_esm5.processed/transports/dash/text_loader.js +4 -2
- package/dist/_esm5.processed/transports/dash/text_parser.js +3 -1
- package/dist/_esm5.processed/transports/local/segment_loader.d.ts +3 -2
- package/dist/_esm5.processed/transports/local/segment_loader.js +2 -2
- package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +8 -8
- package/dist/_esm5.processed/transports/smooth/pipelines.js +11 -7
- package/dist/_esm5.processed/transports/smooth/utils.d.ts +4 -2
- package/dist/_esm5.processed/transports/smooth/utils.js +7 -1
- package/dist/_esm5.processed/transports/types.d.ts +5 -3
- package/dist/_esm5.processed/utils/event_emitter.d.ts +1 -2
- package/dist/_esm5.processed/utils/resolve_url.d.ts +7 -4
- package/dist/_esm5.processed/utils/resolve_url.js +11 -8
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.js +5656 -13236
- package/dist/rx-player.min.js +1 -1
- package/jest.config.js +28 -23
- package/package.json +29 -29
- package/sonar-project.properties +1 -1
- package/src/compat/__tests__/can_reuse_media_keys.test.ts +54 -0
- package/src/compat/__tests__/enable_audio_track.test.ts +341 -0
- package/src/compat/__tests__/{should_renew_media_keys.test.ts → should_renew_media_key_system_access.test.ts} +7 -5
- package/src/compat/browser_detection.ts +10 -0
- package/src/compat/can_reuse_media_keys.ts +19 -0
- package/src/compat/enable_audio_track.ts +33 -0
- package/src/compat/index.ts +6 -2
- package/src/compat/{should_renew_media_keys.ts → should_renew_media_key_system_access.ts} +3 -3
- package/src/core/api/playback_observer.ts +97 -33
- package/src/core/api/public_api.ts +126 -74
- package/src/core/api/tracks_management/media_element_track_choice_manager.ts +3 -11
- package/src/core/decrypt/__tests__/__global__/media_keys.test.ts +182 -0
- package/src/core/decrypt/__tests__/__global__/utils.ts +2 -0
- package/src/core/decrypt/find_key_system.ts +3 -3
- package/src/core/decrypt/get_media_keys.ts +5 -1
- package/src/core/fetchers/cdn_prioritizer.ts +198 -0
- package/src/core/fetchers/manifest/manifest_fetcher.ts +7 -11
- package/src/core/fetchers/segment/segment_fetcher.ts +12 -10
- package/src/core/fetchers/segment/segment_fetcher_creator.ts +10 -1
- package/src/core/fetchers/utils/schedule_request.ts +482 -0
- package/src/core/init/content_time_boundaries_observer.ts +12 -12
- package/src/core/init/initialize_media_source.ts +31 -4
- package/src/core/init/load_on_media_source.ts +11 -2
- package/src/core/init/stall_avoider.ts +4 -1
- package/src/core/stream/orchestrator/stream_orchestrator.ts +0 -1
- package/src/default_config.ts +12 -0
- package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +1 -0
- package/src/manifest/manifest.ts +11 -2
- package/src/manifest/representation.ts +15 -0
- package/src/manifest/representation_index/__tests__/static.test.ts +1 -1
- package/src/manifest/representation_index/static.ts +3 -3
- package/src/manifest/representation_index/types.ts +33 -15
- package/src/manifest/update_period_in_place.ts +1 -0
- package/src/parsers/manifest/dash/common/indexes/base.ts +22 -23
- package/src/parsers/manifest/dash/common/indexes/get_init_segment.ts +6 -4
- package/src/parsers/manifest/dash/common/indexes/get_segments_from_timeline.ts +5 -5
- package/src/parsers/manifest/dash/common/indexes/list.ts +19 -20
- package/src/parsers/manifest/dash/common/indexes/template.ts +23 -27
- package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +25 -23
- package/src/parsers/manifest/dash/common/indexes/tokens.ts +7 -18
- package/src/parsers/manifest/dash/common/parse_mpd.ts +2 -4
- package/src/parsers/manifest/dash/common/parse_representation_index.ts +1 -6
- package/src/parsers/manifest/dash/common/parse_representations.ts +9 -0
- package/src/parsers/manifest/dash/common/resolve_base_urls.ts +5 -9
- package/src/parsers/manifest/dash/js-parser/node_parsers/BaseURL.ts +2 -29
- package/src/parsers/manifest/dash/js-parser/node_parsers/__tests__/AdaptationSet.test.ts +7 -11
- package/src/parsers/manifest/dash/node_parser_types.ts +0 -7
- package/src/parsers/manifest/dash/wasm-parser/rs/events.rs +3 -1
- package/src/parsers/manifest/dash/wasm-parser/rs/processor/attributes.rs +1 -8
- package/src/parsers/manifest/dash/wasm-parser/ts/generators/BaseURL.ts +0 -13
- package/src/parsers/manifest/dash/wasm-parser/ts/types.ts +8 -0
- package/src/parsers/manifest/local/parse_local_manifest.ts +1 -0
- package/src/parsers/manifest/local/representation_index.ts +2 -2
- package/src/parsers/manifest/metaplaylist/metaplaylist_parser.ts +7 -1
- package/src/parsers/manifest/smooth/create_parser.ts +17 -13
- package/src/parsers/manifest/smooth/representation_index.ts +2 -2
- package/src/parsers/manifest/types.ts +26 -1
- package/src/parsers/manifest/utils/__tests__/get_first_time_from_adaptations.test.ts +15 -0
- package/src/parsers/manifest/utils/__tests__/get_last_time_from_adaptation.test.ts +15 -0
- package/src/parsers/texttracks/ttml/html/apply_extent.ts +8 -1
- package/src/parsers/texttracks/ttml/html/apply_origin.ts +9 -1
- package/src/parsers/texttracks/ttml/html/create_element.ts +2 -2
- package/src/transports/dash/construct_segment_url.ts +28 -0
- package/src/transports/dash/image_pipelines.ts +5 -2
- package/src/transports/dash/segment_loader.ts +5 -2
- package/src/transports/dash/text_loader.ts +5 -2
- package/src/transports/dash/text_parser.ts +3 -1
- package/src/transports/local/segment_loader.ts +3 -2
- package/src/transports/metaplaylist/pipelines.ts +28 -9
- package/src/transports/smooth/pipelines.ts +12 -6
- package/src/transports/smooth/utils.ts +13 -1
- package/src/transports/types.ts +6 -3
- package/src/utils/__tests__/event_emitter.test.ts +72 -67
- package/src/utils/__tests__/initialization_segment_cache.test.ts +7 -7
- package/src/utils/__tests__/resolve_url.test.ts +27 -23
- package/src/utils/event_emitter.ts +1 -3
- package/src/utils/resolve_url.ts +11 -8
- package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.d.ts +0 -85
- package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +0 -264
- package/dummy +0 -1
- package/src/core/fetchers/utils/try_urls_with_backoff.ts +0 -287
package/src/default_config.ts
CHANGED
|
@@ -395,6 +395,18 @@ const DEFAULT_CONFIG = {
|
|
|
395
395
|
*/
|
|
396
396
|
DEFAULT_MAX_MANIFEST_REQUEST_RETRY: 4,
|
|
397
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Default delay, in seconds, during which a CDN will be "downgraded".
|
|
400
|
+
*
|
|
401
|
+
* For example in case of media content being available on multiple CDNs, the
|
|
402
|
+
* RxPlayer may decide that a CDN is less reliable (for example, it returned a
|
|
403
|
+
* server error) and should thus be avoided, at least for some time
|
|
404
|
+
*
|
|
405
|
+
* This value is the amount of time this CDN will be "less considered" than the
|
|
406
|
+
* alternatives.
|
|
407
|
+
*/
|
|
408
|
+
DEFAULT_CDN_DOWNGRADE_TIME: 60,
|
|
409
|
+
|
|
398
410
|
/**
|
|
399
411
|
* The default number of times a segment request will be re-performed when
|
|
400
412
|
* on error which justify a retry.
|
package/src/manifest/manifest.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
import arrayFind from "../utils/array_find";
|
|
24
24
|
import EventEmitter from "../utils/event_emitter";
|
|
25
25
|
import idGenerator from "../utils/id_generator";
|
|
26
|
+
import { getFilenameIndexInUrl } from "../utils/resolve_url";
|
|
26
27
|
import warnOnce from "../utils/warn_once";
|
|
27
28
|
import Adaptation from "./adaptation";
|
|
28
29
|
import Period, {
|
|
@@ -612,14 +613,18 @@ export default class Manifest extends EventEmitter<IManifestEvents> {
|
|
|
612
613
|
const newImageTracks = _imageTracks.map(({ mimeType, url }) => {
|
|
613
614
|
const adaptationID = "gen-image-ada-" + generateSupplementaryTrackID();
|
|
614
615
|
const representationID = "gen-image-rep-" + generateSupplementaryTrackID();
|
|
616
|
+
const indexOfFilename = getFilenameIndexInUrl(url);
|
|
617
|
+
const cdnUrl = url.substring(0, indexOfFilename);
|
|
618
|
+
const filename = url.substring(indexOfFilename);
|
|
615
619
|
const newAdaptation = new Adaptation({ id: adaptationID,
|
|
616
620
|
type: "image",
|
|
617
621
|
representations: [{
|
|
618
622
|
bitrate: 0,
|
|
623
|
+
cdnMetadata: [ { baseUrl: cdnUrl } ],
|
|
619
624
|
id: representationID,
|
|
620
625
|
mimeType,
|
|
621
626
|
index: new StaticRepresentationIndex({
|
|
622
|
-
media:
|
|
627
|
+
media: filename,
|
|
623
628
|
}) }] },
|
|
624
629
|
{ isManuallyAdded: true });
|
|
625
630
|
if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
|
|
@@ -664,6 +669,9 @@ export default class Manifest extends EventEmitter<IManifestEvents> {
|
|
|
664
669
|
languages != null ? languages :
|
|
665
670
|
[];
|
|
666
671
|
|
|
672
|
+
const indexOfFilename = getFilenameIndexInUrl(url);
|
|
673
|
+
const cdnUrl = url.substring(0, indexOfFilename);
|
|
674
|
+
const filename = url.substring(indexOfFilename);
|
|
667
675
|
return allSubs.concat(langsToMapOn.map((_language) => {
|
|
668
676
|
const adaptationID = "gen-text-ada-" + generateSupplementaryTrackID();
|
|
669
677
|
const representationID = "gen-text-rep-" + generateSupplementaryTrackID();
|
|
@@ -673,11 +681,12 @@ export default class Manifest extends EventEmitter<IManifestEvents> {
|
|
|
673
681
|
closedCaption,
|
|
674
682
|
representations: [{
|
|
675
683
|
bitrate: 0,
|
|
684
|
+
cdnMetadata: [{ baseUrl: cdnUrl }],
|
|
676
685
|
id: representationID,
|
|
677
686
|
mimeType,
|
|
678
687
|
codecs,
|
|
679
688
|
index: new StaticRepresentationIndex({
|
|
680
|
-
media:
|
|
689
|
+
media: filename,
|
|
681
690
|
}) }] },
|
|
682
691
|
{ isManuallyAdded: true });
|
|
683
692
|
if (newAdaptation.representations.length > 0 && !newAdaptation.isSupported) {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { isCodecSupported } from "../compat";
|
|
18
18
|
import log from "../log";
|
|
19
19
|
import {
|
|
20
|
+
ICdnMetadata,
|
|
20
21
|
IContentProtections,
|
|
21
22
|
IParsedRepresentation,
|
|
22
23
|
} from "../parsers/manifest";
|
|
@@ -41,6 +42,18 @@ class Representation {
|
|
|
41
42
|
*/
|
|
42
43
|
public index : IRepresentationIndex;
|
|
43
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Information on the CDN(s) on which requests should be done to request this
|
|
47
|
+
* Representation's initialization and media segments.
|
|
48
|
+
*
|
|
49
|
+
* `null` if there's no CDN involved here (e.g. resources are not requested
|
|
50
|
+
* through the network).
|
|
51
|
+
*
|
|
52
|
+
* An empty array means that no CDN are left to request the resource. As such,
|
|
53
|
+
* no resource can be loaded in that situation.
|
|
54
|
+
*/
|
|
55
|
+
public cdnMetadata : ICdnMetadata[] | null;
|
|
56
|
+
|
|
44
57
|
/** Bitrate this Representation is in, in bits per seconds. */
|
|
45
58
|
public bitrate : number;
|
|
46
59
|
|
|
@@ -129,6 +142,8 @@ class Representation {
|
|
|
129
142
|
this.hdrInfo = args.hdrInfo;
|
|
130
143
|
}
|
|
131
144
|
|
|
145
|
+
this.cdnMetadata = args.cdnMetadata;
|
|
146
|
+
|
|
132
147
|
this.index = args.index;
|
|
133
148
|
this.isSupported = opts.type === "audio" ||
|
|
134
149
|
opts.type === "video" ?
|
|
@@ -28,13 +28,13 @@ export interface IStaticRepresentationIndexInfos { media: string }
|
|
|
28
28
|
*/
|
|
29
29
|
export default class StaticRepresentationIndex implements IRepresentationIndex {
|
|
30
30
|
/** URL at which the content is available. */
|
|
31
|
-
private readonly
|
|
31
|
+
private readonly _url : string;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* @param {Object} infos
|
|
35
35
|
*/
|
|
36
36
|
constructor(infos : IStaticRepresentationIndexInfos) {
|
|
37
|
-
this.
|
|
37
|
+
this._url = infos.media;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/**
|
|
@@ -54,7 +54,7 @@ export default class StaticRepresentationIndex implements IRepresentationIndex {
|
|
|
54
54
|
return [{ id: "0",
|
|
55
55
|
isInit: false,
|
|
56
56
|
number: 0,
|
|
57
|
-
|
|
57
|
+
url: this._url,
|
|
58
58
|
time: 0,
|
|
59
59
|
end: Number.MAX_VALUE,
|
|
60
60
|
duration: Number.MAX_VALUE,
|
|
@@ -50,7 +50,7 @@ export interface ISmoothInitSegmentPrivateInfos {
|
|
|
50
50
|
* Supplementary information specific to Smooth media segments (that is, every
|
|
51
51
|
* segments but the initialization segment).
|
|
52
52
|
*/
|
|
53
|
-
export interface
|
|
53
|
+
export interface ISmoothMediaSegmentPrivateInfos {
|
|
54
54
|
/**
|
|
55
55
|
* Start time of the segment as announced in the Manifest, in the same
|
|
56
56
|
* timescale than the one indicated through `ISmoothInitSegmentPrivateInfos`.
|
|
@@ -113,28 +113,28 @@ export interface ILocalManifestSegmentPrivateInfos {
|
|
|
113
113
|
*/
|
|
114
114
|
export interface IPrivateInfos {
|
|
115
115
|
/** Smooth-specific information allowing to generate an initialization segment. */
|
|
116
|
-
smoothInitSegment? : ISmoothInitSegmentPrivateInfos
|
|
116
|
+
smoothInitSegment? : ISmoothInitSegmentPrivateInfos;
|
|
117
117
|
|
|
118
118
|
/** Smooth-specific information linked to all Smooth media segments. */
|
|
119
|
-
smoothMediaSegment? :
|
|
119
|
+
smoothMediaSegment? : ISmoothMediaSegmentPrivateInfos;
|
|
120
120
|
|
|
121
121
|
/** Information that should be present on all MetaPlaylist segments. */
|
|
122
|
-
metaplaylistInfos? : IMetaPlaylistPrivateInfos
|
|
122
|
+
metaplaylistInfos? : IMetaPlaylistPrivateInfos;
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
125
|
* Local Manifest-specific information allowing to request the
|
|
126
126
|
* initialization segment.
|
|
127
127
|
*/
|
|
128
|
-
localManifestInitSegment? : ILocalManifestInitSegmentPrivateInfos
|
|
128
|
+
localManifestInitSegment? : ILocalManifestInitSegmentPrivateInfos;
|
|
129
129
|
|
|
130
130
|
/** Local Manifest-specific information allowing to request any media segment. */
|
|
131
|
-
localManifestSegment? : ILocalManifestSegmentPrivateInfos
|
|
131
|
+
localManifestSegment? : ILocalManifestSegmentPrivateInfos;
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
134
|
* Function allowing to know if a given emsg's event name has been
|
|
135
135
|
* explicitely authorized.
|
|
136
136
|
*/
|
|
137
|
-
isEMSGWhitelisted? : ((evt: IEMSG) => boolean)
|
|
137
|
+
isEMSGWhitelisted? : ((evt: IEMSG) => boolean);
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
/** Represent a single Segment from a Representation. */
|
|
@@ -160,15 +160,10 @@ export interface ISegment {
|
|
|
160
160
|
*/
|
|
161
161
|
isInit : boolean;
|
|
162
162
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
163
|
+
* Store supplementary information on a segment that can be later exploited by
|
|
164
|
+
* the transport logic.
|
|
165
165
|
*/
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Allows to store supplementary information on a segment that can be later
|
|
169
|
-
* exploited by the transport logic.
|
|
170
|
-
*/
|
|
171
|
-
privateInfos : IPrivateInfos | undefined;
|
|
166
|
+
privateInfos : IPrivateInfos;
|
|
172
167
|
/**
|
|
173
168
|
* Estimated time, in seconds, at which the concerned segment should be
|
|
174
169
|
* offseted when decoded.
|
|
@@ -230,6 +225,29 @@ export interface ISegment {
|
|
|
230
225
|
* generated.
|
|
231
226
|
*/
|
|
232
227
|
complete : boolean;
|
|
228
|
+
/**
|
|
229
|
+
* Optional relative or absolute URL to load the resource.
|
|
230
|
+
*
|
|
231
|
+
* If the URL is absolute (it contains the scheme at the beginning), it is the
|
|
232
|
+
* complete URL on which the resource should be requested.
|
|
233
|
+
*
|
|
234
|
+
* If the URL is relative (it does not contain a scheme at the beginning), it
|
|
235
|
+
* should be relative to the chosen CDN that should be recuperated through
|
|
236
|
+
* another mean
|
|
237
|
+
*
|
|
238
|
+
* If `null`, it means either:
|
|
239
|
+
*
|
|
240
|
+
* - that there is no way to reach the resource through a URL.
|
|
241
|
+
*
|
|
242
|
+
* - that there may be an URL, but is already communicated through another
|
|
243
|
+
* mean, like the currently chosen CDN.
|
|
244
|
+
*
|
|
245
|
+
* An empty string is equivalent to indicating that the chosen CDN's URL
|
|
246
|
+
* should be directly requested instead.
|
|
247
|
+
* In that way, it is equivalent to setting it to `null`.
|
|
248
|
+
*/
|
|
249
|
+
url : string | null;
|
|
250
|
+
|
|
233
251
|
/**
|
|
234
252
|
* Optional byte range to retrieve the Segment from its URL(s).
|
|
235
253
|
* TODO this should probably moved to `privateInfos` as this is
|
|
@@ -59,6 +59,7 @@ export default function updatePeriodInPlace(oldPeriod : Period,
|
|
|
59
59
|
log.warn(`Manifest: Representation "${oldRepresentations[k].id}" ` +
|
|
60
60
|
"not found when merging.");
|
|
61
61
|
} else {
|
|
62
|
+
oldRepresentation.cdnMetadata = newRepresentation.cdnMetadata;
|
|
62
63
|
if (updateType === MANIFEST_UPDATE_TYPE.Full) {
|
|
63
64
|
oldRepresentation.index._replace(newRepresentation.index);
|
|
64
65
|
} else {
|
|
@@ -26,10 +26,9 @@ import {
|
|
|
26
26
|
IIndexSegment,
|
|
27
27
|
toIndexTime,
|
|
28
28
|
} from "../../../utils/index_helpers";
|
|
29
|
-
import { IResolvedBaseUrl } from "../resolve_base_urls";
|
|
30
29
|
import getInitSegment from "./get_init_segment";
|
|
31
30
|
import getSegmentsFromTimeline from "./get_segments_from_timeline";
|
|
32
|
-
import {
|
|
31
|
+
import { constructRepresentationUrl } from "./tokens";
|
|
33
32
|
|
|
34
33
|
/**
|
|
35
34
|
* Index property defined for a SegmentBase RepresentationIndex
|
|
@@ -53,17 +52,21 @@ export interface IBaseIndex {
|
|
|
53
52
|
*/
|
|
54
53
|
indexTimeOffset : number;
|
|
55
54
|
/** Information on the initialization segment. */
|
|
56
|
-
initialization
|
|
57
|
-
/**
|
|
58
|
-
|
|
55
|
+
initialization : {
|
|
56
|
+
/**
|
|
57
|
+
* URL path, to add to the wanted CDN, to access the initialization segment.
|
|
58
|
+
* `null` if no URL exists.
|
|
59
|
+
*/
|
|
60
|
+
url: string | null;
|
|
59
61
|
/** possible byte range to request it. */
|
|
60
62
|
range?: [number, number] | undefined;
|
|
61
63
|
} | undefined;
|
|
62
64
|
/**
|
|
63
|
-
*
|
|
64
|
-
* it to real URLs.
|
|
65
|
+
* URL base to access any segment.
|
|
66
|
+
* Can contain token to replace to convert it to real URLs.
|
|
67
|
+
* `null` if no URL exists.
|
|
65
68
|
*/
|
|
66
|
-
|
|
69
|
+
segmentUrlTemplate : string | null;
|
|
67
70
|
/** Number from which the first segments in this index starts with. */
|
|
68
71
|
startNumber? : number | undefined;
|
|
69
72
|
/** Every segments defined in this index. */
|
|
@@ -110,8 +113,6 @@ export interface IBaseIndexContextArgument {
|
|
|
110
113
|
periodStart : number;
|
|
111
114
|
/** End of the period concerned by this RepresentationIndex, in seconds. */
|
|
112
115
|
periodEnd : number|undefined;
|
|
113
|
-
/** Base URL for the Representation concerned. */
|
|
114
|
-
representationBaseURLs : IResolvedBaseUrl[];
|
|
115
116
|
/** ID of the Representation concerned. */
|
|
116
117
|
representationId? : string | undefined;
|
|
117
118
|
/** Bitrate of the Representation concerned. */
|
|
@@ -185,7 +186,6 @@ export default class BaseRepresentationIndex implements IRepresentationIndex {
|
|
|
185
186
|
constructor(index : IBaseIndexIndexArgument, context : IBaseIndexContextArgument) {
|
|
186
187
|
const { periodStart,
|
|
187
188
|
periodEnd,
|
|
188
|
-
representationBaseURLs,
|
|
189
189
|
representationId,
|
|
190
190
|
representationBitrate,
|
|
191
191
|
isEMSGWhitelisted } = context;
|
|
@@ -196,13 +196,15 @@ export default class BaseRepresentationIndex implements IRepresentationIndex {
|
|
|
196
196
|
|
|
197
197
|
const indexTimeOffset = presentationTimeOffset - periodStart * timescale;
|
|
198
198
|
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
199
|
+
const initializationUrl = index.initialization?.media === undefined ?
|
|
200
|
+
null :
|
|
201
|
+
constructRepresentationUrl(index.initialization.media,
|
|
202
|
+
representationId,
|
|
203
|
+
representationBitrate);
|
|
204
|
+
|
|
205
|
+
const segmentUrlTemplate = index.media === undefined ?
|
|
206
|
+
null :
|
|
207
|
+
constructRepresentationUrl(index.media, representationId, representationBitrate);
|
|
206
208
|
|
|
207
209
|
// TODO If indexRange is either undefined or behind the initialization segment
|
|
208
210
|
// the following logic will not work.
|
|
@@ -217,11 +219,8 @@ export default class BaseRepresentationIndex implements IRepresentationIndex {
|
|
|
217
219
|
|
|
218
220
|
this._index = { indexRange: index.indexRange,
|
|
219
221
|
indexTimeOffset,
|
|
220
|
-
initialization: {
|
|
221
|
-
|
|
222
|
-
index.media,
|
|
223
|
-
representationId,
|
|
224
|
-
representationBitrate),
|
|
222
|
+
initialization: { url: initializationUrl, range },
|
|
223
|
+
segmentUrlTemplate,
|
|
225
224
|
startNumber: index.startNumber,
|
|
226
225
|
timeline: index.timeline ?? [],
|
|
227
226
|
timescale };
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { ISegment } from "../../../../../manifest";
|
|
18
|
+
import { IPrivateInfos } from "../../../../../manifest/representation_index/types";
|
|
18
19
|
import { IEMSG } from "../../../../containers/isobmff";
|
|
19
20
|
|
|
20
21
|
/**
|
|
@@ -25,7 +26,7 @@ import { IEMSG } from "../../../../containers/isobmff";
|
|
|
25
26
|
*/
|
|
26
27
|
export default function getInitSegment(
|
|
27
28
|
index: { timescale: number;
|
|
28
|
-
initialization?: {
|
|
29
|
+
initialization?: { url: string | null;
|
|
29
30
|
range?: [number, number] | undefined; } |
|
|
30
31
|
undefined;
|
|
31
32
|
indexRange?: [number, number] | undefined;
|
|
@@ -33,10 +34,11 @@ export default function getInitSegment(
|
|
|
33
34
|
isEMSGWhitelisted?: (inbandEvent: IEMSG) => boolean
|
|
34
35
|
) : ISegment {
|
|
35
36
|
const { initialization } = index;
|
|
36
|
-
|
|
37
|
+
const privateInfos : IPrivateInfos = {};
|
|
37
38
|
if (isEMSGWhitelisted !== undefined) {
|
|
38
|
-
privateInfos =
|
|
39
|
+
privateInfos.isEMSGWhitelisted = isEMSGWhitelisted;
|
|
39
40
|
}
|
|
41
|
+
|
|
40
42
|
return { id: "init",
|
|
41
43
|
isInit: true,
|
|
42
44
|
time: 0,
|
|
@@ -46,7 +48,7 @@ export default function getInitSegment(
|
|
|
46
48
|
range: initialization != null ? initialization.range :
|
|
47
49
|
undefined,
|
|
48
50
|
indexRange: index.indexRange,
|
|
49
|
-
|
|
51
|
+
url: initialization?.url ?? null,
|
|
50
52
|
complete: true,
|
|
51
53
|
privateInfos,
|
|
52
54
|
timestampOffset: -(index.indexTimeOffset / index.timescale) };
|
|
@@ -53,7 +53,7 @@ function getWantedRepeatIndex(
|
|
|
53
53
|
*/
|
|
54
54
|
export default function getSegmentsFromTimeline(
|
|
55
55
|
index : { availabilityTimeComplete? : boolean | undefined;
|
|
56
|
-
|
|
56
|
+
segmentUrlTemplate : string | null;
|
|
57
57
|
startNumber? : number | undefined;
|
|
58
58
|
timeline : IIndexSegment[];
|
|
59
59
|
timescale : number;
|
|
@@ -65,7 +65,7 @@ export default function getSegmentsFromTimeline(
|
|
|
65
65
|
) : ISegment[] {
|
|
66
66
|
const scaledUp = toIndexTime(from, index);
|
|
67
67
|
const scaledTo = toIndexTime(from + durationWanted, index);
|
|
68
|
-
const { timeline, timescale,
|
|
68
|
+
const { timeline, timescale, segmentUrlTemplate, startNumber } = index;
|
|
69
69
|
|
|
70
70
|
let currentNumber = startNumber ?? 1;
|
|
71
71
|
const segments : ISegment[] = [];
|
|
@@ -85,9 +85,9 @@ export default function getSegmentsFromTimeline(
|
|
|
85
85
|
while (segmentTime < scaledTo && segmentNumberInCurrentRange <= repeat) {
|
|
86
86
|
const segmentNumber = currentNumber + segmentNumberInCurrentRange;
|
|
87
87
|
|
|
88
|
-
const
|
|
88
|
+
const detokenizedURL = segmentUrlTemplate === null ?
|
|
89
89
|
null :
|
|
90
|
-
|
|
90
|
+
createDashUrlDetokenizer(segmentTime, segmentNumber)(segmentUrlTemplate);
|
|
91
91
|
|
|
92
92
|
let time = segmentTime - index.indexTimeOffset;
|
|
93
93
|
let realDuration = duration;
|
|
@@ -103,7 +103,7 @@ export default function getSegmentsFromTimeline(
|
|
|
103
103
|
isInit: false,
|
|
104
104
|
range,
|
|
105
105
|
timescale: 1 as const,
|
|
106
|
-
|
|
106
|
+
url: detokenizedURL,
|
|
107
107
|
number: segmentNumber,
|
|
108
108
|
timestampOffset: -(index.indexTimeOffset / timescale),
|
|
109
109
|
complete,
|
|
@@ -21,9 +21,8 @@ import {
|
|
|
21
21
|
} from "../../../../../manifest";
|
|
22
22
|
import { IEMSG } from "../../../../containers/isobmff";
|
|
23
23
|
import { getTimescaledRange } from "../../../utils/index_helpers";
|
|
24
|
-
import { IResolvedBaseUrl } from "../resolve_base_urls";
|
|
25
24
|
import getInitSegment from "./get_init_segment";
|
|
26
|
-
import {
|
|
25
|
+
import { constructRepresentationUrl } from "./tokens";
|
|
27
26
|
|
|
28
27
|
/**
|
|
29
28
|
* Index property defined for a SegmentList RepresentationIndex
|
|
@@ -53,18 +52,21 @@ export interface IListIndex {
|
|
|
53
52
|
indexTimeOffset : number;
|
|
54
53
|
/** Information on the initialization segment. */
|
|
55
54
|
initialization? : {
|
|
56
|
-
/**
|
|
57
|
-
|
|
55
|
+
/**
|
|
56
|
+
* URL path, to add to the wanted CDN, to access the initialization segment.
|
|
57
|
+
* `null` if no URL exists.
|
|
58
|
+
*/
|
|
59
|
+
url: string | null;
|
|
58
60
|
/** possible byte range to request it. */
|
|
59
61
|
range?: [number, number] | undefined;
|
|
60
62
|
} | undefined;
|
|
61
63
|
/** Information on the list of segments for this index. */
|
|
62
64
|
list: Array<{
|
|
63
65
|
/**
|
|
64
|
-
*
|
|
66
|
+
* URL path, to add to the wanted CDN, to access this media segment.
|
|
65
67
|
* `null` if no URL exists.
|
|
66
68
|
*/
|
|
67
|
-
|
|
69
|
+
url : string | null;
|
|
68
70
|
/** Possible byte-range of the segment. */
|
|
69
71
|
mediaRange? : [number, number] | undefined;
|
|
70
72
|
}>;
|
|
@@ -111,8 +113,6 @@ export interface IListIndexContextArgument {
|
|
|
111
113
|
periodStart : number;
|
|
112
114
|
/** End of the period concerned by this RepresentationIndex, in seconds. */
|
|
113
115
|
periodEnd : number | undefined;
|
|
114
|
-
/** Base URL for the Representation concerned. */
|
|
115
|
-
representationBaseURLs : IResolvedBaseUrl[];
|
|
116
116
|
/** ID of the Representation concerned. */
|
|
117
117
|
representationId? : string | undefined;
|
|
118
118
|
/** Bitrate of the Representation concerned. */
|
|
@@ -142,7 +142,6 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
142
142
|
|
|
143
143
|
const { periodStart,
|
|
144
144
|
periodEnd,
|
|
145
|
-
representationBaseURLs,
|
|
146
145
|
representationId,
|
|
147
146
|
representationBitrate,
|
|
148
147
|
isEMSGWhitelisted } = context;
|
|
@@ -155,12 +154,15 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
155
154
|
const timescale = index.timescale ?? 1;
|
|
156
155
|
const indexTimeOffset = presentationTimeOffset - periodStart * timescale;
|
|
157
156
|
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
lItem.media,
|
|
157
|
+
const initializationUrl = index.initialization?.media === undefined ?
|
|
158
|
+
null :
|
|
159
|
+
constructRepresentationUrl(index.initialization.media,
|
|
162
160
|
representationId,
|
|
163
|
-
representationBitrate)
|
|
161
|
+
representationBitrate);
|
|
162
|
+
const list = index.list.map((lItem) => ({
|
|
163
|
+
url: lItem.media === undefined ?
|
|
164
|
+
null :
|
|
165
|
+
constructRepresentationUrl(lItem.media, representationId, representationBitrate),
|
|
164
166
|
mediaRange: lItem.mediaRange }));
|
|
165
167
|
this._index = { list,
|
|
166
168
|
timescale,
|
|
@@ -169,10 +171,7 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
169
171
|
indexRange: index.indexRange,
|
|
170
172
|
initialization: index.initialization == null ?
|
|
171
173
|
undefined :
|
|
172
|
-
{
|
|
173
|
-
index.initialization.media,
|
|
174
|
-
representationId,
|
|
175
|
-
representationBitrate),
|
|
174
|
+
{ url: initializationUrl,
|
|
176
175
|
range: index.initialization.range } };
|
|
177
176
|
}
|
|
178
177
|
|
|
@@ -206,7 +205,7 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
206
205
|
let i = Math.floor(up / duration);
|
|
207
206
|
while (i <= length) {
|
|
208
207
|
const range = list[i].mediaRange;
|
|
209
|
-
const
|
|
208
|
+
const url = list[i].url;
|
|
210
209
|
const time = i * durationInSeconds + this._periodStart;
|
|
211
210
|
const segment =
|
|
212
211
|
{ id: String(i),
|
|
@@ -216,7 +215,7 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
216
215
|
duration: durationInSeconds,
|
|
217
216
|
timescale: 1 as const,
|
|
218
217
|
end: time + durationInSeconds,
|
|
219
|
-
|
|
218
|
+
url,
|
|
220
219
|
timestampOffset: -(index.indexTimeOffset / timescale),
|
|
221
220
|
complete: true,
|
|
222
221
|
privateInfos: { isEMSGWhitelisted:
|
|
@@ -22,11 +22,10 @@ import {
|
|
|
22
22
|
import assert from "../../../../../utils/assert";
|
|
23
23
|
import { IEMSG } from "../../../../containers/isobmff";
|
|
24
24
|
import ManifestBoundsCalculator from "../manifest_bounds_calculator";
|
|
25
|
-
import { IResolvedBaseUrl } from "../resolve_base_urls";
|
|
26
25
|
import getInitSegment from "./get_init_segment";
|
|
27
26
|
import {
|
|
28
27
|
createDashUrlDetokenizer,
|
|
29
|
-
|
|
28
|
+
constructRepresentationUrl,
|
|
30
29
|
} from "./tokens";
|
|
31
30
|
import { getSegmentTimeRoundingError } from "./utils";
|
|
32
31
|
|
|
@@ -52,8 +51,10 @@ export interface ITemplateIndex {
|
|
|
52
51
|
indexRange?: [number, number] | undefined;
|
|
53
52
|
/** Information on the initialization segment. */
|
|
54
53
|
initialization? : {
|
|
55
|
-
/**
|
|
56
|
-
|
|
54
|
+
/**
|
|
55
|
+
* URL path, to add to the wanted CDN, to access the initialization segment.
|
|
56
|
+
*/
|
|
57
|
+
url: string | null;
|
|
57
58
|
/** possible byte range to request it. */
|
|
58
59
|
range?: [number, number] | undefined;
|
|
59
60
|
} | undefined;
|
|
@@ -62,7 +63,7 @@ export interface ITemplateIndex {
|
|
|
62
63
|
* Can contain token to replace to convert it to real URLs.
|
|
63
64
|
* `null` if no URL exists.
|
|
64
65
|
*/
|
|
65
|
-
|
|
66
|
+
url : string | null;
|
|
66
67
|
/**
|
|
67
68
|
* Temporal offset, in the current timescale (see timescale), to add to the
|
|
68
69
|
* presentation time (time a segment has at decoding time) to obtain the
|
|
@@ -124,8 +125,6 @@ export interface ITemplateIndexContextArgument {
|
|
|
124
125
|
periodEnd : number|undefined;
|
|
125
126
|
/** Whether the corresponding Manifest can be updated and changed. */
|
|
126
127
|
isDynamic : boolean;
|
|
127
|
-
/** Base URL for the Representation concerned. */
|
|
128
|
-
representationBaseURLs : IResolvedBaseUrl[];
|
|
129
128
|
/** ID of the Representation concerned. */
|
|
130
129
|
representationId? : string | undefined;
|
|
131
130
|
/** Bitrate of the Representation concerned. */
|
|
@@ -174,18 +173,12 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex
|
|
|
174
173
|
isDynamic,
|
|
175
174
|
periodEnd,
|
|
176
175
|
periodStart,
|
|
177
|
-
representationBaseURLs,
|
|
178
176
|
representationId,
|
|
179
177
|
representationBitrate,
|
|
180
178
|
isEMSGWhitelisted } = context;
|
|
181
179
|
const timescale = index.timescale ?? 1;
|
|
182
180
|
|
|
183
|
-
|
|
184
|
-
0 :
|
|
185
|
-
representationBaseURLs.reduce((acc, rbu) => {
|
|
186
|
-
return Math.min(acc, rbu.availabilityTimeOffset);
|
|
187
|
-
}, Infinity);
|
|
188
|
-
this._availabilityTimeOffset = availabilityTimeOffset + minBaseUrlAto;
|
|
181
|
+
this._availabilityTimeOffset = availabilityTimeOffset;
|
|
189
182
|
|
|
190
183
|
this._manifestBoundsCalculator = manifestBoundsCalculator;
|
|
191
184
|
this._aggressiveMode = aggressiveMode;
|
|
@@ -200,22 +193,25 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex
|
|
|
200
193
|
throw new Error("Invalid SegmentTemplate: no duration");
|
|
201
194
|
}
|
|
202
195
|
|
|
203
|
-
const
|
|
196
|
+
const initializationUrl = index.initialization?.media === undefined ?
|
|
197
|
+
null :
|
|
198
|
+
constructRepresentationUrl(index.initialization.media,
|
|
199
|
+
representationId,
|
|
200
|
+
representationBitrate);
|
|
201
|
+
|
|
202
|
+
const segmentUrlTemplate = index.media === undefined ?
|
|
203
|
+
null :
|
|
204
|
+
constructRepresentationUrl(index.media, representationId, representationBitrate);
|
|
205
|
+
|
|
204
206
|
this._index = { duration: index.duration,
|
|
205
207
|
timescale,
|
|
206
208
|
indexRange: index.indexRange,
|
|
207
209
|
indexTimeOffset,
|
|
208
210
|
initialization: index.initialization == null ?
|
|
209
211
|
undefined :
|
|
210
|
-
{
|
|
211
|
-
index.initialization.media,
|
|
212
|
-
representationId,
|
|
213
|
-
representationBitrate),
|
|
212
|
+
{ url: initializationUrl,
|
|
214
213
|
range: index.initialization.range },
|
|
215
|
-
|
|
216
|
-
index.media,
|
|
217
|
-
representationId,
|
|
218
|
-
representationBitrate),
|
|
214
|
+
url: segmentUrlTemplate,
|
|
219
215
|
presentationTimeOffset,
|
|
220
216
|
startNumber: index.startNumber };
|
|
221
217
|
this._isDynamic = isDynamic;
|
|
@@ -244,7 +240,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex
|
|
|
244
240
|
const { duration,
|
|
245
241
|
startNumber,
|
|
246
242
|
timescale,
|
|
247
|
-
|
|
243
|
+
url } = index;
|
|
248
244
|
|
|
249
245
|
const scaledStart = this._periodStart * timescale;
|
|
250
246
|
const scaledEnd = this._scaledRelativePeriodEnd;
|
|
@@ -288,9 +284,9 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex
|
|
|
288
284
|
const realTime = timeFromPeriodStart + scaledStart;
|
|
289
285
|
const manifestTime = timeFromPeriodStart + this._index.presentationTimeOffset;
|
|
290
286
|
|
|
291
|
-
const
|
|
287
|
+
const detokenizedURL = url === null ?
|
|
292
288
|
null :
|
|
293
|
-
|
|
289
|
+
createDashUrlDetokenizer(manifestTime, realNumber)(url);
|
|
294
290
|
|
|
295
291
|
const args = { id: String(realNumber),
|
|
296
292
|
number: realNumber,
|
|
@@ -300,7 +296,7 @@ export default class TemplateRepresentationIndex implements IRepresentationIndex
|
|
|
300
296
|
timescale: 1 as const,
|
|
301
297
|
isInit: false,
|
|
302
298
|
scaledDuration: realDuration / timescale,
|
|
303
|
-
|
|
299
|
+
url: detokenizedURL,
|
|
304
300
|
timestampOffset: -(index.indexTimeOffset / timescale),
|
|
305
301
|
complete: true,
|
|
306
302
|
privateInfos: {
|