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/compat/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
MediaSource_,
|
|
23
23
|
} from "./browser_compatibility_types";
|
|
24
24
|
import canPatchISOBMFFSegment from "./can_patch_isobmff";
|
|
25
|
+
import canReuseMediaKeys from "./can_reuse_media_keys";
|
|
25
26
|
import tryToChangeSourceBufferType, {
|
|
26
27
|
ICompatSourceBuffer,
|
|
27
28
|
} from "./change_source_buffer_type";
|
|
@@ -38,6 +39,7 @@ import {
|
|
|
38
39
|
requestMediaKeySystemAccess,
|
|
39
40
|
setMediaKeys,
|
|
40
41
|
} from "./eme";
|
|
42
|
+
import enableAudioTrack from "./enable_audio_track";
|
|
41
43
|
import * as events from "./event_listeners";
|
|
42
44
|
import {
|
|
43
45
|
exitFullscreen,
|
|
@@ -57,7 +59,7 @@ import play from "./play";
|
|
|
57
59
|
import setElementSrc$ from "./set_element_src";
|
|
58
60
|
// eslint-disable-next-line max-len
|
|
59
61
|
import shouldReloadMediaSourceOnDecipherabilityUpdate from "./should_reload_media_source_on_decipherability_update";
|
|
60
|
-
import
|
|
62
|
+
import shouldRenewMediaKeySystemAccess from "./should_renew_media_key_system_access";
|
|
61
63
|
import shouldUnsetMediaKeys from "./should_unset_media_keys";
|
|
62
64
|
import shouldValidateMetadata from "./should_validate_metadata";
|
|
63
65
|
import shouldWaitForDataBeforeLoaded from "./should_wait_for_data_before_loaded";
|
|
@@ -72,9 +74,11 @@ export {
|
|
|
72
74
|
addClassName,
|
|
73
75
|
addTextTrack,
|
|
74
76
|
canPatchISOBMFFSegment,
|
|
77
|
+
canReuseMediaKeys,
|
|
75
78
|
clearElementSrc,
|
|
76
79
|
closeSession,
|
|
77
80
|
CustomMediaKeySystemAccess,
|
|
81
|
+
enableAudioTrack,
|
|
78
82
|
events,
|
|
79
83
|
exitFullscreen,
|
|
80
84
|
generateKeyRequest,
|
|
@@ -102,7 +106,7 @@ export {
|
|
|
102
106
|
setElementSrc$,
|
|
103
107
|
setMediaKeys,
|
|
104
108
|
shouldReloadMediaSourceOnDecipherabilityUpdate,
|
|
105
|
-
|
|
109
|
+
shouldRenewMediaKeySystemAccess,
|
|
106
110
|
shouldUnsetMediaKeys,
|
|
107
111
|
shouldValidateMetadata,
|
|
108
112
|
shouldWaitForDataBeforeLoaded,
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
import { isIE11 } from "./browser_detection";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Returns true if the current target require the
|
|
21
|
-
* each content.
|
|
20
|
+
* Returns true if the current target require the MediaKeySystemAccess to be
|
|
21
|
+
* renewed on each content.
|
|
22
22
|
* @returns {Boolean}
|
|
23
23
|
*/
|
|
24
|
-
export default function
|
|
24
|
+
export default function shouldRenewMediaKeySystemAccess() : boolean {
|
|
25
25
|
return isIE11;
|
|
26
26
|
}
|
|
@@ -264,7 +264,9 @@ export default class PlaybackObserver {
|
|
|
264
264
|
startedInternalSeekTime = this._internalSeeksIncoming.shift();
|
|
265
265
|
}
|
|
266
266
|
const _lastObservation = lastObservation ?? this._generateInitialObservation();
|
|
267
|
-
const mediaTimings = getMediaInfos(this._mediaElement,
|
|
267
|
+
const mediaTimings = getMediaInfos(this._mediaElement,
|
|
268
|
+
tmpEvt,
|
|
269
|
+
this._withMediaSource);
|
|
268
270
|
let pendingInternalSeek : number | null = null;
|
|
269
271
|
if (mediaTimings.seeking) {
|
|
270
272
|
if (typeof startedInternalSeekTime === "number") {
|
|
@@ -350,7 +352,9 @@ export default class PlaybackObserver {
|
|
|
350
352
|
}
|
|
351
353
|
|
|
352
354
|
private _generateInitialObservation() : IPlaybackObservation {
|
|
353
|
-
return objectAssign(getMediaInfos(this._mediaElement,
|
|
355
|
+
return objectAssign(getMediaInfos(this._mediaElement,
|
|
356
|
+
"init",
|
|
357
|
+
this._withMediaSource),
|
|
354
358
|
{ rebuffering: null,
|
|
355
359
|
freezing: null,
|
|
356
360
|
pendingInternalSeek: null });
|
|
@@ -388,14 +392,23 @@ export type IPlaybackObserverEventType =
|
|
|
388
392
|
|
|
389
393
|
/** Information recuperated on the media element on each playback observation. */
|
|
390
394
|
interface IMediaInfos {
|
|
391
|
-
/**
|
|
392
|
-
|
|
395
|
+
/**
|
|
396
|
+
* Gap between `currentTime` and the next position with un-buffered data.
|
|
397
|
+
* `Infinity` if we don't have buffered data right now.
|
|
398
|
+
* `undefined` if we cannot determine the buffer gap.
|
|
399
|
+
*/
|
|
400
|
+
bufferGap : number | undefined;
|
|
393
401
|
/** Value of `buffered` (buffered ranges) for the media element. */
|
|
394
402
|
buffered : TimeRanges;
|
|
395
|
-
/**
|
|
403
|
+
/**
|
|
404
|
+
* The buffered range we are currently playing.
|
|
405
|
+
* `null` if no range is currently available.
|
|
406
|
+
* `undefined` if we cannot tell which range is currently available.
|
|
407
|
+
*/
|
|
396
408
|
currentRange : { start : number;
|
|
397
409
|
end : number; } |
|
|
398
|
-
null
|
|
410
|
+
null |
|
|
411
|
+
undefined;
|
|
399
412
|
/**
|
|
400
413
|
* `currentTime` (position) set on the media element at the time of the
|
|
401
414
|
* PlaybackObserver's measure.
|
|
@@ -435,8 +448,9 @@ export interface IRebufferingStatus {
|
|
|
435
448
|
/**
|
|
436
449
|
* Position, in seconds, at which data is awaited.
|
|
437
450
|
* If `null` the player is rebuffering but not because it is awaiting future data.
|
|
451
|
+
* If `undefined`, that position is unknown.
|
|
438
452
|
*/
|
|
439
|
-
position : number | null;
|
|
453
|
+
position : number | null | undefined;
|
|
440
454
|
}
|
|
441
455
|
|
|
442
456
|
/**
|
|
@@ -585,13 +599,18 @@ function getRebufferingEndGap(
|
|
|
585
599
|
* @returns {Boolean}
|
|
586
600
|
*/
|
|
587
601
|
function hasLoadedUntilTheEnd(
|
|
588
|
-
|
|
602
|
+
currentTime : number,
|
|
603
|
+
currentRange : { start : number; end : number } | null | undefined,
|
|
604
|
+
ended : boolean,
|
|
589
605
|
duration : number,
|
|
590
606
|
lowLatencyMode : boolean
|
|
591
607
|
) : boolean {
|
|
592
608
|
const { REBUFFERING_GAP } = config.getCurrent();
|
|
593
609
|
const suffix : "LOW_LATENCY" | "DEFAULT" = lowLatencyMode ? "LOW_LATENCY" :
|
|
594
610
|
"DEFAULT";
|
|
611
|
+
if (currentRange === undefined) {
|
|
612
|
+
return ended && Math.abs(duration - currentTime) <= REBUFFERING_GAP[suffix];
|
|
613
|
+
}
|
|
595
614
|
return currentRange !== null &&
|
|
596
615
|
(duration - currentRange.end) <= REBUFFERING_GAP[suffix];
|
|
597
616
|
}
|
|
@@ -604,7 +623,8 @@ function hasLoadedUntilTheEnd(
|
|
|
604
623
|
*/
|
|
605
624
|
function getMediaInfos(
|
|
606
625
|
mediaElement : HTMLMediaElement,
|
|
607
|
-
event : IPlaybackObserverEventType
|
|
626
|
+
event : IPlaybackObserverEventType,
|
|
627
|
+
withMediaSource : boolean
|
|
608
628
|
) : IMediaInfos {
|
|
609
629
|
const { buffered,
|
|
610
630
|
currentTime,
|
|
@@ -615,11 +635,23 @@ function getMediaInfos(
|
|
|
615
635
|
readyState,
|
|
616
636
|
seeking } = mediaElement;
|
|
617
637
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
638
|
+
let currentRange;
|
|
639
|
+
let bufferGap;
|
|
640
|
+
if (!withMediaSource && buffered.length === 0 && readyState >= 3) {
|
|
641
|
+
// Sometimes `buffered` stay empty for directfile contents yet we are able
|
|
642
|
+
// to play. This seems to be linked to browser-side issues but has been
|
|
643
|
+
// encountered on enough platforms (Chrome desktop and PlayStation 4's
|
|
644
|
+
// WebKit for us to do something about it in the player.
|
|
645
|
+
currentRange = undefined;
|
|
646
|
+
bufferGap = undefined;
|
|
647
|
+
} else {
|
|
648
|
+
currentRange = getRange(buffered, currentTime);
|
|
649
|
+
bufferGap = currentRange !== null ? currentRange.end - currentTime :
|
|
650
|
+
// TODO null/0 would probably be
|
|
651
|
+
// more appropriate
|
|
652
|
+
Infinity;
|
|
653
|
+
}
|
|
654
|
+
return { bufferGap,
|
|
623
655
|
buffered,
|
|
624
656
|
currentRange,
|
|
625
657
|
position: currentTime,
|
|
@@ -664,14 +696,18 @@ function getRebufferingStatus(
|
|
|
664
696
|
event: prevEvt,
|
|
665
697
|
position: prevTime } = prevObservation;
|
|
666
698
|
|
|
667
|
-
const fullyLoaded = hasLoadedUntilTheEnd(
|
|
699
|
+
const fullyLoaded = hasLoadedUntilTheEnd(currentTime,
|
|
700
|
+
currentRange,
|
|
701
|
+
ended,
|
|
702
|
+
duration,
|
|
703
|
+
lowLatencyMode);
|
|
668
704
|
|
|
669
705
|
const canSwitchToRebuffering = (readyState >= 1 &&
|
|
670
706
|
currentEvt !== "loadedmetadata" &&
|
|
671
707
|
prevRebuffering === null &&
|
|
672
708
|
!(fullyLoaded || ended));
|
|
673
709
|
|
|
674
|
-
let rebufferEndPosition : number | null = null;
|
|
710
|
+
let rebufferEndPosition : number | null | undefined = null;
|
|
675
711
|
let shouldRebuffer : boolean | undefined;
|
|
676
712
|
let shouldStopRebuffer : boolean | undefined;
|
|
677
713
|
|
|
@@ -680,22 +716,32 @@ function getRebufferingStatus(
|
|
|
680
716
|
|
|
681
717
|
if (withMediaSource) {
|
|
682
718
|
if (canSwitchToRebuffering) {
|
|
683
|
-
if (bufferGap
|
|
684
|
-
shouldRebuffer = true;
|
|
685
|
-
rebufferEndPosition = currentTime + bufferGap;
|
|
686
|
-
} else if (bufferGap === Infinity) {
|
|
719
|
+
if (bufferGap === Infinity) {
|
|
687
720
|
shouldRebuffer = true;
|
|
688
721
|
rebufferEndPosition = currentTime;
|
|
722
|
+
} else if (bufferGap === undefined) {
|
|
723
|
+
if (readyState < 3) {
|
|
724
|
+
shouldRebuffer = true;
|
|
725
|
+
rebufferEndPosition = undefined;
|
|
726
|
+
}
|
|
727
|
+
} else if (bufferGap <= rebufferGap) {
|
|
728
|
+
shouldRebuffer = true;
|
|
729
|
+
rebufferEndPosition = currentTime + bufferGap;
|
|
689
730
|
}
|
|
690
731
|
} else if (prevRebuffering !== null) {
|
|
691
732
|
const resumeGap = getRebufferingEndGap(prevRebuffering, lowLatencyMode);
|
|
692
733
|
if (shouldRebuffer !== true && prevRebuffering !== null && readyState > 1 &&
|
|
693
|
-
(fullyLoaded || ended ||
|
|
734
|
+
(fullyLoaded || ended ||
|
|
735
|
+
(bufferGap !== undefined && isFinite(bufferGap) && bufferGap > resumeGap)) ||
|
|
736
|
+
(bufferGap === undefined && readyState >= 3))
|
|
694
737
|
{
|
|
695
738
|
shouldStopRebuffer = true;
|
|
696
|
-
} else if (bufferGap ===
|
|
697
|
-
rebufferEndPosition =
|
|
698
|
-
|
|
739
|
+
} else if (bufferGap === undefined) {
|
|
740
|
+
rebufferEndPosition = undefined;
|
|
741
|
+
} else if (bufferGap === Infinity) {
|
|
742
|
+
rebufferEndPosition = currentTime;
|
|
743
|
+
} else if (bufferGap <= resumeGap) {
|
|
744
|
+
rebufferEndPosition = currentTime + bufferGap;
|
|
699
745
|
}
|
|
700
746
|
}
|
|
701
747
|
}
|
|
@@ -705,17 +751,34 @@ function getRebufferingStatus(
|
|
|
705
751
|
// between two consecutive timeupdates
|
|
706
752
|
else {
|
|
707
753
|
if (canSwitchToRebuffering &&
|
|
708
|
-
(
|
|
709
|
-
|
|
710
|
-
|
|
754
|
+
(
|
|
755
|
+
(
|
|
756
|
+
!paused &&
|
|
757
|
+
currentEvt === "timeupdate" && prevEvt === "timeupdate" &&
|
|
758
|
+
currentTime === prevTime
|
|
759
|
+
) ||
|
|
760
|
+
(
|
|
761
|
+
currentEvt === "seeking" && (
|
|
762
|
+
bufferGap === Infinity || (bufferGap === undefined && readyState < 3)
|
|
763
|
+
)
|
|
764
|
+
)
|
|
765
|
+
)
|
|
711
766
|
) {
|
|
712
767
|
shouldRebuffer = true;
|
|
713
|
-
} else if (
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
768
|
+
} else if (
|
|
769
|
+
prevRebuffering !== null &&
|
|
770
|
+
(
|
|
771
|
+
(currentEvt !== "seeking" && currentTime !== prevTime) ||
|
|
772
|
+
currentEvt === "canplay" ||
|
|
773
|
+
(bufferGap === undefined && readyState >= 3) ||
|
|
774
|
+
(
|
|
775
|
+
bufferGap !== undefined && bufferGap < Infinity &&
|
|
776
|
+
(
|
|
777
|
+
bufferGap > getRebufferingEndGap(prevRebuffering, lowLatencyMode) ||
|
|
778
|
+
fullyLoaded || ended
|
|
779
|
+
)
|
|
780
|
+
)
|
|
781
|
+
)
|
|
719
782
|
) {
|
|
720
783
|
shouldStopRebuffer = true;
|
|
721
784
|
}
|
|
@@ -775,6 +838,7 @@ function getFreezingStatus(
|
|
|
775
838
|
}
|
|
776
839
|
|
|
777
840
|
return currentInfo.event === "timeupdate" &&
|
|
841
|
+
currentInfo.bufferGap !== undefined &&
|
|
778
842
|
currentInfo.bufferGap > MINIMUM_BUFFER_AMOUNT_BEFORE_FREEZING &&
|
|
779
843
|
!currentInfo.ended &&
|
|
780
844
|
!currentInfo.paused &&
|
|
@@ -41,6 +41,7 @@ import {
|
|
|
41
41
|
switchMap,
|
|
42
42
|
take,
|
|
43
43
|
takeUntil,
|
|
44
|
+
tap,
|
|
44
45
|
} from "rxjs";
|
|
45
46
|
import {
|
|
46
47
|
events,
|
|
@@ -119,7 +120,6 @@ import {
|
|
|
119
120
|
IManifestFetcherParsedResult,
|
|
120
121
|
IManifestFetcherWarningEvent,
|
|
121
122
|
ManifestFetcher,
|
|
122
|
-
SegmentFetcherCreator,
|
|
123
123
|
} from "../fetchers";
|
|
124
124
|
import initializeMediaSourcePlayback, {
|
|
125
125
|
IInitEvent,
|
|
@@ -135,6 +135,7 @@ import { IInbandEvent } from "../stream";
|
|
|
135
135
|
import {
|
|
136
136
|
checkReloadOptions,
|
|
137
137
|
IParsedLoadVideoOptions,
|
|
138
|
+
IParsedStartAtOption,
|
|
138
139
|
parseConstructorOptions,
|
|
139
140
|
parseLoadVideoOptions,
|
|
140
141
|
} from "./option_utils";
|
|
@@ -372,10 +373,35 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
372
373
|
/** Determines whether or not the player should stop at the end of video playback. */
|
|
373
374
|
private readonly _priv_stopAtEnd : boolean;
|
|
374
375
|
|
|
375
|
-
/**
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
376
|
+
/**
|
|
377
|
+
* Information that can be relied on once `reload` is called.
|
|
378
|
+
* It should refer to the last content being played.
|
|
379
|
+
*/
|
|
380
|
+
private _priv_reloadingMetadata : {
|
|
381
|
+
/**
|
|
382
|
+
* `loadVideo` options communicated for the last content that will be re-used
|
|
383
|
+
* on reload.
|
|
384
|
+
*/
|
|
385
|
+
options?: IParsedLoadVideoOptions;
|
|
386
|
+
/**
|
|
387
|
+
* Manifest loaded for the last content that should be used once `reload`
|
|
388
|
+
* is called.
|
|
389
|
+
*/
|
|
390
|
+
manifest?: Manifest;
|
|
391
|
+
/**
|
|
392
|
+
* If `true`, the player should be paused after reloading.
|
|
393
|
+
* If `false`, the player should be playing after reloading.
|
|
394
|
+
* If `undefined`, `reload` should depend on other criteria (such as the
|
|
395
|
+
* `autoPlay` option, to know whether the content should play or not after
|
|
396
|
+
* reloading.
|
|
397
|
+
*/
|
|
398
|
+
reloadInPause?: boolean;
|
|
399
|
+
/**
|
|
400
|
+
* If set this is the position that should be seeked to by default after
|
|
401
|
+
* reloading.
|
|
402
|
+
*/
|
|
403
|
+
reloadPosition?: number;
|
|
404
|
+
};
|
|
379
405
|
|
|
380
406
|
/** All possible Error types emitted by the RxPlayer. */
|
|
381
407
|
static get ErrorTypes() : Record<IErrorType, IErrorType> {
|
|
@@ -434,7 +460,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
434
460
|
// See: https://bugzilla.mozilla.org/show_bug.cgi?id=1194624
|
|
435
461
|
videoElement.preload = "auto";
|
|
436
462
|
|
|
437
|
-
this.version = /* PLAYER_VERSION */"3.29.0-dev.
|
|
463
|
+
this.version = /* PLAYER_VERSION */"3.29.0-dev.2022103100";
|
|
438
464
|
this.log = log;
|
|
439
465
|
this.state = "STOPPED";
|
|
440
466
|
this.videoElement = videoElement;
|
|
@@ -529,7 +555,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
529
555
|
this._priv_preferredTextTracks = preferredTextTracks;
|
|
530
556
|
this._priv_preferredVideoTracks = preferredVideoTracks;
|
|
531
557
|
|
|
532
|
-
this.
|
|
558
|
+
this._priv_reloadingMetadata = {};
|
|
533
559
|
}
|
|
534
560
|
|
|
535
561
|
/**
|
|
@@ -600,7 +626,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
600
626
|
this._priv_bitrateInfos.maxAutoBitrates.video.finish();
|
|
601
627
|
this._priv_bitrateInfos.maxAutoBitrates.audio.finish();
|
|
602
628
|
|
|
603
|
-
this.
|
|
629
|
+
this._priv_reloadingMetadata = {};
|
|
604
630
|
|
|
605
631
|
// un-attach video element
|
|
606
632
|
this.videoElement = null;
|
|
@@ -613,51 +639,56 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
613
639
|
loadVideo(opts : ILoadVideoOptions) : void {
|
|
614
640
|
const options = parseLoadVideoOptions(opts);
|
|
615
641
|
log.info("API: Calling loadvideo", options.url, options.transport);
|
|
616
|
-
this.
|
|
642
|
+
this._priv_reloadingMetadata = { options };
|
|
617
643
|
this._priv_initializeContentPlayback(options);
|
|
618
644
|
}
|
|
619
645
|
|
|
620
646
|
/**
|
|
621
|
-
* Reload last content.
|
|
622
|
-
* the manifest.
|
|
647
|
+
* Reload the last loaded content.
|
|
623
648
|
* @param {Object} reloadOpts
|
|
624
649
|
*/
|
|
625
|
-
reload(reloadOpts?: {
|
|
650
|
+
reload(reloadOpts?: {
|
|
651
|
+
reloadAt?: { position?: number; relative?: number };
|
|
652
|
+
autoPlay?: boolean;
|
|
653
|
+
}): void {
|
|
626
654
|
const { options,
|
|
627
655
|
manifest,
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
lastPlaybackPosition === undefined) {
|
|
656
|
+
reloadPosition,
|
|
657
|
+
reloadInPause } = this._priv_reloadingMetadata;
|
|
658
|
+
if (options === undefined) {
|
|
632
659
|
throw new Error("API: Can't reload without having previously loaded a content.");
|
|
633
660
|
}
|
|
634
661
|
checkReloadOptions(reloadOpts);
|
|
635
|
-
let
|
|
636
|
-
if (reloadOpts !== undefined
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
playbackPosition = lastPlaybackPosition;
|
|
644
|
-
} else {
|
|
645
|
-
if (this.videoElement === null) {
|
|
646
|
-
throw new Error("Can't reload when video element does not exist.");
|
|
647
|
-
}
|
|
648
|
-
playbackPosition = this.videoElement.currentTime;
|
|
649
|
-
}
|
|
650
|
-
if (reloadOpts !== undefined &&
|
|
651
|
-
reloadOpts.reloadAt !== undefined &&
|
|
652
|
-
reloadOpts.reloadAt.relative !== undefined) {
|
|
653
|
-
startAtPositon = reloadOpts.reloadAt.relative + playbackPosition;
|
|
662
|
+
let startAt : IParsedStartAtOption | undefined;
|
|
663
|
+
if (reloadOpts?.reloadAt?.position !== undefined) {
|
|
664
|
+
startAt = { position: reloadOpts.reloadAt.position };
|
|
665
|
+
} else if (reloadOpts?.reloadAt?.relative !== undefined) {
|
|
666
|
+
if (reloadPosition === undefined) {
|
|
667
|
+
throw new Error(
|
|
668
|
+
"Can't reload to a relative position when previous content was not loaded."
|
|
669
|
+
);
|
|
654
670
|
} else {
|
|
655
|
-
|
|
671
|
+
startAt = { position: reloadOpts.reloadAt.relative + reloadPosition };
|
|
656
672
|
}
|
|
673
|
+
} else if (reloadPosition !== undefined) {
|
|
674
|
+
startAt = { position: reloadPosition };
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
let autoPlay : boolean | undefined;
|
|
678
|
+
if (reloadOpts?.autoPlay !== undefined) {
|
|
679
|
+
autoPlay = reloadOpts.autoPlay;
|
|
680
|
+
} else if (reloadInPause !== undefined) {
|
|
681
|
+
autoPlay = !reloadInPause;
|
|
657
682
|
}
|
|
683
|
+
|
|
658
684
|
const newOptions = { ...options,
|
|
659
685
|
initialManifest: manifest };
|
|
660
|
-
|
|
686
|
+
if (startAt !== undefined) {
|
|
687
|
+
newOptions.startAt = startAt;
|
|
688
|
+
}
|
|
689
|
+
if (autoPlay !== undefined) {
|
|
690
|
+
newOptions.autoPlay = autoPlay;
|
|
691
|
+
}
|
|
661
692
|
this._priv_initializeContentPlayback(newOptions);
|
|
662
693
|
}
|
|
663
694
|
|
|
@@ -758,14 +789,6 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
758
789
|
maxRetryOffline: offlineRetry,
|
|
759
790
|
requestTimeout: manifestRequestTimeout });
|
|
760
791
|
|
|
761
|
-
/** Interface used to download segments. */
|
|
762
|
-
const segmentFetcherCreator = new SegmentFetcherCreator(
|
|
763
|
-
transportPipelines,
|
|
764
|
-
{ lowLatencyMode,
|
|
765
|
-
maxRetryOffline: offlineRetry,
|
|
766
|
-
maxRetryRegular: segmentRetry,
|
|
767
|
-
requestTimeout: segmentRequestTimeout });
|
|
768
|
-
|
|
769
792
|
/** Observable emitting the initial Manifest */
|
|
770
793
|
let manifest$ : Observable<IManifestFetcherParsedResult |
|
|
771
794
|
IManifestFetcherWarningEvent>;
|
|
@@ -865,6 +888,10 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
865
888
|
onCodecSwitch },
|
|
866
889
|
this._priv_bufferOptions);
|
|
867
890
|
|
|
891
|
+
const segmentRequestOptions = { regularError: segmentRetry,
|
|
892
|
+
requestTimeout: segmentRequestTimeout,
|
|
893
|
+
offlineError: offlineRetry };
|
|
894
|
+
|
|
868
895
|
// We've every options set up. Start everything now
|
|
869
896
|
const init$ = initializeMediaSourcePlayback({ adaptiveOptions,
|
|
870
897
|
autoPlay,
|
|
@@ -876,9 +903,10 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
876
903
|
manifestFetcher,
|
|
877
904
|
mediaElement: videoElement,
|
|
878
905
|
minimumManifestUpdateInterval,
|
|
879
|
-
|
|
906
|
+
segmentRequestOptions,
|
|
880
907
|
speed: this._priv_speed,
|
|
881
908
|
startAt,
|
|
909
|
+
transport: transportPipelines,
|
|
882
910
|
textTrackOptions })
|
|
883
911
|
.pipe(takeUntil(stoppedContent$));
|
|
884
912
|
|
|
@@ -1038,10 +1066,51 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
1038
1066
|
}
|
|
1039
1067
|
});
|
|
1040
1068
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1069
|
+
/**
|
|
1070
|
+
* Function updating `this._priv_reloadingMetadata` in function of the
|
|
1071
|
+
* current state and playback conditions.
|
|
1072
|
+
* To call when either might change.
|
|
1073
|
+
* @param {string} state - The player state we're about to switch to.
|
|
1074
|
+
*/
|
|
1075
|
+
const updateReloadingMetadata = (state : IPlayerState) => {
|
|
1076
|
+
switch (state) {
|
|
1077
|
+
case "STOPPED":
|
|
1078
|
+
case "RELOADING":
|
|
1079
|
+
case "LOADING":
|
|
1080
|
+
break; // keep previous metadata
|
|
1081
|
+
case "ENDED":
|
|
1082
|
+
this._priv_reloadingMetadata.reloadInPause = true;
|
|
1083
|
+
this._priv_reloadingMetadata.reloadPosition =
|
|
1084
|
+
playbackObserver.getReference().getValue().position;
|
|
1085
|
+
break;
|
|
1086
|
+
default:
|
|
1087
|
+
const o = playbackObserver.getReference().getValue();
|
|
1088
|
+
this._priv_reloadingMetadata.reloadInPause = o.paused;
|
|
1089
|
+
this._priv_reloadingMetadata.reloadPosition = o.position;
|
|
1090
|
+
break;
|
|
1091
|
+
}
|
|
1092
|
+
};
|
|
1093
|
+
|
|
1094
|
+
playerState$.pipe(
|
|
1095
|
+
tap(newState => {
|
|
1096
|
+
updateReloadingMetadata(newState);
|
|
1097
|
+
this._priv_setPlayerState(newState);
|
|
1098
|
+
|
|
1099
|
+
// Previous call could have performed all kind of side-effects, thus,
|
|
1100
|
+
// we re-check the current state associated to the RxPlayer
|
|
1101
|
+
if (this.state === "ENDED" && this._priv_stopAtEnd) {
|
|
1102
|
+
currentContentCanceller.cancel();
|
|
1103
|
+
}
|
|
1104
|
+
}),
|
|
1105
|
+
map(state => state !== "RELOADING" && state !== "STOPPED"),
|
|
1106
|
+
distinctUntilChanged(),
|
|
1107
|
+
switchMap(canSendObservation => canSendObservation ? observation$ :
|
|
1108
|
+
EMPTY),
|
|
1109
|
+
takeUntil(stoppedContent$)
|
|
1110
|
+
).subscribe(o => {
|
|
1111
|
+
updateReloadingMetadata(this.state);
|
|
1112
|
+
this._priv_triggerPositionUpdate(o);
|
|
1113
|
+
});
|
|
1045
1114
|
|
|
1046
1115
|
// Link "seeking" and "seeked" events (once the content is loaded)
|
|
1047
1116
|
loaded$.pipe(
|
|
@@ -1052,19 +1121,6 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
1052
1121
|
this.trigger(evt, null);
|
|
1053
1122
|
});
|
|
1054
1123
|
|
|
1055
|
-
// Handle state updates
|
|
1056
|
-
playerState$
|
|
1057
|
-
.pipe(takeUntil(stoppedContent$))
|
|
1058
|
-
.subscribe(newState => {
|
|
1059
|
-
this._priv_setPlayerState(newState);
|
|
1060
|
-
|
|
1061
|
-
// Previous call could have performed all kind of side-effects, thus,
|
|
1062
|
-
// we re-check the current state associated to the RxPlayer
|
|
1063
|
-
if (this.state === "ENDED" && this._priv_stopAtEnd) {
|
|
1064
|
-
currentContentCanceller.cancel();
|
|
1065
|
-
}
|
|
1066
|
-
});
|
|
1067
|
-
|
|
1068
1124
|
// Link playback events to the corresponding callbacks
|
|
1069
1125
|
playback$.subscribe({
|
|
1070
1126
|
next: (x) => this._priv_onPlaybackEvent(x),
|
|
@@ -2498,7 +2554,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
2498
2554
|
return;
|
|
2499
2555
|
}
|
|
2500
2556
|
contentInfos.manifest = manifest;
|
|
2501
|
-
this.
|
|
2557
|
+
this._priv_reloadingMetadata.manifest = manifest;
|
|
2502
2558
|
|
|
2503
2559
|
const { initialAudioTrack, initialTextTrack } = contentInfos;
|
|
2504
2560
|
this._priv_trackChoiceManager = new TrackChoiceManager({
|
|
@@ -2859,17 +2915,11 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
2859
2915
|
return;
|
|
2860
2916
|
}
|
|
2861
2917
|
|
|
2862
|
-
if (this.state === PLAYER_STATES.RELOADING) {
|
|
2863
|
-
return;
|
|
2864
|
-
}
|
|
2865
|
-
|
|
2866
2918
|
const { isDirectFile, manifest } = this._priv_contentInfos;
|
|
2867
2919
|
if ((!isDirectFile && manifest === null) || isNullOrUndefined(observation)) {
|
|
2868
2920
|
return;
|
|
2869
2921
|
}
|
|
2870
2922
|
|
|
2871
|
-
this._priv_lastContentPlaybackInfos.lastPlaybackPosition = observation.position;
|
|
2872
|
-
|
|
2873
2923
|
const maximumPosition = manifest !== null ? manifest.getMaximumSafePosition() :
|
|
2874
2924
|
undefined;
|
|
2875
2925
|
const positionData : IPositionUpdate = {
|
|
@@ -2878,9 +2928,11 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
2878
2928
|
playbackRate: observation.playbackRate,
|
|
2879
2929
|
maximumBufferTime: maximumPosition,
|
|
2880
2930
|
|
|
2881
|
-
// TODO
|
|
2882
|
-
bufferGap:
|
|
2883
|
-
|
|
2931
|
+
// TODO bufferGap may be undefined
|
|
2932
|
+
bufferGap: observation.bufferGap === undefined ||
|
|
2933
|
+
!isFinite(observation.bufferGap) ?
|
|
2934
|
+
0 :
|
|
2935
|
+
observation.bufferGap,
|
|
2884
2936
|
};
|
|
2885
2937
|
|
|
2886
2938
|
if (manifest !== null &&
|
|
@@ -2950,7 +3002,7 @@ class Player extends EventEmitter<IPublicAPIEvent> {
|
|
|
2950
3002
|
return activeRepresentations[currentPeriod.id];
|
|
2951
3003
|
}
|
|
2952
3004
|
}
|
|
2953
|
-
Player.version = /* PLAYER_VERSION */"3.29.0-dev.
|
|
3005
|
+
Player.version = /* PLAYER_VERSION */"3.29.0-dev.2022103100";
|
|
2954
3006
|
|
|
2955
3007
|
/** Every events sent by the RxPlayer's public API. */
|
|
2956
3008
|
interface IPublicAPIEvent {
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* It always should be imported through the `features` object.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
+
import { enableAudioTrack } from "../../../compat";
|
|
22
23
|
import {
|
|
23
24
|
ICompatAudioTrack,
|
|
24
25
|
ICompatAudioTrackList,
|
|
@@ -39,7 +40,6 @@ import {
|
|
|
39
40
|
IAvailableAudioTrack,
|
|
40
41
|
IAvailableTextTrack,
|
|
41
42
|
} from "../../../public_types";
|
|
42
|
-
import assert from "../../../utils/assert";
|
|
43
43
|
import EventEmitter from "../../../utils/event_emitter";
|
|
44
44
|
import normalizeLanguage from "../../../utils/languages";
|
|
45
45
|
|
|
@@ -913,16 +913,8 @@ export default class MediaElementTrackChoiceManager
|
|
|
913
913
|
* @param {number} index}
|
|
914
914
|
*/
|
|
915
915
|
private _enableAudioTrackFromIndex(index : number) : void {
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
// Seen on Safari MacOS only (2022-02-14), not disabling ALL audio tracks
|
|
919
|
-
// first (even the wanted one), can lead to the media not playing.
|
|
920
|
-
for (const audioTrack of this._audioTracks) {
|
|
921
|
-
audioTrack.nativeTrack.enabled = false;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
this._audioTracks[index].nativeTrack.enabled = true;
|
|
925
|
-
return;
|
|
916
|
+
enableAudioTrack(this._audioTracks.map(({ nativeTrack }) => nativeTrack),
|
|
917
|
+
index);
|
|
926
918
|
}
|
|
927
919
|
}
|
|
928
920
|
|