rx-player 3.28.0-dev.2022063000 → 3.28.1-dev.2022083000
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/.github/workflows/checks.yml +20 -18
- package/CHANGELOG.md +14 -2
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/eme/load_session.d.ts +5 -6
- package/dist/_esm5.processed/compat/eme/load_session.js +5 -6
- package/dist/_esm5.processed/compat/event_listeners.js +5 -0
- package/dist/_esm5.processed/core/api/media_element_track_choice_manager.js +1 -1
- package/dist/_esm5.processed/core/api/public_api.js +2 -2
- package/dist/_esm5.processed/core/decrypt/create_session.js +33 -4
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +14 -0
- package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +25 -0
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +1 -1
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +1 -1
- package/dist/_esm5.processed/core/init/content_time_boundaries_observer.js +110 -38
- package/dist/_esm5.processed/core/stream/representation/check_for_discontinuity.js +21 -9
- package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +21 -29
- package/dist/_esm5.processed/errors/encrypted_media_error.d.ts +1 -2
- package/dist/_esm5.processed/errors/encrypted_media_error.js +0 -1
- package/dist/_esm5.processed/errors/error_codes.d.ts +6 -1
- package/dist/_esm5.processed/errors/media_error.d.ts +1 -2
- package/dist/_esm5.processed/errors/media_error.js +0 -1
- package/dist/_esm5.processed/errors/network_error.d.ts +1 -2
- package/dist/_esm5.processed/errors/network_error.js +0 -1
- package/dist/_esm5.processed/errors/other_error.d.ts +1 -2
- package/dist/_esm5.processed/errors/other_error.js +0 -1
- package/dist/_esm5.processed/manifest/manifest.d.ts +1 -1
- package/dist/_esm5.processed/manifest/manifest.js +1 -1
- package/dist/_esm5.processed/manifest/representation_index/static.d.ts +21 -6
- package/dist/_esm5.processed/manifest/representation_index/static.js +26 -8
- package/dist/_esm5.processed/manifest/representation_index/types.d.ts +55 -44
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.d.ts +21 -8
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/base.js +25 -10
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.d.ts +26 -12
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/list.js +26 -13
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.d.ts +23 -7
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/template.js +65 -22
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.d.ts +20 -3
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.js +57 -7
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/{is_period_fulfilled.d.ts → utils.d.ts} +3 -6
- package/dist/_esm5.processed/parsers/manifest/dash/common/indexes/{is_period_fulfilled.js → utils.js} +4 -8
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_periods.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/local/parse_local_manifest.js +5 -8
- package/dist/_esm5.processed/parsers/manifest/local/representation_index.d.ts +21 -8
- package/dist/_esm5.processed/parsers/manifest/local/representation_index.js +49 -14
- package/dist/_esm5.processed/parsers/manifest/local/types.d.ts +16 -0
- package/dist/_esm5.processed/parsers/manifest/metaplaylist/representation_index.d.ts +20 -6
- package/dist/_esm5.processed/parsers/manifest/metaplaylist/representation_index.js +28 -10
- package/dist/_esm5.processed/parsers/manifest/smooth/create_parser.js +4 -4
- package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.d.ts +21 -12
- package/dist/_esm5.processed/parsers/manifest/smooth/representation_index.js +39 -14
- package/dist/_esm5.processed/parsers/manifest/utils/get_first_time_from_adaptation.js +1 -1
- package/dist/_esm5.processed/parsers/manifest/utils/get_last_time_from_adaptation.js +1 -1
- package/dist/_esm5.processed/transports/metaplaylist/pipelines.js +0 -2
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +1 -1
- package/dist/_esm5.processed/transports/types.d.ts +1 -1
- package/dist/_esm5.processed/utils/deep_merge.d.ts +1 -1
- package/dist/_esm5.processed/utils/deep_merge.js +6 -5
- package/dist/_esm5.processed/utils/task_canceller.d.ts +0 -3
- package/dist/_esm5.processed/utils/task_canceller.js +0 -3
- package/dist/mpd-parser.wasm +0 -0
- package/dist/rx-player.js +1390 -1059
- package/dist/rx-player.min.js +1 -1
- package/jest.config.js +5 -0
- package/package.json +31 -30
- package/sonar-project.properties +1 -1
- package/src/compat/eme/load_session.ts +5 -6
- package/src/compat/event_listeners.ts +5 -0
- package/src/core/api/media_element_track_choice_manager.ts +1 -1
- package/src/core/api/public_api.ts +2 -2
- package/src/core/decrypt/create_session.ts +28 -2
- package/src/core/decrypt/utils/loaded_sessions_store.ts +29 -0
- package/src/core/fetchers/segment/segment_fetcher.ts +1 -1
- package/src/core/init/content_time_boundaries_observer.ts +116 -42
- package/src/core/stream/representation/check_for_discontinuity.ts +28 -10
- package/src/core/stream/representation/get_buffer_status.ts +27 -34
- package/src/errors/encrypted_media_error.ts +1 -2
- package/src/errors/error_codes.ts +2 -2
- package/src/errors/media_error.ts +1 -2
- package/src/errors/network_error.ts +1 -2
- package/src/errors/other_error.ts +1 -2
- package/src/manifest/__tests__/adaptation.test.ts +4 -3
- package/src/manifest/__tests__/representation.test.ts +4 -3
- package/src/manifest/manifest.ts +1 -1
- package/src/manifest/representation_index/__tests__/static.test.ts +5 -4
- package/src/manifest/representation_index/static.ts +28 -9
- package/src/manifest/representation_index/types.ts +62 -46
- package/src/parsers/manifest/dash/common/indexes/base.ts +27 -11
- package/src/parsers/manifest/dash/common/indexes/list.ts +32 -15
- package/src/parsers/manifest/dash/common/indexes/template.ts +73 -27
- package/src/parsers/manifest/dash/common/indexes/timeline/timeline_representation_index.ts +60 -8
- package/src/parsers/manifest/dash/common/indexes/{is_period_fulfilled.ts → utils.ts} +4 -13
- package/src/parsers/manifest/dash/common/parse_periods.ts +1 -1
- package/src/parsers/manifest/local/parse_local_manifest.ts +8 -20
- package/src/parsers/manifest/local/representation_index.ts +51 -16
- package/src/parsers/manifest/local/types.ts +13 -0
- package/src/parsers/manifest/metaplaylist/representation_index.ts +31 -11
- package/src/parsers/manifest/smooth/create_parser.ts +4 -4
- package/src/parsers/manifest/smooth/representation_index.ts +40 -15
- package/src/parsers/manifest/utils/__tests__/get_first_time_from_adaptations.test.ts +4 -3
- package/src/parsers/manifest/utils/__tests__/get_last_time_from_adaptation.test.ts +4 -3
- package/src/parsers/manifest/utils/get_first_time_from_adaptation.ts +1 -1
- package/src/parsers/manifest/utils/get_last_time_from_adaptation.ts +1 -1
- package/src/transports/metaplaylist/pipelines.ts +0 -2
- package/src/transports/smooth/segment_loader.ts +1 -1
- package/src/transports/types.ts +1 -1
- package/src/utils/__tests__/initialization_segment_cache.test.ts +7 -0
- package/src/utils/deep_merge.ts +7 -4
- package/src/utils/task_canceller.ts +0 -3
|
@@ -64,38 +64,30 @@ export default function getBufferStatus(content, initialWantedTime, playbackObse
|
|
|
64
64
|
* `true` if the current `RepresentationStream` has loaded all the
|
|
65
65
|
* needed segments for this Representation until the end of the Period.
|
|
66
66
|
*/
|
|
67
|
-
var hasFinishedLoading =
|
|
67
|
+
var hasFinishedLoading = representation.index.isInitialized() &&
|
|
68
|
+
representation.index.isFinished() &&
|
|
69
|
+
neededRange.hasReachedPeriodEnd &&
|
|
68
70
|
prioritizedNeededSegments.length === 0 &&
|
|
69
71
|
segmentsOnHold.length === 0;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Start time in seconds of the next available not-yet pushed segment.
|
|
74
|
+
* `null` if no segment is wanted for the current wanted range.
|
|
75
|
+
*/
|
|
76
|
+
var nextSegmentStart = null;
|
|
77
|
+
if (segmentsBeingPushed.length > 0) {
|
|
78
|
+
nextSegmentStart = Math.min.apply(Math, segmentsBeingPushed.map(function (info) { return info.segment.time; }));
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (segmentsOnHold.length > 0) {
|
|
88
|
-
nextSegmentStart = nextSegmentStart !== null ?
|
|
89
|
-
Math.min(nextSegmentStart, segmentsOnHold[0].time) :
|
|
90
|
-
segmentsOnHold[0].time;
|
|
91
|
-
}
|
|
92
|
-
if (prioritizedNeededSegments.length > 0) {
|
|
93
|
-
nextSegmentStart = nextSegmentStart !== null ?
|
|
94
|
-
Math.min(nextSegmentStart, prioritizedNeededSegments[0].segment.time) :
|
|
95
|
-
prioritizedNeededSegments[0].segment.time;
|
|
96
|
-
}
|
|
97
|
-
imminentDiscontinuity = checkForDiscontinuity(content, neededRange, nextSegmentStart, hasFinishedLoading, bufferedSegments);
|
|
80
|
+
if (segmentsOnHold.length > 0) {
|
|
81
|
+
nextSegmentStart = nextSegmentStart !== null ?
|
|
82
|
+
Math.min(nextSegmentStart, segmentsOnHold[0].time) :
|
|
83
|
+
segmentsOnHold[0].time;
|
|
84
|
+
}
|
|
85
|
+
if (prioritizedNeededSegments.length > 0) {
|
|
86
|
+
nextSegmentStart = nextSegmentStart !== null ?
|
|
87
|
+
Math.min(nextSegmentStart, prioritizedNeededSegments[0].segment.time) :
|
|
88
|
+
prioritizedNeededSegments[0].segment.time;
|
|
98
89
|
}
|
|
90
|
+
var imminentDiscontinuity = checkForDiscontinuity(content, neededRange, nextSegmentStart, hasFinishedLoading, bufferedSegments);
|
|
99
91
|
return { imminentDiscontinuity: imminentDiscontinuity, hasFinishedLoading: hasFinishedLoading, neededSegments: prioritizedNeededSegments, isBufferFull: isBufferFull, shouldRefreshManifest: shouldRefreshManifest };
|
|
100
92
|
}
|
|
101
93
|
/**
|
|
@@ -111,7 +103,7 @@ function getRangeOfNeededSegments(content, initialWantedTime, bufferGoal) {
|
|
|
111
103
|
var _a;
|
|
112
104
|
var wantedStartPosition;
|
|
113
105
|
var manifest = content.manifest, period = content.period, representation = content.representation;
|
|
114
|
-
var lastIndexPosition = representation.index.
|
|
106
|
+
var lastIndexPosition = representation.index.getLastAvailablePosition();
|
|
115
107
|
var representationIndex = representation.index;
|
|
116
108
|
// There is an exception for when the current initially wanted time is already
|
|
117
109
|
// after the last position with segments AND when we're playing the absolute
|
|
@@ -22,14 +22,13 @@ import { IEncryptedMediaErrorCode } from "./error_codes";
|
|
|
22
22
|
*/
|
|
23
23
|
export default class EncryptedMediaError extends Error {
|
|
24
24
|
readonly name: "EncryptedMediaError";
|
|
25
|
-
readonly type:
|
|
25
|
+
readonly type: "ENCRYPTED_MEDIA_ERROR";
|
|
26
26
|
readonly code: IEncryptedMediaErrorCode;
|
|
27
27
|
message: string;
|
|
28
28
|
fatal: boolean;
|
|
29
29
|
/**
|
|
30
30
|
* @param {string} code
|
|
31
31
|
* @param {string} reason
|
|
32
|
-
* @Param {Boolean} fatal
|
|
33
32
|
*/
|
|
34
33
|
constructor(code: IEncryptedMediaErrorCode, reason: string);
|
|
35
34
|
}
|
|
@@ -20,7 +20,12 @@ export declare type INetworkErrorCode = "PIPELINE_LOAD_ERROR";
|
|
|
20
20
|
export declare type IOtherErrorCode = "PIPELINE_LOAD_ERROR" | "PIPELINE_PARSE_ERROR" | "INTEGRITY_ERROR" | "NONE";
|
|
21
21
|
export declare type IErrorCode = INetworkErrorCode | IMediaErrorCode | IEncryptedMediaErrorCode | IOtherErrorCode;
|
|
22
22
|
export declare type INetworkErrorType = "TIMEOUT" | "ERROR_EVENT" | "PARSE_ERROR" | "ERROR_HTTP_CODE";
|
|
23
|
-
declare const ErrorTypes:
|
|
23
|
+
declare const ErrorTypes: {
|
|
24
|
+
readonly NETWORK_ERROR: "NETWORK_ERROR";
|
|
25
|
+
readonly MEDIA_ERROR: "MEDIA_ERROR";
|
|
26
|
+
readonly ENCRYPTED_MEDIA_ERROR: "ENCRYPTED_MEDIA_ERROR";
|
|
27
|
+
readonly OTHER_ERROR: "OTHER_ERROR";
|
|
28
|
+
};
|
|
24
29
|
declare const NetworkErrorTypes: Record<INetworkErrorType, INetworkErrorType>;
|
|
25
30
|
declare const ErrorCodes: Record<IErrorCode, IErrorCode>;
|
|
26
31
|
export { ErrorTypes, NetworkErrorTypes, ErrorCodes, };
|
|
@@ -22,14 +22,13 @@ import { IMediaErrorCode } from "./error_codes";
|
|
|
22
22
|
*/
|
|
23
23
|
export default class MediaError extends Error {
|
|
24
24
|
readonly name: "MediaError";
|
|
25
|
-
readonly type:
|
|
25
|
+
readonly type: "MEDIA_ERROR";
|
|
26
26
|
readonly message: string;
|
|
27
27
|
readonly code: IMediaErrorCode;
|
|
28
28
|
fatal: boolean;
|
|
29
29
|
/**
|
|
30
30
|
* @param {string} code
|
|
31
31
|
* @param {string} reason
|
|
32
|
-
* @param {Boolean} fatal
|
|
33
32
|
*/
|
|
34
33
|
constructor(code: IMediaErrorCode, reason: string);
|
|
35
34
|
}
|
|
@@ -23,7 +23,7 @@ import RequestError from "./request_error";
|
|
|
23
23
|
*/
|
|
24
24
|
export default class NetworkError extends Error {
|
|
25
25
|
readonly name: "NetworkError";
|
|
26
|
-
readonly type:
|
|
26
|
+
readonly type: "NETWORK_ERROR";
|
|
27
27
|
readonly message: string;
|
|
28
28
|
readonly code: INetworkErrorCode;
|
|
29
29
|
readonly xhr: XMLHttpRequest | null;
|
|
@@ -34,7 +34,6 @@ export default class NetworkError extends Error {
|
|
|
34
34
|
/**
|
|
35
35
|
* @param {string} code
|
|
36
36
|
* @param {Error} baseError
|
|
37
|
-
* @param {Boolean} fatal
|
|
38
37
|
*/
|
|
39
38
|
constructor(code: INetworkErrorCode, baseError: RequestError);
|
|
40
39
|
/**
|
|
@@ -20,14 +20,13 @@ import { IOtherErrorCode } from "./error_codes";
|
|
|
20
20
|
*/
|
|
21
21
|
export default class OtherError extends Error {
|
|
22
22
|
readonly name: "OtherError";
|
|
23
|
-
readonly type:
|
|
23
|
+
readonly type: "OTHER_ERROR";
|
|
24
24
|
readonly message: string;
|
|
25
25
|
readonly code: IOtherErrorCode;
|
|
26
26
|
fatal: boolean;
|
|
27
27
|
/**
|
|
28
28
|
* @param {string} code
|
|
29
29
|
* @param {string} reason
|
|
30
|
-
* @param {Boolean} fatal
|
|
31
30
|
*/
|
|
32
31
|
constructor(code: IOtherErrorCode, reason: string);
|
|
33
32
|
}
|
|
@@ -277,7 +277,7 @@ export default class Manifest extends EventEmitter<IManifestEvents> {
|
|
|
277
277
|
* and mark them as being impossible to decrypt.
|
|
278
278
|
* Then trigger a "decipherabilityUpdate" event to notify everyone of the
|
|
279
279
|
* changes performed.
|
|
280
|
-
* @param {
|
|
280
|
+
* @param {Function} isDecipherableCb
|
|
281
281
|
*/
|
|
282
282
|
updateRepresentationsDeciperability(isDecipherableCb: (rep: Representation) => boolean | undefined): void;
|
|
283
283
|
/**
|
|
@@ -251,7 +251,7 @@ var Manifest = /** @class */ (function (_super) {
|
|
|
251
251
|
* and mark them as being impossible to decrypt.
|
|
252
252
|
* Then trigger a "decipherabilityUpdate" event to notify everyone of the
|
|
253
253
|
* changes performed.
|
|
254
|
-
* @param {
|
|
254
|
+
* @param {Function} isDecipherableCb
|
|
255
255
|
*/
|
|
256
256
|
Manifest.prototype.updateRepresentationsDeciperability = function (isDecipherableCb) {
|
|
257
257
|
var updates = updateDeciperability(this, isDecipherableCb);
|
|
@@ -43,12 +43,31 @@ export default class StaticRepresentationIndex implements IRepresentationIndex {
|
|
|
43
43
|
* Returns first position in index.
|
|
44
44
|
* @returns {undefined}
|
|
45
45
|
*/
|
|
46
|
-
|
|
46
|
+
getFirstAvailablePosition(): undefined;
|
|
47
47
|
/**
|
|
48
48
|
* Returns last position in index.
|
|
49
49
|
* @returns {undefined}
|
|
50
50
|
*/
|
|
51
|
-
|
|
51
|
+
getLastAvailablePosition(): undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Returns the absolute end in seconds this RepresentationIndex can reach once
|
|
54
|
+
* all segments are available.
|
|
55
|
+
* @returns {number|null|undefined}
|
|
56
|
+
*/
|
|
57
|
+
getEnd(): undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Returns:
|
|
60
|
+
* - `true` if in the given time interval, at least one new segment is
|
|
61
|
+
* expected to be available in the future.
|
|
62
|
+
* - `false` either if all segments in that time interval are already
|
|
63
|
+
* available for download or if none will ever be available for it.
|
|
64
|
+
* - `undefined` when it is not possible to tell.
|
|
65
|
+
*
|
|
66
|
+
* Always `false` in a `StaticRepresentationIndex` because all segments should
|
|
67
|
+
* be directly available.
|
|
68
|
+
* @returns {boolean}
|
|
69
|
+
*/
|
|
70
|
+
awaitSegmentBetween(): false;
|
|
52
71
|
/**
|
|
53
72
|
* Returns false as a static file never need to be refreshed.
|
|
54
73
|
* @returns {Boolean}
|
|
@@ -58,10 +77,6 @@ export default class StaticRepresentationIndex implements IRepresentationIndex {
|
|
|
58
77
|
* @returns {null}
|
|
59
78
|
*/
|
|
60
79
|
checkDiscontinuity(): null;
|
|
61
|
-
/**
|
|
62
|
-
* @returns {boolean}
|
|
63
|
-
*/
|
|
64
|
-
areSegmentsChronologicallyGenerated(): boolean;
|
|
65
80
|
/**
|
|
66
81
|
* Returns true as a static file should never need lose availability.
|
|
67
82
|
* @returns {Boolean}
|
|
@@ -46,22 +46,46 @@ var StaticRepresentationIndex = /** @class */ (function () {
|
|
|
46
46
|
end: Number.MAX_VALUE,
|
|
47
47
|
duration: Number.MAX_VALUE,
|
|
48
48
|
complete: true,
|
|
49
|
+
privateInfos: {},
|
|
49
50
|
timescale: 1 }];
|
|
50
51
|
};
|
|
51
52
|
/**
|
|
52
53
|
* Returns first position in index.
|
|
53
54
|
* @returns {undefined}
|
|
54
55
|
*/
|
|
55
|
-
StaticRepresentationIndex.prototype.
|
|
56
|
+
StaticRepresentationIndex.prototype.getFirstAvailablePosition = function () {
|
|
56
57
|
return;
|
|
57
58
|
};
|
|
58
59
|
/**
|
|
59
60
|
* Returns last position in index.
|
|
60
61
|
* @returns {undefined}
|
|
61
62
|
*/
|
|
62
|
-
StaticRepresentationIndex.prototype.
|
|
63
|
+
StaticRepresentationIndex.prototype.getLastAvailablePosition = function () {
|
|
63
64
|
return;
|
|
64
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Returns the absolute end in seconds this RepresentationIndex can reach once
|
|
68
|
+
* all segments are available.
|
|
69
|
+
* @returns {number|null|undefined}
|
|
70
|
+
*/
|
|
71
|
+
StaticRepresentationIndex.prototype.getEnd = function () {
|
|
72
|
+
return;
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Returns:
|
|
76
|
+
* - `true` if in the given time interval, at least one new segment is
|
|
77
|
+
* expected to be available in the future.
|
|
78
|
+
* - `false` either if all segments in that time interval are already
|
|
79
|
+
* available for download or if none will ever be available for it.
|
|
80
|
+
* - `undefined` when it is not possible to tell.
|
|
81
|
+
*
|
|
82
|
+
* Always `false` in a `StaticRepresentationIndex` because all segments should
|
|
83
|
+
* be directly available.
|
|
84
|
+
* @returns {boolean}
|
|
85
|
+
*/
|
|
86
|
+
StaticRepresentationIndex.prototype.awaitSegmentBetween = function () {
|
|
87
|
+
return false;
|
|
88
|
+
};
|
|
65
89
|
/**
|
|
66
90
|
* Returns false as a static file never need to be refreshed.
|
|
67
91
|
* @returns {Boolean}
|
|
@@ -75,12 +99,6 @@ var StaticRepresentationIndex = /** @class */ (function () {
|
|
|
75
99
|
StaticRepresentationIndex.prototype.checkDiscontinuity = function () {
|
|
76
100
|
return null;
|
|
77
101
|
};
|
|
78
|
-
/**
|
|
79
|
-
* @returns {boolean}
|
|
80
|
-
*/
|
|
81
|
-
StaticRepresentationIndex.prototype.areSegmentsChronologicallyGenerated = function () {
|
|
82
|
-
return true;
|
|
83
|
-
};
|
|
84
102
|
/**
|
|
85
103
|
* Returns true as a static file should never need lose availability.
|
|
86
104
|
* @returns {Boolean}
|
|
@@ -99,11 +99,23 @@ export interface ILocalManifestSegmentPrivateInfos {
|
|
|
99
99
|
* exploited by the corresponding transport logic.
|
|
100
100
|
*/
|
|
101
101
|
export interface IPrivateInfos {
|
|
102
|
+
/** Smooth-specific information allowing to generate an initialization segment. */
|
|
102
103
|
smoothInitSegment?: ISmoothInitSegmentPrivateInfos | undefined;
|
|
104
|
+
/** Smooth-specific information linked to all Smooth media segments. */
|
|
103
105
|
smoothMediaSegment?: ISmoothSegmentPrivateInfos | undefined;
|
|
106
|
+
/** Information that should be present on all MetaPlaylist segments. */
|
|
104
107
|
metaplaylistInfos?: IMetaPlaylistPrivateInfos | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Local Manifest-specific information allowing to request the
|
|
110
|
+
* initialization segment.
|
|
111
|
+
*/
|
|
105
112
|
localManifestInitSegment?: ILocalManifestInitSegmentPrivateInfos | undefined;
|
|
113
|
+
/** Local Manifest-specific information allowing to request any media segment. */
|
|
106
114
|
localManifestSegment?: ILocalManifestSegmentPrivateInfos | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Function allowing to know if a given emsg's event name has been
|
|
117
|
+
* explicitely authorized.
|
|
118
|
+
*/
|
|
107
119
|
isEMSGWhitelisted?: ((evt: IEMSG) => boolean) | undefined;
|
|
108
120
|
}
|
|
109
121
|
/** Represent a single Segment from a Representation. */
|
|
@@ -128,26 +140,16 @@ export interface ISegment {
|
|
|
128
140
|
* segments" in the code.
|
|
129
141
|
*/
|
|
130
142
|
isInit: boolean;
|
|
131
|
-
/** URLs where this segment is available. From the most to least prioritary. */
|
|
132
|
-
mediaURLs: string[] | null;
|
|
133
|
-
/**
|
|
134
|
-
* If set, the corresponding byte-range in the downloaded segment will
|
|
135
|
-
* contain an index describing other Segments
|
|
136
|
-
* TODO put in privateInfos?
|
|
137
|
-
*/
|
|
138
|
-
indexRange?: [number, number] | undefined;
|
|
139
143
|
/**
|
|
140
|
-
*
|
|
141
|
-
*
|
|
144
|
+
* URLs where this segment is available. From the most to least prioritary.
|
|
145
|
+
* `null` if no URL exists.
|
|
142
146
|
*/
|
|
143
|
-
|
|
147
|
+
mediaURLs: string[] | null;
|
|
144
148
|
/**
|
|
145
149
|
* Allows to store supplementary information on a segment that can be later
|
|
146
150
|
* exploited by the transport logic.
|
|
147
151
|
*/
|
|
148
|
-
privateInfos
|
|
149
|
-
/** Optional byte range to retrieve the Segment from its URL(s) */
|
|
150
|
-
range?: [number, number] | undefined;
|
|
152
|
+
privateInfos: IPrivateInfos | undefined;
|
|
151
153
|
/**
|
|
152
154
|
* Estimated time, in seconds, at which the concerned segment should be
|
|
153
155
|
* offseted when decoded.
|
|
@@ -209,6 +211,31 @@ export interface ISegment {
|
|
|
209
211
|
* generated.
|
|
210
212
|
*/
|
|
211
213
|
complete: boolean;
|
|
214
|
+
/**
|
|
215
|
+
* Optional byte range to retrieve the Segment from its URL(s).
|
|
216
|
+
* TODO this should probably moved to `privateInfos` as this is
|
|
217
|
+
* transport-specific metadata only useful for performing requests, but it is
|
|
218
|
+
* sadly documented in the API, so moving it is actuall a v3.X.X breaking
|
|
219
|
+
* change.
|
|
220
|
+
*/
|
|
221
|
+
range?: [number, number] | undefined;
|
|
222
|
+
/**
|
|
223
|
+
* If set, the corresponding byte-range in the downloaded segment will
|
|
224
|
+
* contain an index describing other Segments
|
|
225
|
+
* TODO this should probably moved to `privateInfos` as this is
|
|
226
|
+
* transport-specific metadata only useful for performing requests, but it is
|
|
227
|
+
* sadly documented in the API, so moving it is actuall a v3.X.X breaking
|
|
228
|
+
* change.
|
|
229
|
+
*/
|
|
230
|
+
indexRange?: [number, number] | undefined;
|
|
231
|
+
/**
|
|
232
|
+
* Optional number of the Segment.
|
|
233
|
+
* TODO this should probably moved to `privateInfos` as this is
|
|
234
|
+
* transport-specific metadata only useful for performing requests, but it is
|
|
235
|
+
* sadly documented in the API, so moving it is actuall a v3.X.X breaking
|
|
236
|
+
* change.
|
|
237
|
+
*/
|
|
238
|
+
number?: number | undefined;
|
|
212
239
|
}
|
|
213
240
|
/** Interface that should be implemented by any Representation's `index` value. */
|
|
214
241
|
export interface IRepresentationIndex {
|
|
@@ -246,7 +273,7 @@ export interface IRepresentationIndex {
|
|
|
246
273
|
* Returns `undefined` if we cannot know this value.
|
|
247
274
|
* @returns {Number|null}
|
|
248
275
|
*/
|
|
249
|
-
|
|
276
|
+
getFirstAvailablePosition(): number | null | undefined;
|
|
250
277
|
/**
|
|
251
278
|
* Returns the ending time, in seconds, of the last playable position
|
|
252
279
|
* currently available in this index.
|
|
@@ -259,7 +286,18 @@ export interface IRepresentationIndex {
|
|
|
259
286
|
* instead.
|
|
260
287
|
* @returns {Number|null|undefined}
|
|
261
288
|
*/
|
|
262
|
-
|
|
289
|
+
getLastAvailablePosition(): number | null | undefined;
|
|
290
|
+
/**
|
|
291
|
+
* Returns the ending time, in seconds, of the Representation once it is
|
|
292
|
+
* "finished" (@see isFinished).
|
|
293
|
+
* Should thus be equivalent to `getLastAvailablePosition` once finished.
|
|
294
|
+
*
|
|
295
|
+
* Returns `null` if nothing is in the index
|
|
296
|
+
* Returns `undefined` if we cannot know this value.
|
|
297
|
+
*
|
|
298
|
+
* @returns {number|undefined}
|
|
299
|
+
*/
|
|
300
|
+
getEnd(): number | null | undefined;
|
|
263
301
|
/**
|
|
264
302
|
* Returns `true` if a Segment returned by this index is still considered
|
|
265
303
|
* available.
|
|
@@ -298,34 +336,6 @@ export interface IRepresentationIndex {
|
|
|
298
336
|
* position for which a segment is available in seconds.
|
|
299
337
|
*/
|
|
300
338
|
checkDiscontinuity(time: number): number | null;
|
|
301
|
-
/**
|
|
302
|
-
* Most RepresentationIndex are linked to segments which are generated in
|
|
303
|
-
* chronological order: from an initial position (obtainable with
|
|
304
|
-
* `getFirstPosition`) to the last position of the corresponding Period
|
|
305
|
-
* (obtainable with `getLastPosition`).
|
|
306
|
-
*
|
|
307
|
-
* However, some RepresentationIndex could announce segments in a more random
|
|
308
|
-
* order.
|
|
309
|
-
* Examples of such RepresentationIndex are ones for contents which are being
|
|
310
|
-
* downloaded locally. Here a seek close to the end could schedule the
|
|
311
|
-
* download of the last segments immediately, which might thus be announced
|
|
312
|
-
* in this index before segments in the middle are.
|
|
313
|
-
*
|
|
314
|
-
* Knowing this value serves for example to check if a discontinuity
|
|
315
|
-
* encountered in the content can be skipped over, or if it's possible that
|
|
316
|
-
* this discontinuity is due to a segment not yet being generated.
|
|
317
|
-
*
|
|
318
|
-
* You should return `true` only if there is a chance that segments are not
|
|
319
|
-
* chronologically generated (even if they all have since been generated, this
|
|
320
|
-
* function is only to know if it's possible, not if it's the case now).
|
|
321
|
-
*
|
|
322
|
-
* In other most likely cases, you should return `false`.
|
|
323
|
-
*
|
|
324
|
-
* TODO find a better way with the "local" RepresentationIndex, like
|
|
325
|
-
* explicitely declaring which segments have not been downloaded yet.
|
|
326
|
-
* @returns {boolean}
|
|
327
|
-
*/
|
|
328
|
-
areSegmentsChronologicallyGenerated(): boolean;
|
|
329
339
|
/**
|
|
330
340
|
* Returns `true` if the last segments in this index have already been
|
|
331
341
|
* generated so that we can freely go to the next period.
|
|
@@ -355,6 +365,7 @@ export interface IRepresentationIndex {
|
|
|
355
365
|
* @returns {boolean}
|
|
356
366
|
*/
|
|
357
367
|
isInitialized(): boolean;
|
|
368
|
+
awaitSegmentBetween(start: number, end: number): boolean | undefined;
|
|
358
369
|
/**
|
|
359
370
|
* Replace the index with another one, such as after a Manifest update.
|
|
360
371
|
* @param {Object} newIndex
|
|
@@ -154,12 +154,31 @@ export default class BaseRepresentationIndex implements IRepresentationIndex {
|
|
|
154
154
|
* Returns first position in index.
|
|
155
155
|
* @returns {Number|null}
|
|
156
156
|
*/
|
|
157
|
-
|
|
157
|
+
getFirstAvailablePosition(): number | null;
|
|
158
158
|
/**
|
|
159
159
|
* Returns last position in index.
|
|
160
160
|
* @returns {Number|null}
|
|
161
161
|
*/
|
|
162
|
-
|
|
162
|
+
getLastAvailablePosition(): number | null;
|
|
163
|
+
/**
|
|
164
|
+
* Returns the absolute end in seconds this RepresentationIndex can reach once
|
|
165
|
+
* all segments are available.
|
|
166
|
+
* @returns {number|null|undefined}
|
|
167
|
+
*/
|
|
168
|
+
getEnd(): number | null;
|
|
169
|
+
/**
|
|
170
|
+
* Returns:
|
|
171
|
+
* - `true` if in the given time interval, at least one new segment is
|
|
172
|
+
* expected to be available in the future.
|
|
173
|
+
* - `false` either if all segments in that time interval are already
|
|
174
|
+
* available for download or if none will ever be available for it.
|
|
175
|
+
* - `undefined` when it is not possible to tell.
|
|
176
|
+
*
|
|
177
|
+
* Always `false` in a `BaseRepresentationIndex` because all segments should
|
|
178
|
+
* be directly available.
|
|
179
|
+
* @returns {boolean}
|
|
180
|
+
*/
|
|
181
|
+
awaitSegmentBetween(): false;
|
|
163
182
|
/**
|
|
164
183
|
* Segments in a segmentBase scheme should stay available.
|
|
165
184
|
* @returns {Boolean|undefined}
|
|
@@ -170,12 +189,6 @@ export default class BaseRepresentationIndex implements IRepresentationIndex {
|
|
|
170
189
|
* @returns {null}
|
|
171
190
|
*/
|
|
172
191
|
checkDiscontinuity(): null;
|
|
173
|
-
/**
|
|
174
|
-
* `BaseRepresentationIndex` should just already all be generated.
|
|
175
|
-
* Return `true` as a default value here.
|
|
176
|
-
* @returns {boolean}
|
|
177
|
-
*/
|
|
178
|
-
areSegmentsChronologicallyGenerated(): true;
|
|
179
192
|
/**
|
|
180
193
|
* No segment in a `BaseRepresentationIndex` are known initially.
|
|
181
194
|
* It is only defined generally in an "index segment" that will thus need to
|
|
@@ -118,7 +118,7 @@ var BaseRepresentationIndex = /** @class */ (function () {
|
|
|
118
118
|
* Returns first position in index.
|
|
119
119
|
* @returns {Number|null}
|
|
120
120
|
*/
|
|
121
|
-
BaseRepresentationIndex.prototype.
|
|
121
|
+
BaseRepresentationIndex.prototype.getFirstAvailablePosition = function () {
|
|
122
122
|
var index = this._index;
|
|
123
123
|
if (index.timeline.length === 0) {
|
|
124
124
|
return null;
|
|
@@ -129,7 +129,7 @@ var BaseRepresentationIndex = /** @class */ (function () {
|
|
|
129
129
|
* Returns last position in index.
|
|
130
130
|
* @returns {Number|null}
|
|
131
131
|
*/
|
|
132
|
-
BaseRepresentationIndex.prototype.
|
|
132
|
+
BaseRepresentationIndex.prototype.getLastAvailablePosition = function () {
|
|
133
133
|
var _a;
|
|
134
134
|
var timeline = this._index.timeline;
|
|
135
135
|
if (timeline.length === 0) {
|
|
@@ -139,6 +139,29 @@ var BaseRepresentationIndex = /** @class */ (function () {
|
|
|
139
139
|
var lastTime = Math.min(getIndexSegmentEnd(lastTimelineElement, null, this._scaledPeriodEnd), (_a = this._scaledPeriodEnd) !== null && _a !== void 0 ? _a : Infinity);
|
|
140
140
|
return fromIndexTime(lastTime, this._index);
|
|
141
141
|
};
|
|
142
|
+
/**
|
|
143
|
+
* Returns the absolute end in seconds this RepresentationIndex can reach once
|
|
144
|
+
* all segments are available.
|
|
145
|
+
* @returns {number|null|undefined}
|
|
146
|
+
*/
|
|
147
|
+
BaseRepresentationIndex.prototype.getEnd = function () {
|
|
148
|
+
return this.getLastAvailablePosition();
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Returns:
|
|
152
|
+
* - `true` if in the given time interval, at least one new segment is
|
|
153
|
+
* expected to be available in the future.
|
|
154
|
+
* - `false` either if all segments in that time interval are already
|
|
155
|
+
* available for download or if none will ever be available for it.
|
|
156
|
+
* - `undefined` when it is not possible to tell.
|
|
157
|
+
*
|
|
158
|
+
* Always `false` in a `BaseRepresentationIndex` because all segments should
|
|
159
|
+
* be directly available.
|
|
160
|
+
* @returns {boolean}
|
|
161
|
+
*/
|
|
162
|
+
BaseRepresentationIndex.prototype.awaitSegmentBetween = function () {
|
|
163
|
+
return false;
|
|
164
|
+
};
|
|
142
165
|
/**
|
|
143
166
|
* Segments in a segmentBase scheme should stay available.
|
|
144
167
|
* @returns {Boolean|undefined}
|
|
@@ -153,14 +176,6 @@ var BaseRepresentationIndex = /** @class */ (function () {
|
|
|
153
176
|
BaseRepresentationIndex.prototype.checkDiscontinuity = function () {
|
|
154
177
|
return null;
|
|
155
178
|
};
|
|
156
|
-
/**
|
|
157
|
-
* `BaseRepresentationIndex` should just already all be generated.
|
|
158
|
-
* Return `true` as a default value here.
|
|
159
|
-
* @returns {boolean}
|
|
160
|
-
*/
|
|
161
|
-
BaseRepresentationIndex.prototype.areSegmentsChronologicallyGenerated = function () {
|
|
162
|
-
return true;
|
|
163
|
-
};
|
|
164
179
|
/**
|
|
165
180
|
* No segment in a `BaseRepresentationIndex` are known initially.
|
|
166
181
|
* It is only defined generally in an "index segment" that will thus need to
|
|
@@ -36,7 +36,10 @@ export interface IListIndex {
|
|
|
36
36
|
} | undefined;
|
|
37
37
|
/** Information on the list of segments for this index. */
|
|
38
38
|
list: Array<{
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* URLs of the segment.
|
|
41
|
+
* `null` if no URL exists.
|
|
42
|
+
*/
|
|
40
43
|
mediaURLs: string[] | null;
|
|
41
44
|
/** Possible byte-range of the segment. */
|
|
42
45
|
mediaRange?: [number, number] | undefined;
|
|
@@ -114,7 +117,7 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
114
117
|
getInitSegment(): ISegment;
|
|
115
118
|
/**
|
|
116
119
|
* @param {Number} fromTime
|
|
117
|
-
* @param {Number}
|
|
120
|
+
* @param {Number} dur
|
|
118
121
|
* @returns {Array.<Object>}
|
|
119
122
|
*/
|
|
120
123
|
getSegments(fromTime: number, dur: number): ISegment[];
|
|
@@ -131,16 +134,34 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
131
134
|
* Returns first position in this index, in seconds.
|
|
132
135
|
* @returns {Number}
|
|
133
136
|
*/
|
|
134
|
-
|
|
137
|
+
getFirstAvailablePosition(): number;
|
|
135
138
|
/**
|
|
136
139
|
* Returns last position in this index, in seconds.
|
|
137
140
|
* @returns {Number}
|
|
138
141
|
*/
|
|
139
|
-
|
|
142
|
+
getLastAvailablePosition(): number;
|
|
143
|
+
/**
|
|
144
|
+
* Returns the absolute end in seconds this RepresentationIndex can reach once
|
|
145
|
+
* all segments are available.
|
|
146
|
+
* @returns {number|null|undefined}
|
|
147
|
+
*/
|
|
148
|
+
getEnd(): number | null;
|
|
149
|
+
/**
|
|
150
|
+
* Returns:
|
|
151
|
+
* - `true` if in the given time interval, at least one new segment is
|
|
152
|
+
* expected to be available in the future.
|
|
153
|
+
* - `false` either if all segments in that time interval are already
|
|
154
|
+
* available for download or if none will ever be available for it.
|
|
155
|
+
* - `undefined` when it is not possible to tell.
|
|
156
|
+
*
|
|
157
|
+
* Always `false` in a `ListRepresentationIndex` because all segments should
|
|
158
|
+
* be directly available.
|
|
159
|
+
* @returns {boolean}
|
|
160
|
+
*/
|
|
161
|
+
awaitSegmentBetween(): false;
|
|
140
162
|
/**
|
|
141
163
|
* Returns true if a Segment returned by this index is still considered
|
|
142
164
|
* available.
|
|
143
|
-
* @param {Object} segment
|
|
144
165
|
* @returns {Boolean}
|
|
145
166
|
*/
|
|
146
167
|
isSegmentStillAvailable(): true;
|
|
@@ -149,10 +170,6 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
149
170
|
* @returns {null}
|
|
150
171
|
*/
|
|
151
172
|
checkDiscontinuity(): null;
|
|
152
|
-
/**
|
|
153
|
-
* @returns {boolean}
|
|
154
|
-
*/
|
|
155
|
-
areSegmentsChronologicallyGenerated(): boolean;
|
|
156
173
|
/**
|
|
157
174
|
* SegmentList should not be updated.
|
|
158
175
|
* @returns {Boolean}
|
|
@@ -170,8 +187,5 @@ export default class ListRepresentationIndex implements IRepresentationIndex {
|
|
|
170
187
|
* @param {Object} newIndex
|
|
171
188
|
*/
|
|
172
189
|
_replace(newIndex: ListRepresentationIndex): void;
|
|
173
|
-
/**
|
|
174
|
-
* @param {Object} newIndex
|
|
175
|
-
*/
|
|
176
190
|
_update(): void;
|
|
177
191
|
}
|