bitmovin-player-ui 4.2.0 → 4.3.0
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 +20 -0
- package/dist/js/bitmovinplayer-ui.js +1 -1
- package/dist/js/bitmovinplayer-ui.js.map +1 -1
- package/dist/js/framework/UIFactory.js +1 -2
- package/dist/js/framework/components/Container.d.ts +1 -1
- package/dist/js/framework/components/UIContainer.d.ts +7 -1
- package/dist/js/framework/components/UIContainer.js +33 -2
- package/dist/js/framework/components/ads/AdMessageLabel.d.ts +22 -3
- package/dist/js/framework/components/ads/AdMessageLabel.js +40 -17
- package/dist/js/framework/components/overlays/DismissClickOverlay.js +7 -1
- package/dist/js/framework/components/settings/SettingsPanel.d.ts +28 -1
- package/dist/js/framework/components/settings/SettingsPanel.js +103 -7
- package/dist/js/framework/utils/StringUtils.d.ts +2 -2
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/AdClickOverlay.html +28 -28
- package/docs/classes/AdControlBar.html +31 -31
- package/docs/classes/AdCounterLabel.html +31 -31
- package/docs/classes/AdMessageLabel.html +51 -32
- package/docs/classes/AdSkipButton.html +27 -27
- package/docs/classes/AdStatusOverlay.html +31 -31
- package/docs/classes/AirPlayToggleButton.html +35 -35
- package/docs/classes/AudioQualitySelectBox.html +38 -38
- package/docs/classes/AudioTrackListBox.html +40 -39
- package/docs/classes/AudioTrackSelectBox.html +38 -38
- package/docs/classes/BackgroundColorSelectBox.html +38 -38
- package/docs/classes/BackgroundOpacitySelectBox.html +38 -38
- package/docs/classes/BrowserUtils.html +2 -2
- package/docs/classes/BufferingOverlay.html +31 -31
- package/docs/classes/Button.html +27 -27
- package/docs/classes/CastStatusOverlay.html +31 -31
- package/docs/classes/CastToggleButton.html +35 -35
- package/docs/classes/CastUIContainer.html +31 -31
- package/docs/classes/CharacterEdgeSelectBox.html +38 -38
- package/docs/classes/ClickOverlay.html +28 -28
- package/docs/classes/CloseButton.html +27 -27
- package/docs/classes/Component.html +25 -25
- package/docs/classes/Container.html +31 -31
- package/docs/classes/ControlBar.html +31 -31
- package/docs/classes/DynamicSettingsPanelItem.html +33 -33
- package/docs/classes/ErrorMessageOverlay.html +31 -31
- package/docs/classes/FontColorSelectBox.html +38 -38
- package/docs/classes/FontFamilySelectBox.html +38 -38
- package/docs/classes/FontOpacitySelectBox.html +38 -38
- package/docs/classes/FontSizeSelectBox.html +38 -38
- package/docs/classes/FullscreenToggleButton.html +35 -35
- package/docs/classes/HugePlaybackToggleButton.html +35 -35
- package/docs/classes/HugeReplayButton.html +27 -27
- package/docs/classes/I18n.html +2 -2
- package/docs/classes/Icon.html +25 -25
- package/docs/classes/ItemSelectionList.html +38 -38
- package/docs/classes/Label.html +31 -31
- package/docs/classes/ListBox.html +40 -39
- package/docs/classes/ListSelector.html +38 -38
- package/docs/classes/MetadataLabel.html +31 -31
- package/docs/classes/NavigationGroup.html +10 -10
- package/docs/classes/PictureInPictureToggleButton.html +35 -35
- package/docs/classes/PlaybackSpeedSelectBox.html +38 -38
- package/docs/classes/PlaybackTimeLabel.html +32 -32
- package/docs/classes/PlaybackToggleButton.html +35 -35
- package/docs/classes/PlaybackToggleOverlay.html +31 -31
- package/docs/classes/PlayerUtils.LiveStreamDetector.html +2 -2
- package/docs/classes/PlayerUtils.TimeShiftAvailabilityDetector.html +2 -2
- package/docs/classes/PlayerWrapper.html +4 -4
- package/docs/classes/QuickSeekButton.html +27 -27
- package/docs/classes/RecommendationItem.html +25 -25
- package/docs/classes/RecommendationOverlay.html +31 -31
- package/docs/classes/ReplayButton.html +27 -27
- package/docs/classes/RootNavigationGroup.html +10 -10
- package/docs/classes/SeekBar.html +36 -36
- package/docs/classes/SeekBarLabel.html +35 -35
- package/docs/classes/SelectBox.html +38 -38
- package/docs/classes/SettingsPanel.html +40 -39
- package/docs/classes/SettingsPanelItem.html +33 -33
- package/docs/classes/SettingsPanelNavigationGroup.html +10 -10
- package/docs/classes/SettingsPanelNavigationGroupConfig.html +2 -2
- package/docs/classes/SettingsPanelPage.html +33 -33
- package/docs/classes/SettingsPanelPageBackButton.html +29 -29
- package/docs/classes/SettingsPanelPageOpenButton.html +29 -29
- package/docs/classes/SettingsToggleButton.html +35 -35
- package/docs/classes/Spacer.html +25 -25
- package/docs/classes/SpatialNavigation.html +4 -4
- package/docs/classes/SubtitleListBox.html +40 -39
- package/docs/classes/SubtitleOverlay.html +31 -31
- package/docs/classes/SubtitleSelectBox.html +38 -38
- package/docs/classes/SubtitleSettingSelectBox.html +38 -38
- package/docs/classes/SubtitleSettingsPanelPage.html +33 -33
- package/docs/classes/SubtitleSettingsResetButton.html +27 -27
- package/docs/classes/TitleBar.html +31 -31
- package/docs/classes/ToggleButton.html +35 -35
- package/docs/classes/UIContainer.html +31 -31
- package/docs/classes/UIInstanceManager.html +14 -14
- package/docs/classes/UIManager.html +14 -14
- package/docs/classes/VRToggleButton.html +35 -35
- package/docs/classes/VideoQualitySelectBox.html +39 -39
- package/docs/classes/VolumeControlButton.html +33 -33
- package/docs/classes/VolumeSlider.html +36 -36
- package/docs/classes/VolumeToggleButton.html +35 -35
- package/docs/classes/Watermark.html +28 -28
- package/docs/classes/WindowColorSelectBox.html +38 -38
- package/docs/classes/WindowOpacitySelectBox.html +38 -38
- package/docs/enums/ButtonStyle.html +5 -5
- package/docs/enums/LabelStyle.html +4 -4
- package/docs/enums/MetadataLabelContent.html +3 -3
- package/docs/enums/NavigationDirection.html +2 -2
- package/docs/enums/PlaybackTimeLabelMode.html +5 -5
- package/docs/enums/PlayerUtils.PlayerState.html +2 -2
- package/docs/enums/UIUtils.KeyCode.html +2 -2
- package/docs/enums/ViewMode.html +3 -3
- package/docs/functions/ArrayUtils.remove.html +1 -1
- package/docs/functions/ErrorUtils.defaultMobileV3ErrorMessageTranslator.html +1 -1
- package/docs/functions/PlayerUtils.clampValueToRange.html +1 -1
- package/docs/functions/PlayerUtils.getCurrentTimeRelativeToSeekableRange.html +1 -1
- package/docs/functions/PlayerUtils.getSeekableRangeRespectingLive.html +1 -1
- package/docs/functions/PlayerUtils.getSeekableRangeStart.html +1 -1
- package/docs/functions/PlayerUtils.getState.html +1 -1
- package/docs/functions/PlayerUtils.isTimeShiftAvailable.html +1 -1
- package/docs/functions/StorageUtils.getItem.html +1 -1
- package/docs/functions/StorageUtils.getObject.html +1 -1
- package/docs/functions/StorageUtils.setItem.html +1 -1
- package/docs/functions/StorageUtils.setObject.html +1 -1
- package/docs/functions/StorageUtils.setStorageApiDisabled.html +1 -1
- package/docs/functions/StringUtils.replaceAdMessagePlaceholders.html +1 -1
- package/docs/functions/StringUtils.secondsToText.html +1 -1
- package/docs/functions/StringUtils.secondsToTime.html +1 -1
- package/docs/functions/UIFactory.buildCastReceiverUI.html +1 -1
- package/docs/functions/UIFactory.buildSmallScreenUI.html +1 -1
- package/docs/functions/UIFactory.buildSubtitleUI.html +1 -1
- package/docs/functions/UIFactory.buildTvUI.html +1 -1
- package/docs/functions/UIFactory.buildUI.html +1 -1
- package/docs/functions/UIUtils.traverseTree.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/ActiveUiChangedArgs.html +3 -3
- package/docs/interfaces/AdControlBarConfig.html +12 -12
- package/docs/interfaces/AdSkipButtonConfig.html +16 -16
- package/docs/interfaces/BufferingOverlayConfig.html +13 -13
- package/docs/interfaces/ButtonConfig.html +14 -14
- package/docs/interfaces/ClickOverlayConfig.html +15 -15
- package/docs/interfaces/CloseButtonConfig.html +15 -15
- package/docs/interfaces/ComponentConfig.html +11 -11
- package/docs/interfaces/ComponentFocusChangedEventArgs.html +2 -2
- package/docs/interfaces/ComponentHoverChangedEventArgs.html +2 -2
- package/docs/interfaces/ContainerConfig.html +12 -12
- package/docs/interfaces/ControlBarConfig.html +12 -12
- package/docs/interfaces/DynamicSettingsPanelItemConfig.html +19 -19
- package/docs/interfaces/ErrorMessageMap.html +1 -1
- package/docs/interfaces/ErrorMessageOverlayConfig.html +13 -13
- package/docs/interfaces/ErrorMessageTranslator.html +1 -1
- package/docs/interfaces/ExternalRecommendationLink.html +3 -3
- package/docs/interfaces/IconConfig.html +12 -12
- package/docs/interfaces/InternalUIConfig.html +15 -15
- package/docs/interfaces/LabelConfig.html +14 -14
- package/docs/interfaces/ListBoxConfig.html +22 -17
- package/docs/interfaces/ListItem.html +2 -2
- package/docs/interfaces/ListItemFilter.html +1 -1
- package/docs/interfaces/ListItemLabelTranslator.html +1 -1
- package/docs/interfaces/ListSelectorConfig.html +11 -11
- package/docs/interfaces/LocalizationConfig.html +3 -3
- package/docs/interfaces/MetadataLabelConfig.html +15 -15
- package/docs/interfaces/PlaybackTimeLabelConfig.html +16 -16
- package/docs/interfaces/PlaybackToggleButtonConfig.html +19 -19
- package/docs/interfaces/PlaybackToggleOverlayConfig.html +13 -13
- package/docs/interfaces/PlayerUtils.LiveStreamDetectorEventArgs.html +2 -2
- package/docs/interfaces/PlayerUtils.TimeShiftAvailabilityChangedArgs.html +2 -2
- package/docs/interfaces/QuickSeekButtonConfig.html +15 -15
- package/docs/interfaces/RecommendationConfig.html +4 -4
- package/docs/interfaces/RecommendationItemConfig.html +12 -12
- package/docs/interfaces/SeekBarConfig.html +19 -19
- package/docs/interfaces/SeekBarLabelConfig.html +12 -12
- package/docs/interfaces/SeekBarMarker.html +2 -2
- package/docs/interfaces/SeekPreviewArgs.html +3 -3
- package/docs/interfaces/SeekPreviewEventArgs.html +4 -4
- package/docs/interfaces/SettingsPanelConfig.html +20 -15
- package/docs/interfaces/SettingsPanelItemConfig.html +17 -17
- package/docs/interfaces/SettingsPanelPageConfig.html +13 -13
- package/docs/interfaces/SettingsToggleButtonConfig.html +20 -20
- package/docs/interfaces/SubtitleSettingSelectBoxConfig.html +11 -11
- package/docs/interfaces/SubtitleSettingsPanelPageConfig.html +13 -13
- package/docs/interfaces/TimelineMarker.html +6 -6
- package/docs/interfaces/TitleBarConfig.html +13 -13
- package/docs/interfaces/ToggleButtonConfig.html +18 -18
- package/docs/interfaces/UIConditionContext.html +10 -10
- package/docs/interfaces/UIConditionResolver.html +1 -1
- package/docs/interfaces/UIConfig.html +14 -14
- package/docs/interfaces/UIContainerConfig.html +20 -16
- package/docs/interfaces/UIUtils.TreeTraversalCallback.html +1 -1
- package/docs/interfaces/UIVariant.html +2 -2
- package/docs/interfaces/ViewModeChangedEventArgs.html +2 -2
- package/docs/interfaces/Vocabularies.html +1 -1
- package/docs/interfaces/Vocabulary.html +2 -2
- package/docs/interfaces/VolumeControlButtonConfig.html +14 -14
- package/docs/interfaces/VolumeSliderConfig.html +21 -21
- package/docs/interfaces/WatermarkConfig.html +15 -15
- package/docs/interfaces/WrappedPlayer.html +2 -2
- package/docs/media/CHANGELOG.md +20 -0
- package/docs/types/CustomVocabulary.html +1 -1
- package/docs/types/LocalizableText.html +1 -1
- package/docs/types/Localizer.html +1 -1
- package/docs/variables/ErrorUtils.defaultErrorMessages.html +1 -1
- package/docs/variables/ErrorUtils.defaultWebErrorMessageTranslator.html +1 -1
- package/docs/variables/StringUtils.FORMAT_HHMMSS.html +1 -1
- package/docs/variables/StringUtils.FORMAT_MMSS.html +1 -1
- package/docs/variables/i18n.html +1 -1
- package/docs/variables/version.html +1 -1
- package/package.json +1 -1
- package/src/ts/DOM.ts +18 -18
- package/src/ts/EventDispatcher.ts +5 -5
- package/src/ts/UIFactory.ts +8 -9
- package/src/ts/UIManager.ts +29 -29
- package/src/ts/components/CastUIContainer.ts +6 -6
- package/src/ts/components/Component.ts +3 -3
- package/src/ts/components/Container.ts +5 -5
- package/src/ts/components/RecommendationItem.ts +2 -2
- package/src/ts/components/TvNoiseCanvas.ts +3 -3
- package/src/ts/components/UIContainer.ts +57 -14
- package/src/ts/components/ads/AdClickOverlay.ts +2 -2
- package/src/ts/components/ads/AdMessageLabel.ts +47 -20
- package/src/ts/components/ads/AdSkipButton.ts +5 -5
- package/src/ts/components/buttons/Button.ts +1 -1
- package/src/ts/components/buttons/CastToggleButton.ts +1 -1
- package/src/ts/components/buttons/CloseButton.ts +1 -1
- package/src/ts/components/buttons/HugePlaybackToggleButton.ts +3 -3
- package/src/ts/components/buttons/PlaybackToggleButton.ts +3 -3
- package/src/ts/components/buttons/QuickSeekButton.ts +1 -1
- package/src/ts/components/buttons/SmallCenteredPlaybackToggleButton.ts +1 -1
- package/src/ts/components/buttons/VRToggleButton.ts +4 -4
- package/src/ts/components/buttons/VolumeControlButton.ts +2 -2
- package/src/ts/components/labels/Label.ts +1 -1
- package/src/ts/components/labels/MetadataLabel.ts +4 -4
- package/src/ts/components/labels/PlaybackTimeLabel.ts +13 -13
- package/src/ts/components/lists/ItemSelectionList.ts +3 -3
- package/src/ts/components/lists/ListSelector.ts +4 -4
- package/src/ts/components/overlays/CastStatusOverlay.ts +2 -2
- package/src/ts/components/overlays/ClickOverlay.ts +1 -1
- package/src/ts/components/overlays/DismissClickOverlay.ts +7 -2
- package/src/ts/components/overlays/ErrorMessageOverlay.ts +2 -2
- package/src/ts/components/overlays/RecommendationOverlay.ts +2 -2
- package/src/ts/components/overlays/SubtitleOverlay.ts +10 -10
- package/src/ts/components/seekbar/SeekBar.ts +37 -37
- package/src/ts/components/seekbar/SeekBarLabel.ts +15 -15
- package/src/ts/components/seekbar/VolumeSlider.ts +1 -1
- package/src/ts/components/settings/AudioQualitySelectBox.ts +4 -4
- package/src/ts/components/settings/DynamicSettingsPanelItem.ts +3 -3
- package/src/ts/components/settings/SelectBox.ts +3 -3
- package/src/ts/components/settings/SettingsPanel.ts +137 -10
- package/src/ts/components/settings/SettingsPanelItem.ts +1 -1
- package/src/ts/components/settings/SettingsPanelPage.ts +4 -4
- package/src/ts/components/settings/SettingsPanelSelectOption.ts +1 -1
- package/src/ts/components/settings/SettingsToggleButton.ts +3 -3
- package/src/ts/components/settings/VideoQualitySelectBox.ts +4 -4
- package/src/ts/components/settings/subtitlesettings/BackgroundColorSelectBox.ts +1 -1
- package/src/ts/components/settings/subtitlesettings/FontColorSelectBox.ts +1 -1
- package/src/ts/components/settings/subtitlesettings/WindowColorSelectBox.ts +1 -1
- package/src/ts/main.ts +2 -2
- package/src/ts/spatialnavigation/NavigationGroup.ts +2 -2
- package/src/ts/spatialnavigation/SettingsPanelNavigationGroup.ts +1 -1
- package/src/ts/utils/ArrayUtils.ts +1 -1
- package/src/ts/utils/AudioTrackUtils.ts +1 -1
- package/src/ts/utils/ImageLoader.ts +2 -2
- package/src/ts/utils/PlayerUtils.ts +4 -4
- package/src/ts/utils/StorageUtils.ts +3 -3
- package/src/ts/utils/StringUtils.ts +17 -17
- package/src/ts/utils/SubtitleSettingsManager.ts +3 -3
- package/src/ts/utils/SubtitleUtils.ts +1 -1
- package/src/ts/utils/UIUtils.ts +2 -2
|
@@ -33,7 +33,7 @@ export class HugePlaybackToggleButton extends PlaybackToggleButton {
|
|
|
33
33
|
this.config.enterFullscreenOnInitialPlayback = uimanager.getConfig().enterFullscreenOnInitialPlayback;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
const togglePlayback = () => {
|
|
37
37
|
if (player.isPlaying() || this.isPlayInitiated) {
|
|
38
38
|
player.pause('ui');
|
|
39
39
|
} else {
|
|
@@ -41,7 +41,7 @@ export class HugePlaybackToggleButton extends PlaybackToggleButton {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
const toggleFullscreen = () => {
|
|
45
45
|
if (player.getViewMode() === player.exports.ViewMode.Fullscreen) {
|
|
46
46
|
player.setViewMode(player.exports.ViewMode.Inline);
|
|
47
47
|
} else {
|
|
@@ -88,7 +88,7 @@ export class HugePlaybackToggleButton extends PlaybackToggleButton {
|
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
const now = Date.now();
|
|
92
92
|
|
|
93
93
|
if (now - clickTime < 200) {
|
|
94
94
|
// We have a double click inside the 200ms interval, just toggle fullscreen mode
|
|
@@ -54,7 +54,7 @@ export class PlaybackToggleButton extends ToggleButton<PlaybackToggleButtonConfi
|
|
|
54
54
|
let firstPlay = true;
|
|
55
55
|
|
|
56
56
|
// Handler to update button state based on player state
|
|
57
|
-
|
|
57
|
+
const playbackStateHandler = () => {
|
|
58
58
|
// If the UI is currently seeking, playback is temporarily stopped but the buttons should
|
|
59
59
|
// not reflect that and stay as-is (e.g indicate playback while seeking).
|
|
60
60
|
if (isSeeking) {
|
|
@@ -113,8 +113,8 @@ export class PlaybackToggleButton extends ToggleButton<PlaybackToggleButtonConfi
|
|
|
113
113
|
};
|
|
114
114
|
|
|
115
115
|
// Detect absence of timeshifting on live streams and add tagging class to convert button icons to play/stop
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
const timeShiftDetector = new PlayerUtils.TimeShiftAvailabilityDetector(player);
|
|
117
|
+
const liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);
|
|
118
118
|
|
|
119
119
|
timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(() => updateLiveState());
|
|
120
120
|
liveStreamDetector.onLiveChanged.subscribe(() => updateLiveState());
|
|
@@ -77,7 +77,7 @@ export class QuickSeekButton extends Button<QuickSeekButtonConfig> {
|
|
|
77
77
|
},
|
|
78
78
|
);
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
const liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);
|
|
81
81
|
liveStreamDetector.onLiveChanged.subscribe((sender, args: PlayerUtils.LiveStreamDetectorEventArgs) => {
|
|
82
82
|
isLive = args.live;
|
|
83
83
|
switchVisibility(isLive, hasTimeShift);
|
|
@@ -28,7 +28,7 @@ export class SmallCenteredPlaybackToggleButton extends PlaybackToggleButton {
|
|
|
28
28
|
this.config.enterFullscreenOnInitialPlayback = uimanager.getConfig().enterFullscreenOnInitialPlayback;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
const togglePlayback = () => {
|
|
32
32
|
if (player.isPlaying() || this.isPlayInitiated) {
|
|
33
33
|
player.pause('ui');
|
|
34
34
|
} else {
|
|
@@ -25,7 +25,7 @@ export class VRToggleButton extends ToggleButton<ToggleButtonConfig> {
|
|
|
25
25
|
configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
|
|
26
26
|
super.configure(player, uimanager);
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
const isVRConfigured = () => {
|
|
29
29
|
// VR availability cannot be checked through getVRStatus() because it is asynchronously populated and not
|
|
30
30
|
// available at UI initialization. As an alternative, we check the VR settings in the config.
|
|
31
31
|
// TODO use getVRStatus() through isVRStereoAvailable() once the player has been rewritten and the status is
|
|
@@ -34,12 +34,12 @@ export class VRToggleButton extends ToggleButton<ToggleButtonConfig> {
|
|
|
34
34
|
return source && Boolean(source.vr);
|
|
35
35
|
};
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
const isVRStereoAvailable = () => {
|
|
38
38
|
const source = player.getSource();
|
|
39
39
|
return player.vr && Boolean(source.vr);
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
const vrStateHandler = (ev: PlayerEventBase) => {
|
|
43
43
|
if (
|
|
44
44
|
ev.type === player.exports.PlayerEvent.Warning &&
|
|
45
45
|
(ev as WarningEvent).code !== player.exports.WarningCode.VR_RENDERING_ERROR
|
|
@@ -60,7 +60,7 @@ export class VRToggleButton extends ToggleButton<ToggleButtonConfig> {
|
|
|
60
60
|
}
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
const vrButtonVisibilityHandler = () => {
|
|
64
64
|
if (isVRConfigured()) {
|
|
65
65
|
this.show();
|
|
66
66
|
} else {
|
|
@@ -61,8 +61,8 @@ export class VolumeControlButton extends Container<VolumeControlButtonConfig> {
|
|
|
61
61
|
configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
|
|
62
62
|
super.configure(player, uimanager);
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const volumeToggleButton = this.getVolumeToggleButton();
|
|
65
|
+
const volumeSlider = this.getVolumeSlider();
|
|
66
66
|
|
|
67
67
|
this.volumeSliderHideTimeout = new Timeout(this.getConfig().hideDelay, () => {
|
|
68
68
|
volumeSlider.hide();
|
|
@@ -81,7 +81,7 @@ export class Label<Config extends LabelConfig> extends Component<Config> {
|
|
|
81
81
|
|
|
82
82
|
protected toDomElement(): DOM {
|
|
83
83
|
const tagName = this.config.for != null ? 'label' : 'span';
|
|
84
|
-
|
|
84
|
+
const textElement = new DOM(
|
|
85
85
|
'span',
|
|
86
86
|
{
|
|
87
87
|
class: this.prefixCss('ui-label-text'),
|
|
@@ -49,10 +49,10 @@ export class MetadataLabel extends Label<MetadataLabelConfig> {
|
|
|
49
49
|
configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
|
|
50
50
|
super.configure(player, uimanager);
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
const config = this.getConfig();
|
|
53
|
+
const uiconfig = uimanager.getConfig();
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
const init = () => {
|
|
56
56
|
switch (config.content) {
|
|
57
57
|
case MetadataLabelContent.Title:
|
|
58
58
|
this.setText(uiconfig.metadata.title);
|
|
@@ -63,7 +63,7 @@ export class MetadataLabel extends Label<MetadataLabelConfig> {
|
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
const unload = () => {
|
|
67
67
|
this.setText(null);
|
|
68
68
|
};
|
|
69
69
|
|
|
@@ -67,17 +67,17 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
67
67
|
configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
|
|
68
68
|
super.configure(player, uimanager);
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
const config = this.getConfig();
|
|
71
71
|
let live = false;
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
const liveCssClass = this.prefixCss('ui-playbacktimelabel-live');
|
|
73
|
+
const liveEdgeCssClass = this.prefixCss('ui-playbacktimelabel-live-edge');
|
|
74
74
|
let minWidth = 0;
|
|
75
75
|
|
|
76
|
-
|
|
76
|
+
const liveClickHandler = () => {
|
|
77
77
|
player.timeShift(0);
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
const updateLiveState = () => {
|
|
81
81
|
// Player is playing a live stream when the duration is infinite
|
|
82
82
|
live = player.isLive();
|
|
83
83
|
|
|
@@ -98,7 +98,7 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
const updateLiveTimeshiftState = () => {
|
|
102
102
|
if (!live) {
|
|
103
103
|
return;
|
|
104
104
|
}
|
|
@@ -117,14 +117,14 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
117
117
|
}
|
|
118
118
|
};
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
const playbackTimeHandler = () => {
|
|
121
121
|
if (!live && player.getDuration() !== Infinity) {
|
|
122
122
|
this.setTime(PlayerUtils.getCurrentTimeRelativeToSeekableRange(player), player.getDuration());
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// To avoid 'jumping' in the UI by varying label sizes due to non-monospaced fonts,
|
|
126
126
|
// we gradually increase the min-width with the content to reach a stable size.
|
|
127
|
-
|
|
127
|
+
const width = this.getDomElement().width();
|
|
128
128
|
if (width > minWidth) {
|
|
129
129
|
minWidth = width;
|
|
130
130
|
this.getDomElement().css({
|
|
@@ -133,7 +133,7 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
133
133
|
}
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
const updateTimeFormatBasedOnDuration = () => {
|
|
137
137
|
// Set time format depending on source duration
|
|
138
138
|
this.timeFormat =
|
|
139
139
|
Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600
|
|
@@ -142,7 +142,7 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
142
142
|
playbackTimeHandler();
|
|
143
143
|
};
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
const liveStreamDetector = new PlayerUtils.LiveStreamDetector(player, uimanager);
|
|
146
146
|
liveStreamDetector.onLiveChanged.subscribe((sender, args: LiveStreamDetectorEventArgs) => {
|
|
147
147
|
live = args.live;
|
|
148
148
|
playbackTimeHandler();
|
|
@@ -162,7 +162,7 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
162
162
|
player.on(player.exports.PlayerEvent.StallStarted, updateLiveTimeshiftState);
|
|
163
163
|
player.on(player.exports.PlayerEvent.StallEnded, updateLiveTimeshiftState);
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
const init = () => {
|
|
166
166
|
// Reset min-width when a new source is ready (especially for switching VOD/Live modes where the label content
|
|
167
167
|
// changes)
|
|
168
168
|
minWidth = 0;
|
|
@@ -183,8 +183,8 @@ export class PlaybackTimeLabel extends Label<PlaybackTimeLabelConfig> {
|
|
|
183
183
|
* @param durationSeconds the total duration in seconds
|
|
184
184
|
*/
|
|
185
185
|
setTime(playbackSeconds: number, durationSeconds: number) {
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
const currentTime = StringUtils.secondsToTime(playbackSeconds, this.timeFormat);
|
|
187
|
+
const totalTime = StringUtils.secondsToTime(durationSeconds, this.timeFormat);
|
|
188
188
|
|
|
189
189
|
switch ((<PlaybackTimeLabelConfig>this.config).timeLabelMode) {
|
|
190
190
|
case PlaybackTimeLabelMode.CurrentTime:
|
|
@@ -28,7 +28,7 @@ export class ItemSelectionList extends ListSelector<ListSelectorConfig> {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
protected toDomElement(): DOM {
|
|
31
|
-
|
|
31
|
+
const listElement = new DOM(
|
|
32
32
|
'ul',
|
|
33
33
|
{
|
|
34
34
|
id: this.config.id,
|
|
@@ -57,8 +57,8 @@ export class ItemSelectionList extends ListSelector<ListSelectorConfig> {
|
|
|
57
57
|
listItem.removeClass(this.prefixCss(ItemSelectionList.CLASS_SELECTED));
|
|
58
58
|
};
|
|
59
59
|
|
|
60
|
-
for (
|
|
61
|
-
|
|
60
|
+
for (const item of this.items) {
|
|
61
|
+
const listItem = new DOM('li', {
|
|
62
62
|
type: 'li',
|
|
63
63
|
class: this.prefixCss('ui-selectionlistitem'),
|
|
64
64
|
}).append(new DOM('a', {}).html(i18n.performLocalization(item.label)));
|
|
@@ -150,7 +150,7 @@ export abstract class ListSelector<Config extends ListSelectorConfig> extends Co
|
|
|
150
150
|
* @returns {boolean} true if removal was successful, false if the item is not part of this selector
|
|
151
151
|
*/
|
|
152
152
|
removeItem(key: string): boolean {
|
|
153
|
-
|
|
153
|
+
const index = this.getItemIndex(key);
|
|
154
154
|
if (index > -1) {
|
|
155
155
|
ArrayUtils.remove(this.items, this.items[index]);
|
|
156
156
|
this.onItemRemovedEvent(key);
|
|
@@ -171,7 +171,7 @@ export abstract class ListSelector<Config extends ListSelectorConfig> extends Co
|
|
|
171
171
|
return true;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
|
|
174
|
+
const index = this.getItemIndex(key);
|
|
175
175
|
|
|
176
176
|
if (index > -1) {
|
|
177
177
|
this.selectedItem = key;
|
|
@@ -220,7 +220,7 @@ export abstract class ListSelector<Config extends ListSelectorConfig> extends Co
|
|
|
220
220
|
*/
|
|
221
221
|
clearItems() {
|
|
222
222
|
// local copy for iteration after clear
|
|
223
|
-
|
|
223
|
+
const items = this.items;
|
|
224
224
|
// clear items
|
|
225
225
|
this.items = [];
|
|
226
226
|
|
|
@@ -228,7 +228,7 @@ export abstract class ListSelector<Config extends ListSelectorConfig> extends Co
|
|
|
228
228
|
this.selectedItem = null;
|
|
229
229
|
|
|
230
230
|
// fire events
|
|
231
|
-
for (
|
|
231
|
+
for (const item of items) {
|
|
232
232
|
this.onItemRemovedEvent(item.key);
|
|
233
233
|
}
|
|
234
234
|
}
|
|
@@ -34,7 +34,7 @@ export class CastStatusOverlay extends Container<ContainerConfig> {
|
|
|
34
34
|
player.on(player.exports.PlayerEvent.CastWaitingForDevice, (event: CastWaitingForDeviceEvent) => {
|
|
35
35
|
this.show();
|
|
36
36
|
// Get device name and update status text while connecting
|
|
37
|
-
|
|
37
|
+
const castDeviceName = event.castPayload.deviceName;
|
|
38
38
|
this.statusLabel.setText(i18n.getLocalizer('connectingTo', { castDeviceName }));
|
|
39
39
|
});
|
|
40
40
|
player.on(player.exports.PlayerEvent.CastStarted, (event: CastStartedEvent) => {
|
|
@@ -42,7 +42,7 @@ export class CastStatusOverlay extends Container<ContainerConfig> {
|
|
|
42
42
|
// For cases when a session is resumed, we do not receive the previous events and therefore show the status panel
|
|
43
43
|
// here too
|
|
44
44
|
this.show();
|
|
45
|
-
|
|
45
|
+
const castDeviceName = event.deviceName;
|
|
46
46
|
this.statusLabel.setText(i18n.getLocalizer('playingOn', { castDeviceName }));
|
|
47
47
|
});
|
|
48
48
|
player.on(player.exports.PlayerEvent.CastStopped, event => {
|
|
@@ -35,7 +35,7 @@ export class ClickOverlay extends Button<ClickOverlayConfig> {
|
|
|
35
35
|
super.initialize();
|
|
36
36
|
|
|
37
37
|
this.setUrl((<ClickOverlayConfig>this.config).url);
|
|
38
|
-
|
|
38
|
+
const element = this.getDomElement();
|
|
39
39
|
element.on('click', () => {
|
|
40
40
|
if (element.data('url')) {
|
|
41
41
|
window.open(element.data('url'), '_blank');
|
|
@@ -3,6 +3,7 @@ import { Component, ComponentConfig } from '../Component';
|
|
|
3
3
|
import { Container } from '../Container';
|
|
4
4
|
import { PlayerAPI } from 'bitmovin-player';
|
|
5
5
|
import { UIInstanceManager } from '../../UIManager';
|
|
6
|
+
import { SettingsPanel } from '../settings/SettingsPanel';
|
|
6
7
|
|
|
7
8
|
export interface DismissClickOverlayConfig extends ButtonConfig {
|
|
8
9
|
target: Component<ComponentConfig>;
|
|
@@ -32,9 +33,13 @@ export class DismissClickOverlay extends Container<DismissClickOverlayConfig> {
|
|
|
32
33
|
this.hide();
|
|
33
34
|
});
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
const element = this.getDomElement();
|
|
36
37
|
element.on('click', () => {
|
|
37
|
-
this.config.target
|
|
38
|
+
if (this.config.target instanceof SettingsPanel) {
|
|
39
|
+
this.config.target.hideAndReset();
|
|
40
|
+
} else {
|
|
41
|
+
this.config.target.hide();
|
|
42
|
+
}
|
|
38
43
|
});
|
|
39
44
|
}
|
|
40
45
|
}
|
|
@@ -113,7 +113,7 @@ export class ErrorMessageOverlay extends Container<ErrorMessageOverlayConfig> {
|
|
|
113
113
|
configure(player: PlayerAPI | MobileV3PlayerAPI, uimanager: UIInstanceManager): void {
|
|
114
114
|
super.configure(player, uimanager);
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
const config = this.getConfig();
|
|
117
117
|
|
|
118
118
|
const handleErrorMessage = (
|
|
119
119
|
event: ErrorEvent | MobileV3SourceErrorEvent | MobileV3PlayerErrorEvent,
|
|
@@ -137,7 +137,7 @@ export class ErrorMessageOverlay extends Container<ErrorMessageOverlayConfig> {
|
|
|
137
137
|
player.on(MobileV3PlayerEvent.SourceError, errorEventHandler);
|
|
138
138
|
} else {
|
|
139
139
|
player.on(player.exports.PlayerEvent.Error, (event: ErrorEvent) => {
|
|
140
|
-
|
|
140
|
+
const message = ErrorUtils.defaultWebErrorMessageTranslator(event);
|
|
141
141
|
handleErrorMessage(event, message);
|
|
142
142
|
});
|
|
143
143
|
}
|
|
@@ -42,13 +42,13 @@ export class RecommendationOverlay extends Container<ContainerConfig> {
|
|
|
42
42
|
configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
|
|
43
43
|
super.configure(player, uimanager);
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
const clearRecommendations = () => {
|
|
46
46
|
this.recommendationContainer.removeComponents();
|
|
47
47
|
this.recommendationContainer.updateComponents();
|
|
48
48
|
this.getDomElement().removeClass(this.prefixCss(RecommendationOverlay.CLASS_HAS_RECOMMENDATIONS));
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
const setupRecommendations = () => {
|
|
52
52
|
clearRecommendations();
|
|
53
53
|
|
|
54
54
|
const recommendations = uimanager.getConfig().metadata.recommendations;
|
|
@@ -66,7 +66,7 @@ export class SubtitleOverlay extends Container<ContainerConfig> {
|
|
|
66
66
|
configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
|
|
67
67
|
super.configure(player, uimanager);
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
const subtitleManager = new ActiveSubtitleManager();
|
|
70
70
|
this.subtitleManager = subtitleManager;
|
|
71
71
|
|
|
72
72
|
this.subtitleContainerManager = new SubtitleRegionContainerManager(this);
|
|
@@ -107,7 +107,7 @@ export class SubtitleOverlay extends Container<ContainerConfig> {
|
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
player.on(player.exports.PlayerEvent.CueExit, (event: SubtitleCueEvent) => {
|
|
110
|
-
|
|
110
|
+
const labelToRemove = subtitleManager.cueExit(event);
|
|
111
111
|
|
|
112
112
|
if (labelToRemove) {
|
|
113
113
|
this.subtitleContainerManager.removeLabel(labelToRemove);
|
|
@@ -124,7 +124,7 @@ export class SubtitleOverlay extends Container<ContainerConfig> {
|
|
|
124
124
|
}
|
|
125
125
|
});
|
|
126
126
|
|
|
127
|
-
|
|
127
|
+
const subtitleClearHandler = () => {
|
|
128
128
|
this.hide();
|
|
129
129
|
this.subtitleContainerManager.clear();
|
|
130
130
|
subtitleManager.clear();
|
|
@@ -405,7 +405,7 @@ export class SubtitleOverlay extends Container<ContainerConfig> {
|
|
|
405
405
|
label.regionStyle = `line-height: ${fontSize}px;`;
|
|
406
406
|
};
|
|
407
407
|
|
|
408
|
-
for (
|
|
408
|
+
for (const label of this.getComponents()) {
|
|
409
409
|
if (label instanceof SubtitleRegionContainer) {
|
|
410
410
|
label.getComponents().forEach((l: SubtitleLabel) => {
|
|
411
411
|
updateLabel(l);
|
|
@@ -595,7 +595,7 @@ class ActiveSubtitleManager {
|
|
|
595
595
|
}
|
|
596
596
|
|
|
597
597
|
private addCueToMap(event: SubtitleCueEvent, label: SubtitleLabel): void {
|
|
598
|
-
|
|
598
|
+
const id = ActiveSubtitleManager.calculateId(event);
|
|
599
599
|
|
|
600
600
|
// Create array for id if it does not exist
|
|
601
601
|
this.activeSubtitleCueMap[id] = this.activeSubtitleCueMap[id] || [];
|
|
@@ -606,8 +606,8 @@ class ActiveSubtitleManager {
|
|
|
606
606
|
}
|
|
607
607
|
|
|
608
608
|
private popCueFromMap(event: SubtitleCueEvent): SubtitleLabel | undefined {
|
|
609
|
-
|
|
610
|
-
|
|
609
|
+
const id = ActiveSubtitleManager.calculateId(event);
|
|
610
|
+
const activeSubtitleCues = this.activeSubtitleCueMap[id];
|
|
611
611
|
|
|
612
612
|
if (activeSubtitleCues && activeSubtitleCues.length > 0) {
|
|
613
613
|
// Remove cue
|
|
@@ -618,7 +618,7 @@ class ActiveSubtitleManager {
|
|
|
618
618
|
* cue end time (which can change between CueEnter and CueExit IN CueUpdate) and use it as an
|
|
619
619
|
* additional hint to try and remove the correct one of the colliding cues.
|
|
620
620
|
*/
|
|
621
|
-
|
|
621
|
+
const activeSubtitleCue = activeSubtitleCues.shift();
|
|
622
622
|
this.activeSubtitleCueCount--;
|
|
623
623
|
|
|
624
624
|
return activeSubtitleCue.label;
|
|
@@ -661,8 +661,8 @@ class ActiveSubtitleManager {
|
|
|
661
661
|
* @return {SubtitleLabel}
|
|
662
662
|
*/
|
|
663
663
|
getCues(event: SubtitleCueEvent): SubtitleLabel[] | undefined {
|
|
664
|
-
|
|
665
|
-
|
|
664
|
+
const id = ActiveSubtitleManager.calculateId(event);
|
|
665
|
+
const activeSubtitleCues = this.activeSubtitleCueMap[id];
|
|
666
666
|
if (activeSubtitleCues && activeSubtitleCues.length > 0) {
|
|
667
667
|
return activeSubtitleCues.map(cue => cue.label);
|
|
668
668
|
}
|