rx-player 3.30.0-dev.2023020100 → 3.30.0-dev.2023030200
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/.eslintrc.js +8 -0
- package/CHANGELOG.md +5 -1
- package/VERSION +1 -1
- package/dist/_esm5.processed/compat/browser_detection.d.ts +23 -12
- package/dist/_esm5.processed/compat/browser_detection.js +80 -38
- package/dist/_esm5.processed/compat/can_reuse_media_keys.js +2 -2
- package/dist/_esm5.processed/compat/eme/close_session.js +2 -2
- package/dist/_esm5.processed/compat/event_listeners.js +1 -1
- package/dist/_esm5.processed/config.d.ts +2 -0
- package/dist/_esm5.processed/core/adaptive/adaptive_representation_selector.js +4 -2
- package/dist/_esm5.processed/core/api/debug/buffer_graph.d.ts +28 -0
- package/dist/_esm5.processed/core/api/debug/buffer_graph.js +175 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.d.ts +10 -0
- package/dist/_esm5.processed/core/api/debug/buffer_size_graph.js +104 -0
- package/dist/_esm5.processed/core/api/debug/constants.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/constants.js +2 -0
- package/dist/_esm5.processed/core/api/debug/index.d.ts +2 -0
- package/dist/_esm5.processed/core/api/debug/index.js +2 -0
- package/dist/_esm5.processed/core/api/debug/modules/general_info.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/modules/general_info.js +199 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.d.ts +4 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_content.js +121 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/modules/segment_buffer_size.js +35 -0
- package/dist/_esm5.processed/core/api/debug/render.d.ts +3 -0
- package/dist/_esm5.processed/core/api/debug/render.js +32 -0
- package/dist/_esm5.processed/core/api/debug/utils.d.ts +39 -0
- package/dist/_esm5.processed/core/api/debug/utils.js +57 -0
- package/dist/_esm5.processed/core/api/playback_observer.js +3 -2
- package/dist/_esm5.processed/core/api/public_api.d.ts +3 -0
- package/dist/_esm5.processed/core/api/public_api.js +25 -14
- package/dist/_esm5.processed/core/api/utils.js +3 -3
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.d.ts +32 -13
- package/dist/_esm5.processed/core/decrypt/__tests__/__global__/utils.js +28 -7
- package/dist/_esm5.processed/core/decrypt/attach_media_keys.js +1 -1
- package/dist/_esm5.processed/core/decrypt/content_decryptor.js +1 -1
- package/dist/_esm5.processed/core/decrypt/find_key_system.js +33 -24
- package/dist/_esm5.processed/core/decrypt/session_events_listener.js +54 -50
- package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +4 -0
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.d.ts +17 -8
- package/dist/_esm5.processed/core/fetchers/cdn_prioritizer.js +10 -6
- package/dist/_esm5.processed/core/fetchers/manifest/manifest_fetcher.js +5 -4
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +22 -5
- package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +37 -21
- package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +21 -23
- package/dist/_esm5.processed/core/fetchers/utils/schedule_request.js +17 -7
- package/dist/_esm5.processed/core/init/directfile_content_initializer.js +1 -1
- package/dist/_esm5.processed/core/init/media_source_content_initializer.js +27 -31
- package/dist/_esm5.processed/core/init/utils/content_time_boundaries_observer.js +2 -2
- package/dist/_esm5.processed/core/init/utils/create_media_source.js +3 -12
- package/dist/_esm5.processed/core/init/utils/end_of_stream.js +6 -3
- package/dist/_esm5.processed/core/init/utils/get_loaded_reference.js +2 -1
- package/dist/_esm5.processed/core/init/utils/initial_seek_and_play.js +9 -5
- package/dist/_esm5.processed/core/init/utils/initialize_content_decryption.js +2 -1
- package/dist/_esm5.processed/core/init/utils/media_duration_updater.js +23 -19
- package/dist/_esm5.processed/core/init/utils/rebuffering_controller.js +1 -1
- package/dist/_esm5.processed/core/init/utils/stream_events_emitter/stream_events_emitter.js +6 -4
- package/dist/_esm5.processed/core/init/utils/throw_on_media_error.js +1 -1
- package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +7 -10
- package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +4 -2
- package/dist/_esm5.processed/core/segment_buffers/segment_buffers_store.js +13 -9
- package/dist/_esm5.processed/core/stream/adaptation/adaptation_stream.js +25 -16
- package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +26 -12
- package/dist/_esm5.processed/core/stream/period/period_stream.js +11 -10
- package/dist/_esm5.processed/core/stream/representation/representation_stream.js +15 -15
- package/dist/_esm5.processed/core/stream/representation/utils/append_segment_to_buffer.js +1 -1
- package/dist/_esm5.processed/core/stream/representation/utils/downloading_queue.js +16 -6
- package/dist/_esm5.processed/default_config.d.ts +16 -0
- package/dist/_esm5.processed/default_config.js +19 -0
- package/dist/_esm5.processed/experimental/features/debug_element.d.ts +8 -0
- package/dist/_esm5.processed/experimental/features/debug_element.js +10 -0
- package/dist/_esm5.processed/experimental/features/index.d.ts +1 -0
- package/dist/_esm5.processed/experimental/features/index.js +1 -0
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +7 -4
- package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +8 -4
- package/dist/_esm5.processed/features/features_object.js +1 -0
- package/dist/_esm5.processed/features/initialize_features.js +13 -10
- package/dist/_esm5.processed/features/types.d.ts +3 -0
- package/dist/_esm5.processed/manifest/adaptation.js +4 -0
- package/dist/_esm5.processed/manifest/manifest.js +2 -0
- package/dist/_esm5.processed/manifest/representation.js +11 -4
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_adaptation_sets.js +105 -137
- package/dist/_esm5.processed/parsers/manifest/dash/common/parse_representations.js +25 -5
- package/dist/_esm5.processed/public_types.d.ts +1 -0
- package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +15 -11
- package/dist/_esm5.processed/transports/dash/low_latency_segment_loader.js +2 -2
- package/dist/_esm5.processed/transports/dash/manifest_parser.js +1 -1
- package/dist/_esm5.processed/transports/dash/segment_loader.js +4 -4
- package/dist/_esm5.processed/transports/local/segment_loader.js +13 -26
- package/dist/_esm5.processed/transports/smooth/segment_loader.js +4 -4
- package/dist/_esm5.processed/transports/utils/call_custom_manifest_loader.js +3 -3
- package/dist/_esm5.processed/utils/cancellable_sleep.js +4 -10
- package/dist/_esm5.processed/utils/create_cancellable_promise.d.ts +26 -0
- package/dist/_esm5.processed/utils/create_cancellable_promise.js +52 -0
- package/dist/_esm5.processed/utils/reference.js +6 -0
- package/dist/_esm5.processed/utils/request/xhr.js +1 -1
- package/dist/_esm5.processed/utils/task_canceller.d.ts +34 -15
- package/dist/_esm5.processed/utils/task_canceller.js +55 -22
- package/dist/rx-player.js +880 -677
- package/dist/rx-player.min.js +1 -1
- package/jest.config.js +1 -0
- package/package.json +19 -18
- package/scripts/build/constants.d.ts +1 -0
- package/scripts/report_build_sizes +4 -0
- package/sonar-project.properties +1 -1
- package/src/compat/browser_detection.ts +99 -52
- package/src/compat/can_reuse_media_keys.ts +5 -2
- package/src/compat/eme/close_session.ts +2 -2
- package/src/compat/event_listeners.ts +1 -1
- package/src/core/adaptive/adaptive_representation_selector.ts +4 -2
- package/src/core/api/debug/buffer_graph.ts +247 -0
- package/src/core/api/debug/buffer_size_graph.ts +130 -0
- package/src/core/api/debug/constants.ts +2 -0
- package/src/core/api/debug/index.ts +3 -0
- package/src/core/api/debug/modules/general_info.ts +204 -0
- package/src/core/api/debug/modules/segment_buffer_content.ts +155 -0
- package/src/core/api/debug/modules/segment_buffer_size.ts +48 -0
- package/src/core/api/debug/render.ts +40 -0
- package/src/core/api/debug/utils.ts +103 -0
- package/src/core/api/playback_observer.ts +4 -2
- package/src/core/api/public_api.ts +28 -14
- package/src/core/api/utils.ts +3 -3
- package/src/core/decrypt/__tests__/__global__/utils.ts +61 -40
- package/src/core/decrypt/attach_media_keys.ts +1 -1
- package/src/core/decrypt/content_decryptor.ts +1 -1
- package/src/core/decrypt/find_key_system.ts +36 -35
- package/src/core/decrypt/session_events_listener.ts +57 -56
- package/src/core/decrypt/utils/check_key_statuses.ts +6 -0
- package/src/core/fetchers/cdn_prioritizer.ts +18 -9
- package/src/core/fetchers/manifest/manifest_fetcher.ts +5 -4
- package/src/core/fetchers/segment/segment_fetcher.ts +36 -14
- package/src/core/fetchers/segment/task_prioritizer.ts +25 -30
- package/src/core/fetchers/utils/schedule_request.ts +18 -7
- package/src/core/init/directfile_content_initializer.ts +1 -1
- package/src/core/init/media_source_content_initializer.ts +37 -41
- package/src/core/init/utils/content_time_boundaries_observer.ts +2 -2
- package/src/core/init/utils/create_media_source.ts +4 -16
- package/src/core/init/utils/end_of_stream.ts +6 -3
- package/src/core/init/utils/get_loaded_reference.ts +2 -1
- package/src/core/init/utils/initial_seek_and_play.ts +9 -5
- package/src/core/init/utils/initialize_content_decryption.ts +2 -1
- package/src/core/init/utils/media_duration_updater.ts +25 -20
- package/src/core/init/utils/rebuffering_controller.ts +1 -1
- package/src/core/init/utils/stream_events_emitter/stream_events_emitter.ts +6 -4
- package/src/core/init/utils/throw_on_media_error.ts +1 -1
- package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +7 -11
- package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +4 -2
- package/src/core/segment_buffers/segment_buffers_store.ts +16 -13
- package/src/core/stream/adaptation/adaptation_stream.ts +28 -19
- package/src/core/stream/orchestrator/stream_orchestrator.ts +26 -12
- package/src/core/stream/period/period_stream.ts +11 -10
- package/src/core/stream/representation/representation_stream.ts +15 -15
- package/src/core/stream/representation/utils/append_segment_to_buffer.ts +1 -1
- package/src/core/stream/representation/utils/downloading_queue.ts +16 -4
- package/src/default_config.ts +30 -9
- package/src/experimental/features/__tests__/debug_element.test.ts +26 -0
- package/src/experimental/features/debug_element.ts +13 -0
- package/src/experimental/features/index.ts +1 -0
- package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +7 -4
- package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +8 -4
- package/src/features/__tests__/initialize_features.test.ts +11 -0
- package/src/features/features_object.ts +1 -0
- package/src/features/initialize_features.ts +15 -10
- package/src/features/types.ts +9 -0
- package/src/manifest/adaptation.ts +7 -0
- package/src/manifest/manifest.ts +4 -0
- package/src/manifest/representation.ts +10 -4
- package/src/parsers/manifest/dash/common/parse_adaptation_sets.ts +116 -151
- package/src/parsers/manifest/dash/common/parse_representations.ts +21 -4
- package/src/public_types.ts +1 -0
- package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +31 -22
- package/src/transports/dash/low_latency_segment_loader.ts +2 -2
- package/src/transports/dash/manifest_parser.ts +1 -1
- package/src/transports/dash/segment_loader.ts +4 -4
- package/src/transports/local/segment_loader.ts +14 -30
- package/src/transports/smooth/segment_loader.ts +4 -4
- package/src/transports/utils/call_custom_manifest_loader.ts +3 -3
- package/src/typings/globals.d.ts +2 -0
- package/src/utils/cancellable_sleep.ts +5 -14
- package/src/utils/create_cancellable_promise.ts +69 -0
- package/src/utils/reference.ts +6 -0
- package/src/utils/request/xhr.ts +1 -1
- package/src/utils/task_canceller.ts +63 -34
|
@@ -28,13 +28,13 @@ import createSharedReference from "../../utils/reference";
|
|
|
28
28
|
* remove all listeners this function has registered.
|
|
29
29
|
*/
|
|
30
30
|
export function emitSeekEvents(mediaElement, playbackObserver, onSeeking, onSeeked, cancelSignal) {
|
|
31
|
-
if (cancelSignal.isCancelled || mediaElement === null) {
|
|
31
|
+
if (cancelSignal.isCancelled() || mediaElement === null) {
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
var wasSeeking = playbackObserver.getReference().getValue().seeking;
|
|
35
35
|
if (wasSeeking) {
|
|
36
36
|
onSeeking();
|
|
37
|
-
if (cancelSignal.isCancelled) {
|
|
37
|
+
if (cancelSignal.isCancelled()) {
|
|
38
38
|
return;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
@@ -54,7 +54,7 @@ export function constructPlayerStateReference(initializer, mediaElement, playbac
|
|
|
54
54
|
initializer.addEventListener("loaded", function () {
|
|
55
55
|
if (playerStateRef.getValue() === "LOADING" /* PLAYER_STATES.LOADING */) {
|
|
56
56
|
playerStateRef.setValue("LOADED" /* PLAYER_STATES.LOADED */);
|
|
57
|
-
if (!cancelSignal.isCancelled) {
|
|
57
|
+
if (!cancelSignal.isCancelled()) {
|
|
58
58
|
var newState = getLoadedContentState(mediaElement, null);
|
|
59
59
|
if (newState !== "PAUSED" /* PLAYER_STATES.PAUSED */) {
|
|
60
60
|
playerStateRef.setValue(newState);
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
import { IEncryptedEventData } from "../../../../compat/eme";
|
|
18
18
|
import EventEmitter from "../../../../utils/event_emitter";
|
|
19
19
|
/** Default MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
20
|
-
export declare const defaultKSConfig: {
|
|
20
|
+
export declare const defaultKSConfig: ({
|
|
21
21
|
audioCapabilities: {
|
|
22
22
|
contentType: string;
|
|
23
23
|
}[];
|
|
@@ -28,12 +28,19 @@ export declare const defaultKSConfig: {
|
|
|
28
28
|
videoCapabilities: {
|
|
29
29
|
contentType: string;
|
|
30
30
|
}[];
|
|
31
|
-
}
|
|
31
|
+
} | {
|
|
32
|
+
audioCapabilities: undefined;
|
|
33
|
+
distinctiveIdentifier: "optional";
|
|
34
|
+
initDataTypes: readonly ["cenc"];
|
|
35
|
+
persistentState: "optional";
|
|
36
|
+
sessionTypes: readonly ["temporary"];
|
|
37
|
+
videoCapabilities: undefined;
|
|
38
|
+
})[];
|
|
32
39
|
/**
|
|
33
40
|
* Default "com.microsoft.playready.recommendation" MediaKeySystemAccess
|
|
34
41
|
* configuration used by the RxPlayer.
|
|
35
42
|
*/
|
|
36
|
-
export declare const defaultPRRecommendationKSConfig: {
|
|
43
|
+
export declare const defaultPRRecommendationKSConfig: ({
|
|
37
44
|
audioCapabilities: {
|
|
38
45
|
robustness: string;
|
|
39
46
|
contentType: string;
|
|
@@ -46,22 +53,34 @@ export declare const defaultPRRecommendationKSConfig: {
|
|
|
46
53
|
robustness: string;
|
|
47
54
|
contentType: string;
|
|
48
55
|
}[];
|
|
49
|
-
}
|
|
56
|
+
} | {
|
|
57
|
+
audioCapabilities: undefined;
|
|
58
|
+
distinctiveIdentifier: "optional";
|
|
59
|
+
initDataTypes: readonly ["cenc"];
|
|
60
|
+
persistentState: "optional";
|
|
61
|
+
sessionTypes: readonly ["temporary"];
|
|
62
|
+
videoCapabilities: undefined;
|
|
63
|
+
})[];
|
|
50
64
|
/** Default Widevine MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
51
|
-
export declare const defaultWidevineConfig: {
|
|
65
|
+
export declare const defaultWidevineConfig: ({
|
|
52
66
|
audioCapabilities: {
|
|
53
67
|
contentType: string;
|
|
54
|
-
robustness: string;
|
|
55
68
|
}[];
|
|
69
|
+
distinctiveIdentifier: "optional";
|
|
70
|
+
initDataTypes: readonly ["cenc"];
|
|
71
|
+
persistentState: "optional";
|
|
72
|
+
sessionTypes: readonly ["temporary"];
|
|
56
73
|
videoCapabilities: {
|
|
57
74
|
contentType: string;
|
|
58
|
-
robustness: string;
|
|
59
75
|
}[];
|
|
76
|
+
} | {
|
|
77
|
+
audioCapabilities: undefined;
|
|
60
78
|
distinctiveIdentifier: "optional";
|
|
61
79
|
initDataTypes: readonly ["cenc"];
|
|
62
80
|
persistentState: "optional";
|
|
63
81
|
sessionTypes: readonly ["temporary"];
|
|
64
|
-
|
|
82
|
+
videoCapabilities: undefined;
|
|
83
|
+
})[];
|
|
65
84
|
/**
|
|
66
85
|
* Custom implementation of an EME-compliant MediaKeyStatusMap.
|
|
67
86
|
* @class MediaKeyStatusMapImpl
|
|
@@ -119,17 +138,17 @@ export declare function requestMediaKeySystemAccessImpl(keySystem: string, confi
|
|
|
119
138
|
* Mock functions coming from the compat directory.
|
|
120
139
|
*/
|
|
121
140
|
export declare function mockCompat(exportedFunctions?: {}): {
|
|
122
|
-
mockEvents: Record<string, jest.Mock<any, any>>;
|
|
141
|
+
mockEvents: Record<string, jest.Mock<any, any, any>>;
|
|
123
142
|
eventTriggers: {
|
|
124
143
|
triggerEncrypted(elt: HTMLMediaElement, value: unknown): void;
|
|
125
144
|
triggerKeyMessage(session: MediaKeySessionImpl, value: unknown): void;
|
|
126
145
|
triggerKeyError(session: MediaKeySessionImpl, value: unknown): void;
|
|
127
146
|
triggerKeyStatusesChange(session: MediaKeySessionImpl, value: unknown): void;
|
|
128
147
|
};
|
|
129
|
-
mockRequestMediaKeySystemAccess: jest.Mock<Promise<MediaKeySystemAccessImpl>, [keySystem: string, config: MediaKeySystemConfiguration[]]>;
|
|
130
|
-
mockGetInitData: jest.Mock<IEncryptedEventData, [encryptedEvent: IEncryptedEventData]>;
|
|
131
|
-
mockSetMediaKeys: jest.Mock<any, any>;
|
|
132
|
-
mockGenerateKeyRequest: jest.Mock<Promise<void>, [mks: MediaKeySessionImpl, initializationDataType: any, initializationData: any]>;
|
|
148
|
+
mockRequestMediaKeySystemAccess: jest.Mock<Promise<MediaKeySystemAccessImpl>, [keySystem: string, config: MediaKeySystemConfiguration[]], any>;
|
|
149
|
+
mockGetInitData: jest.Mock<IEncryptedEventData, [encryptedEvent: IEncryptedEventData], any>;
|
|
150
|
+
mockSetMediaKeys: jest.Mock<any, any, any>;
|
|
151
|
+
mockGenerateKeyRequest: jest.Mock<Promise<void>, [mks: MediaKeySessionImpl, initializationDataType: any, initializationData: any], any>;
|
|
133
152
|
};
|
|
134
153
|
/**
|
|
135
154
|
* Check that the ContentDecryptor, when called with those arguments, throws.
|
|
@@ -44,7 +44,8 @@ import EventEmitter from "../../../../utils/event_emitter";
|
|
|
44
44
|
import flatMap from "../../../../utils/flat_map";
|
|
45
45
|
import { strToUtf8, utf8ToStr, } from "../../../../utils/string_parsing";
|
|
46
46
|
/** Default MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
47
|
-
export var defaultKSConfig = [
|
|
47
|
+
export var defaultKSConfig = [
|
|
48
|
+
{
|
|
48
49
|
audioCapabilities: [{ contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
49
50
|
{ contentType: "audio/webm;codecs=opus" }],
|
|
50
51
|
distinctiveIdentifier: "optional",
|
|
@@ -54,12 +55,22 @@ export var defaultKSConfig = [{
|
|
|
54
55
|
videoCapabilities: [{ contentType: "video/mp4;codecs=\"avc1.4d401e\"" },
|
|
55
56
|
{ contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
56
57
|
{ contentType: "video/webm;codecs=\"vp8\"" }],
|
|
57
|
-
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
audioCapabilities: undefined,
|
|
61
|
+
distinctiveIdentifier: "optional",
|
|
62
|
+
initDataTypes: ["cenc"],
|
|
63
|
+
persistentState: "optional",
|
|
64
|
+
sessionTypes: ["temporary"],
|
|
65
|
+
videoCapabilities: undefined,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
58
68
|
/**
|
|
59
69
|
* Default "com.microsoft.playready.recommendation" MediaKeySystemAccess
|
|
60
70
|
* configuration used by the RxPlayer.
|
|
61
71
|
*/
|
|
62
|
-
export var defaultPRRecommendationKSConfig = [
|
|
72
|
+
export var defaultPRRecommendationKSConfig = [
|
|
73
|
+
{
|
|
63
74
|
audioCapabilities: [{ robustness: "3000",
|
|
64
75
|
contentType: "audio/mp4;codecs=\"mp4a.40.2\"" },
|
|
65
76
|
{ robustness: "3000",
|
|
@@ -84,7 +95,16 @@ export var defaultPRRecommendationKSConfig = [{
|
|
|
84
95
|
contentType: "video/mp4;codecs=\"avc1.42e01e\"" },
|
|
85
96
|
{ robustness: "2000",
|
|
86
97
|
contentType: "video/webm;codecs=\"vp8\"" }],
|
|
87
|
-
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
audioCapabilities: undefined,
|
|
101
|
+
distinctiveIdentifier: "optional",
|
|
102
|
+
initDataTypes: ["cenc"],
|
|
103
|
+
persistentState: "optional",
|
|
104
|
+
sessionTypes: ["temporary"],
|
|
105
|
+
videoCapabilities: undefined,
|
|
106
|
+
},
|
|
107
|
+
];
|
|
88
108
|
/** Default Widevine MediaKeySystemAccess configuration used by the RxPlayer. */
|
|
89
109
|
export var defaultWidevineConfig = (function () {
|
|
90
110
|
var ROBUSTNESSES = ["HW_SECURE_ALL",
|
|
@@ -101,9 +121,10 @@ export var defaultWidevineConfig = (function () {
|
|
|
101
121
|
return [{ contentType: "audio/mp4;codecs=\"mp4a.40.2\"", robustness: robustness },
|
|
102
122
|
{ contentType: "audio/webm;codecs=opus", robustness: robustness }];
|
|
103
123
|
});
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
|
|
124
|
+
return [
|
|
125
|
+
__assign(__assign({}, defaultKSConfig[0]), { audioCapabilities: audioCapabilities, videoCapabilities: videoCapabilities }),
|
|
126
|
+
defaultKSConfig[1],
|
|
127
|
+
];
|
|
107
128
|
})();
|
|
108
129
|
/**
|
|
109
130
|
* Custom implementation of an EME-compliant MediaKeyStatusMap.
|
|
@@ -87,7 +87,7 @@ export default function attachMediaKeys(mediaElement, _a, cancelSignal) {
|
|
|
87
87
|
_b.sent();
|
|
88
88
|
// If this task has been cancelled while we were closing previous sessions,
|
|
89
89
|
// stop now (and thus avoid setting the new media keys);
|
|
90
|
-
if (cancelSignal.isCancelled) {
|
|
90
|
+
if (cancelSignal.isCancelled()) {
|
|
91
91
|
throw cancelSignal.cancellationError;
|
|
92
92
|
}
|
|
93
93
|
MediaKeysInfosStore.setState(mediaElement, { keySystemOptions: keySystemOptions, mediaKeySystemAccess: mediaKeySystemAccess, mediaKeys: mediaKeys, loadedSessionsStore: loadedSessionsStore });
|
|
@@ -614,7 +614,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
|
|
|
614
614
|
* formatted and sent in an "error" event.
|
|
615
615
|
*/
|
|
616
616
|
ContentDecryptor.prototype._onFatalError = function (err) {
|
|
617
|
-
if (this._canceller.isUsed) {
|
|
617
|
+
if (this._canceller.isUsed()) {
|
|
618
618
|
return;
|
|
619
619
|
}
|
|
620
620
|
var formattedErr = err instanceof Error ?
|
|
@@ -13,6 +13,17 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
var __assign = (this && this.__assign) || function () {
|
|
17
|
+
__assign = Object.assign || function(t) {
|
|
18
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
19
|
+
s = arguments[i];
|
|
20
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
21
|
+
t[p] = s[p];
|
|
22
|
+
}
|
|
23
|
+
return t;
|
|
24
|
+
};
|
|
25
|
+
return __assign.apply(this, arguments);
|
|
26
|
+
};
|
|
16
27
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
28
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
29
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -130,7 +141,7 @@ function buildKeySystemConfigurations(ksName, ksType, keySystem) {
|
|
|
130
141
|
if (keySystem.distinctiveIdentifierRequired === true) {
|
|
131
142
|
distinctiveIdentifier = "required";
|
|
132
143
|
}
|
|
133
|
-
var _a = config.getCurrent(), EME_DEFAULT_WIDEVINE_ROBUSTNESSES = _a.EME_DEFAULT_WIDEVINE_ROBUSTNESSES, EME_DEFAULT_PLAYREADY_ROBUSTNESSES = _a.EME_DEFAULT_PLAYREADY_ROBUSTNESSES;
|
|
144
|
+
var _a = config.getCurrent(), EME_DEFAULT_AUDIO_CODECS = _a.EME_DEFAULT_AUDIO_CODECS, EME_DEFAULT_VIDEO_CODECS = _a.EME_DEFAULT_VIDEO_CODECS, EME_DEFAULT_WIDEVINE_ROBUSTNESSES = _a.EME_DEFAULT_WIDEVINE_ROBUSTNESSES, EME_DEFAULT_PLAYREADY_ROBUSTNESSES = _a.EME_DEFAULT_PLAYREADY_ROBUSTNESSES;
|
|
134
145
|
// Set robustness, in order of consideration:
|
|
135
146
|
// 1. the user specified its own robustnesses
|
|
136
147
|
// 2. a "widevine" key system is used, in that case set the default widevine
|
|
@@ -180,34 +191,32 @@ function buildKeySystemConfigurations(ksName, ksType, keySystem) {
|
|
|
180
191
|
// https://storage.googleapis.com/wvdocs/Chrome_EME_Changes_and_Best_Practices.pdf
|
|
181
192
|
// https://www.w3.org/TR/encrypted-media/#get-supported-configuration-and-consent
|
|
182
193
|
var videoCapabilities = flatMap(videoRobustnesses, function (robustness) {
|
|
183
|
-
return
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
return robustness !== undefined ? { contentType: contentType, robustness: robustness } :
|
|
187
|
-
{ contentType: contentType };
|
|
194
|
+
return EME_DEFAULT_VIDEO_CODECS.map(function (contentType) {
|
|
195
|
+
return robustness === undefined ? { contentType: contentType } :
|
|
196
|
+
{ contentType: contentType, robustness: robustness };
|
|
188
197
|
});
|
|
189
198
|
});
|
|
190
199
|
var audioCapabilities = flatMap(audioRobustnesses, function (robustness) {
|
|
191
|
-
return
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
{ contentType: contentType };
|
|
200
|
+
return EME_DEFAULT_AUDIO_CODECS.map(function (contentType) {
|
|
201
|
+
return robustness === undefined ? { contentType: contentType } :
|
|
202
|
+
{ contentType: contentType, robustness: robustness };
|
|
195
203
|
});
|
|
196
204
|
});
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
205
|
+
var wantedMediaKeySystemConfiguration = {
|
|
206
|
+
initDataTypes: ["cenc"],
|
|
207
|
+
videoCapabilities: videoCapabilities,
|
|
208
|
+
audioCapabilities: audioCapabilities,
|
|
209
|
+
distinctiveIdentifier: distinctiveIdentifier,
|
|
210
|
+
persistentState: persistentState,
|
|
211
|
+
sessionTypes: sessionTypes,
|
|
212
|
+
};
|
|
213
|
+
return [
|
|
214
|
+
wantedMediaKeySystemConfiguration,
|
|
215
|
+
// Some legacy implementations have issues with `audioCapabilities` and
|
|
216
|
+
// `videoCapabilities`, so we're including a supplementary
|
|
217
|
+
// `MediaKeySystemConfiguration` without those properties.
|
|
218
|
+
__assign(__assign({}, wantedMediaKeySystemConfiguration), { audioCapabilities: undefined, videoCapabilities: undefined }),
|
|
219
|
+
];
|
|
211
220
|
}
|
|
212
221
|
/**
|
|
213
222
|
* Try to find a compatible key system from the keySystems array given.
|
|
@@ -86,12 +86,13 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
86
86
|
log.info("DRM: Binding session events", session.sessionId);
|
|
87
87
|
var _a = keySystemOptions.getLicenseConfig, getLicenseConfig = _a === void 0 ? {} : _a;
|
|
88
88
|
/** Allows to manually cancel everything the `SessionEventsListener` is doing. */
|
|
89
|
-
var manualCanceller = new TaskCanceller(
|
|
89
|
+
var manualCanceller = new TaskCanceller();
|
|
90
|
+
manualCanceller.linkToSignal(cancelSignal);
|
|
90
91
|
if (!isNullOrUndefined(session.closed)) {
|
|
91
92
|
session.closed
|
|
92
93
|
.then(function () { return manualCanceller.cancel(); })
|
|
93
94
|
.catch(function (err) {
|
|
94
|
-
if (cancelSignal.isCancelled) {
|
|
95
|
+
if (cancelSignal.isCancelled()) {
|
|
95
96
|
return;
|
|
96
97
|
}
|
|
97
98
|
manualCanceller.cancel();
|
|
@@ -104,8 +105,8 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
104
105
|
}, manualCanceller.signal);
|
|
105
106
|
onKeyStatusesChange(session, function (keyStatusesEvent) {
|
|
106
107
|
handleKeyStatusesChangeEvent(keyStatusesEvent).catch(function (error) {
|
|
107
|
-
if (cancelSignal.isCancelled ||
|
|
108
|
-
(manualCanceller.isUsed && error instanceof CancellationSignal)) {
|
|
108
|
+
if (cancelSignal.isCancelled() ||
|
|
109
|
+
(manualCanceller.isUsed() && error instanceof CancellationSignal)) {
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
112
|
manualCanceller.cancel();
|
|
@@ -122,7 +123,7 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
122
123
|
var backoffOptions = getLicenseBackoffOptions(getLicenseConfig.retry);
|
|
123
124
|
retryPromiseWithBackoff(function () { return runGetLicense(message, messageType); }, backoffOptions, manualCanceller.signal)
|
|
124
125
|
.then(function (licenseObject) {
|
|
125
|
-
if (manualCanceller.isUsed) {
|
|
126
|
+
if (manualCanceller.isUsed()) {
|
|
126
127
|
return Promise.resolve();
|
|
127
128
|
}
|
|
128
129
|
if (isNullOrUndefined(licenseObject)) {
|
|
@@ -133,7 +134,7 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
133
134
|
}
|
|
134
135
|
})
|
|
135
136
|
.catch(function (err) {
|
|
136
|
-
if (manualCanceller.isUsed) {
|
|
137
|
+
if (manualCanceller.isUsed()) {
|
|
137
138
|
return;
|
|
138
139
|
}
|
|
139
140
|
manualCanceller.cancel();
|
|
@@ -150,6 +151,8 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
150
151
|
callbacks.onError(formattedError);
|
|
151
152
|
});
|
|
152
153
|
}, manualCanceller.signal);
|
|
154
|
+
checkAndHandleCurrentKeyStatuses();
|
|
155
|
+
return;
|
|
153
156
|
/**
|
|
154
157
|
* @param {Event} keyStatusesEvent
|
|
155
158
|
* @returns {Promise}
|
|
@@ -162,7 +165,7 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
162
165
|
return __generator(this, function (_a) {
|
|
163
166
|
switch (_a.label) {
|
|
164
167
|
case 0:
|
|
165
|
-
if (manualCanceller.isUsed) {
|
|
168
|
+
if (manualCanceller.isUsed()) {
|
|
166
169
|
return [2 /*return*/];
|
|
167
170
|
}
|
|
168
171
|
if (!(typeof keySystemOptions.onKeyStatusesChange === "function")) return [3 /*break*/, 7];
|
|
@@ -173,13 +176,13 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
173
176
|
return [4 /*yield*/, keySystemOptions.onKeyStatusesChange(keyStatusesEvent, session)];
|
|
174
177
|
case 2:
|
|
175
178
|
ret = _a.sent();
|
|
176
|
-
if (manualCanceller.isUsed) {
|
|
179
|
+
if (manualCanceller.isUsed()) {
|
|
177
180
|
return [2 /*return*/];
|
|
178
181
|
}
|
|
179
182
|
return [3 /*break*/, 4];
|
|
180
183
|
case 3:
|
|
181
184
|
error_1 = _a.sent();
|
|
182
|
-
if (cancelSignal.isCancelled) {
|
|
185
|
+
if (cancelSignal.isCancelled()) {
|
|
183
186
|
return [2 /*return*/];
|
|
184
187
|
}
|
|
185
188
|
err = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "Unknown `onKeyStatusesChange` error");
|
|
@@ -201,32 +204,13 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
201
204
|
});
|
|
202
205
|
});
|
|
203
206
|
}
|
|
204
|
-
/**
|
|
205
|
-
* Check current MediaKeyStatus for each key in the given MediaKeySession and:
|
|
206
|
-
* - throw if at least one status is a non-recoverable error
|
|
207
|
-
* - call warning callback for recoverable errors
|
|
208
|
-
* - call onKeyUpdate callback when the MediaKeyStatus of any key is updated
|
|
209
|
-
*/
|
|
210
|
-
function handleKeyStatusEvent() {
|
|
211
|
-
if (manualCanceller.isUsed || session.keyStatuses.size === 0) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
var _a = checkKeyStatuses(session, keySystemOptions, keySystem), warning = _a.warning, blacklistedKeyIds = _a.blacklistedKeyIds, whitelistedKeyIds = _a.whitelistedKeyIds;
|
|
215
|
-
if (warning !== undefined) {
|
|
216
|
-
callbacks.onWarning(warning);
|
|
217
|
-
if (manualCanceller.isUsed) {
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
callbacks.onKeyUpdate({ whitelistedKeyIds: whitelistedKeyIds, blacklistedKeyIds: blacklistedKeyIds });
|
|
222
|
-
}
|
|
223
207
|
return __generator(this, function (_a) {
|
|
224
208
|
switch (_a.label) {
|
|
225
209
|
case 0:
|
|
226
210
|
log.info("DRM: keystatuseschange event received", session.sessionId);
|
|
227
211
|
return [4 /*yield*/, Promise.all([
|
|
228
212
|
runOnKeyStatusesChangeCallback(),
|
|
229
|
-
Promise.resolve(
|
|
213
|
+
Promise.resolve(checkAndHandleCurrentKeyStatuses()),
|
|
230
214
|
])];
|
|
231
215
|
case 1:
|
|
232
216
|
_a.sent();
|
|
@@ -235,36 +219,56 @@ export default function SessionEventsListener(session, keySystemOptions, keySyst
|
|
|
235
219
|
});
|
|
236
220
|
});
|
|
237
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Check current MediaKeyStatus for each key in the given MediaKeySession and:
|
|
224
|
+
* - throw if at least one status is a non-recoverable error
|
|
225
|
+
* - call warning callback for recoverable errors
|
|
226
|
+
* - call onKeyUpdate callback when the MediaKeyStatus of any key is updated
|
|
227
|
+
*/
|
|
228
|
+
function checkAndHandleCurrentKeyStatuses() {
|
|
229
|
+
if (manualCanceller.isUsed() || session.keyStatuses.size === 0) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
var _a = checkKeyStatuses(session, keySystemOptions, keySystem), warning = _a.warning, blacklistedKeyIds = _a.blacklistedKeyIds, whitelistedKeyIds = _a.whitelistedKeyIds;
|
|
233
|
+
if (warning !== undefined) {
|
|
234
|
+
callbacks.onWarning(warning);
|
|
235
|
+
if (manualCanceller.isUsed()) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
callbacks.onKeyUpdate({ whitelistedKeyIds: whitelistedKeyIds, blacklistedKeyIds: blacklistedKeyIds });
|
|
240
|
+
}
|
|
238
241
|
function runGetLicense(message, messageType) {
|
|
242
|
+
var timeoutId;
|
|
239
243
|
return new Promise(function (res, rej) {
|
|
240
|
-
log.debug("DRM: Calling `getLicense`", messageType);
|
|
241
|
-
var getLicense = keySystemOptions.getLicense(message, messageType);
|
|
242
|
-
var getLicenseTimeout = isNullOrUndefined(getLicenseConfig.timeout) ?
|
|
243
|
-
10 * 1000 :
|
|
244
|
-
getLicenseConfig.timeout;
|
|
245
|
-
var timeoutId;
|
|
246
|
-
if (getLicenseTimeout >= 0) {
|
|
247
|
-
timeoutId = setTimeout(function () {
|
|
248
|
-
rej(new GetLicenseTimeoutError("\"getLicense\" timeout exceeded (".concat(getLicenseTimeout, " ms)")));
|
|
249
|
-
}, getLicenseTimeout);
|
|
250
|
-
}
|
|
251
244
|
try {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
245
|
+
log.debug("DRM: Calling `getLicense`", messageType);
|
|
246
|
+
var getLicense = keySystemOptions.getLicense(message, messageType);
|
|
247
|
+
var getLicenseTimeout_1 = isNullOrUndefined(getLicenseConfig.timeout) ?
|
|
248
|
+
10 * 1000 :
|
|
249
|
+
getLicenseConfig.timeout;
|
|
250
|
+
if (getLicenseTimeout_1 >= 0) {
|
|
251
|
+
timeoutId = setTimeout(function () {
|
|
252
|
+
rej(new GetLicenseTimeoutError("\"getLicense\" timeout exceeded (".concat(getLicenseTimeout_1, " ms)")));
|
|
253
|
+
}, getLicenseTimeout_1);
|
|
254
|
+
}
|
|
255
|
+
Promise.resolve(getLicense)
|
|
256
|
+
.then(clearTimeoutAndResolve, clearTimeoutAndReject);
|
|
259
257
|
}
|
|
260
258
|
catch (err) {
|
|
261
|
-
|
|
262
|
-
rej(err);
|
|
259
|
+
clearTimeoutAndReject(err);
|
|
263
260
|
}
|
|
264
|
-
function
|
|
261
|
+
function clearTimeoutAndResolve(data) {
|
|
265
262
|
if (timeoutId !== undefined) {
|
|
266
263
|
clearTimeout(timeoutId);
|
|
267
264
|
}
|
|
265
|
+
res(data);
|
|
266
|
+
}
|
|
267
|
+
function clearTimeoutAndReject(err) {
|
|
268
|
+
if (timeoutId !== undefined) {
|
|
269
|
+
clearTimeout(timeoutId);
|
|
270
|
+
}
|
|
271
|
+
rej(err);
|
|
268
272
|
}
|
|
269
273
|
});
|
|
270
274
|
}
|
|
@@ -40,6 +40,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
40
40
|
/* eslint-disable-next-line max-len */
|
|
41
41
|
import getUUIDKidFromKeyStatusKID from "../../../compat/eme/get_uuid_kid_from_keystatus_kid";
|
|
42
42
|
import { EncryptedMediaError } from "../../../errors";
|
|
43
|
+
import log from "../../../log";
|
|
43
44
|
import assertUnreachable from "../../../utils/assert_unreachable";
|
|
44
45
|
import { bytesToHex } from "../../../utils/string_parsing";
|
|
45
46
|
/**
|
|
@@ -95,6 +96,9 @@ export default function checkKeyStatuses(session, options, keySystem) {
|
|
|
95
96
|
})(), keyStatus = _a[0], keyStatusKeyId = _a[1];
|
|
96
97
|
var keyId = getUUIDKidFromKeyStatusKID(keySystem, new Uint8Array(keyStatusKeyId));
|
|
97
98
|
var keyStatusObj = { keyId: keyId.buffer, keyStatus: keyStatus };
|
|
99
|
+
if (log.hasLevel("DEBUG")) {
|
|
100
|
+
log.debug("DRM: key status update (".concat(bytesToHex(keyId), "): ").concat(keyStatus));
|
|
101
|
+
}
|
|
98
102
|
switch (keyStatus) {
|
|
99
103
|
case KEY_STATUSES.EXPIRED: {
|
|
100
104
|
var error = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A decryption key expired (".concat(bytesToHex(keyId), ")"), { keyStatuses: __spreadArray([keyStatusObj], badKeyStatuses, true) });
|
|
@@ -14,17 +14,20 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { ICdnMetadata } from "../../parsers/manifest";
|
|
17
|
-
import { IPlayerError } from "../../public_types";
|
|
18
17
|
import EventEmitter from "../../utils/event_emitter";
|
|
19
18
|
import { CancellationSignal } from "../../utils/task_canceller";
|
|
20
19
|
/**
|
|
21
|
-
* Class signaling the priority between multiple CDN available for
|
|
22
|
-
* resource.
|
|
20
|
+
* Class storing and signaling the priority between multiple CDN available for
|
|
21
|
+
* any given resource.
|
|
23
22
|
*
|
|
24
|
-
* This class
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
23
|
+
* This class was first created to implement the complexities behind
|
|
24
|
+
* Content Steering features, though its handling hasn't been added yet as we
|
|
25
|
+
* wait for its specification to be both standardized and relied on in the wild.
|
|
26
|
+
* In the meantime, it acts as an abstraction for the simple concept of
|
|
27
|
+
* avoiding to request a CDN for any segment when an issue is encountered with
|
|
28
|
+
* one (e.g. HTTP 500 statuses) and several CDN exist for a given resource. It
|
|
29
|
+
* should be noted that this is also one of the planified features of the
|
|
30
|
+
* Content Steering specification.
|
|
28
31
|
*
|
|
29
32
|
* @class CdnPrioritizer
|
|
30
33
|
*/
|
|
@@ -92,7 +95,13 @@ export default class CdnPrioritizer extends EventEmitter<ICdnPrioritizerEvents>
|
|
|
92
95
|
*/
|
|
93
96
|
private _removeIndexFromDowngradeList;
|
|
94
97
|
}
|
|
98
|
+
/** Events sent by a `CdnPrioritizer` */
|
|
95
99
|
export interface ICdnPrioritizerEvents {
|
|
96
|
-
|
|
100
|
+
/**
|
|
101
|
+
* The priority of one or several CDN changed.
|
|
102
|
+
*
|
|
103
|
+
* You might want to re-check if a CDN should still be used when this event
|
|
104
|
+
* is triggered.
|
|
105
|
+
*/
|
|
97
106
|
priorityChange: null;
|
|
98
107
|
}
|
|
@@ -32,13 +32,17 @@ import config from "../../config";
|
|
|
32
32
|
import arrayFindIndex from "../../utils/array_find_index";
|
|
33
33
|
import EventEmitter from "../../utils/event_emitter";
|
|
34
34
|
/**
|
|
35
|
-
* Class signaling the priority between multiple CDN available for
|
|
36
|
-
* resource.
|
|
35
|
+
* Class storing and signaling the priority between multiple CDN available for
|
|
36
|
+
* any given resource.
|
|
37
37
|
*
|
|
38
|
-
* This class
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
38
|
+
* This class was first created to implement the complexities behind
|
|
39
|
+
* Content Steering features, though its handling hasn't been added yet as we
|
|
40
|
+
* wait for its specification to be both standardized and relied on in the wild.
|
|
41
|
+
* In the meantime, it acts as an abstraction for the simple concept of
|
|
42
|
+
* avoiding to request a CDN for any segment when an issue is encountered with
|
|
43
|
+
* one (e.g. HTTP 500 statuses) and several CDN exist for a given resource. It
|
|
44
|
+
* should be noted that this is also one of the planified features of the
|
|
45
|
+
* Content Steering specification.
|
|
42
46
|
*
|
|
43
47
|
* @class CdnPrioritizer
|
|
44
48
|
*/
|
|
@@ -145,7 +145,7 @@ var ManifestFetcher = /** @class */ (function (_super) {
|
|
|
145
145
|
manifestProm
|
|
146
146
|
.then(function (val) {
|
|
147
147
|
_this.trigger("manifestReady", val.manifest);
|
|
148
|
-
if (!_this._canceller.isUsed) {
|
|
148
|
+
if (!_this._canceller.isUsed()) {
|
|
149
149
|
_this._recursivelyRefreshManifest(val.manifest, val);
|
|
150
150
|
}
|
|
151
151
|
})
|
|
@@ -311,7 +311,7 @@ var ManifestFetcher = /** @class */ (function (_super) {
|
|
|
311
311
|
function onWarnings(warnings) {
|
|
312
312
|
for (var _i = 0, warnings_1 = warnings; _i < warnings_1.length; _i++) {
|
|
313
313
|
var warning = warnings_1[_i];
|
|
314
|
-
if (cancelSignal.isCancelled) {
|
|
314
|
+
if (cancelSignal.isCancelled()) {
|
|
315
315
|
return;
|
|
316
316
|
}
|
|
317
317
|
var formattedError = formatError(warning, {
|
|
@@ -430,7 +430,8 @@ var ManifestFetcher = /** @class */ (function (_super) {
|
|
|
430
430
|
* be effectively considered.
|
|
431
431
|
* `nextRefreshCanceller` will allow to cancel every other when one is triggered.
|
|
432
432
|
*/
|
|
433
|
-
var nextRefreshCanceller = new TaskCanceller(
|
|
433
|
+
var nextRefreshCanceller = new TaskCanceller();
|
|
434
|
+
nextRefreshCanceller.linkToSignal(this._canceller.signal);
|
|
434
435
|
/* Function to manually schedule a Manifest refresh */
|
|
435
436
|
this.scheduleManualRefresh = function (settings) {
|
|
436
437
|
var enablePartialRefresh = settings.enablePartialRefresh, delay = settings.delay, canUseUnsafeMode = settings.canUseUnsafeMode;
|
|
@@ -603,7 +604,7 @@ var ManifestFetcher = /** @class */ (function (_super) {
|
|
|
603
604
|
});
|
|
604
605
|
};
|
|
605
606
|
ManifestFetcher.prototype._onFatalError = function (err) {
|
|
606
|
-
if (this._canceller.isUsed) {
|
|
607
|
+
if (this._canceller.isUsed()) {
|
|
607
608
|
return;
|
|
608
609
|
}
|
|
609
610
|
this.trigger("error", err);
|
|
@@ -26,10 +26,22 @@ import CdnPrioritizer from "../cdn_prioritizer";
|
|
|
26
26
|
* An `ISegmentFetcher` also implements a retry mechanism, based on the given
|
|
27
27
|
* `options` argument, which may retry a segment request when it fails.
|
|
28
28
|
*
|
|
29
|
-
* @param {string} bufferType
|
|
30
|
-
*
|
|
31
|
-
* @param {Object}
|
|
32
|
-
*
|
|
29
|
+
* @param {string} bufferType - Type of buffer concerned (e.g. `"audio"`,
|
|
30
|
+
* `"video"`, `"text" etc.)
|
|
31
|
+
* @param {Object} pipeline - The transport-specific logic allowing to load
|
|
32
|
+
* segments of the given buffer type and transport protocol (e.g. DASH).
|
|
33
|
+
* @param {Object|null} cdnPrioritizer - Abstraction allowing to synchronize,
|
|
34
|
+
* update and keep track of the priorization of the CDN to use to load any given
|
|
35
|
+
* segment, in cases where multiple ones are available.
|
|
36
|
+
*
|
|
37
|
+
* Can be set to `null` in which case a minimal priorization logic will be used
|
|
38
|
+
* instead.
|
|
39
|
+
* @param {Object} lifecycleCallbacks - Callbacks that can be registered to be
|
|
40
|
+
* informed when new requests are made, ended, new metrics are available etc.
|
|
41
|
+
* This should be mainly useful to implement an adaptive logic relying on those
|
|
42
|
+
* metrics and events.
|
|
43
|
+
* @param {Object} options - Various tweaking options allowing to configure the
|
|
44
|
+
* behavior of the returned `ISegmentFetcher`.
|
|
33
45
|
* @returns {Function}
|
|
34
46
|
*/
|
|
35
47
|
export default function createSegmentFetcher<TLoadedFormat, TSegmentDataType>(bufferType: IBufferType, pipeline: ISegmentPipeline<TLoadedFormat, TSegmentDataType>, cdnPrioritizer: CdnPrioritizer | null, lifecycleCallbacks: ISegmentFetcherLifecycleCallbacks, options: ISegmentFetcherOptions): ISegmentFetcher<TSegmentDataType>;
|
|
@@ -59,10 +71,15 @@ export interface ISegmentFetcherCallbacks<TSegmentDataType> {
|
|
|
59
71
|
/**
|
|
60
72
|
* Callback called when all decodable chunks of the loaded segment have been
|
|
61
73
|
* communicated through the `onChunk` callback.
|
|
74
|
+
*
|
|
75
|
+
* This callback is called before the corresponding `ISegmentFetcher`'s
|
|
76
|
+
* returned Promise is resolved.
|
|
62
77
|
*/
|
|
63
78
|
onAllChunksReceived(): void;
|
|
64
79
|
/**
|
|
65
|
-
* Callback called when the segment request has to restart from scratch.
|
|
80
|
+
* Callback called when the segment request has to restart from scratch, e.g.
|
|
81
|
+
* due to a request error.
|
|
82
|
+
*/
|
|
66
83
|
onRetry(error: IPlayerError): void;
|
|
67
84
|
}
|
|
68
85
|
/** Content used by the segment loader as a context to load a new segment. */
|