@npo/player 1.21.0 → 1.22.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.
Files changed (45) hide show
  1. package/README.md +1 -2
  2. package/lib/js/drm/handlers/verifydrm.test.js +1 -1
  3. package/lib/js/markers/updateLiveMarkers.d.ts +1 -1
  4. package/lib/js/markers/updateLiveMarkers.js +42 -13
  5. package/lib/js/markers/updateLiveMarkers.test.js +3 -2
  6. package/lib/js/playeractions/handlers/error.test.js +6 -6
  7. package/lib/js/playeractions/handlers/handleoffsets.test.js +7 -7
  8. package/lib/js/playeractions/handlers/processsourceconfig.d.ts +2 -2
  9. package/lib/js/playeractions/handlers/processsourceconfig.js +20 -6
  10. package/lib/js/playeractions/handlers/removereplayclass.js +4 -3
  11. package/lib/js/playeractions/handlers/removereplayclass.test.js +7 -3
  12. package/lib/js/tracking/handlers/eventbinding.js +41 -31
  13. package/lib/js/tracking/handlers/eventlogging.d.ts +1 -1
  14. package/lib/js/tracking/handlers/eventlogging.js +1 -1
  15. package/lib/js/ui/components/buttons.js +2 -2
  16. package/lib/js/ui/components/nativemobile/buttons.d.ts +0 -12
  17. package/lib/js/ui/components/nativemobile/buttons.js +0 -41
  18. package/lib/js/ui/handlers/domhandlers.test.js +2 -1
  19. package/lib/{src/js/ui/components/shared → js/ui/handlers}/playnextscreen.d.ts +2 -2
  20. package/lib/js/ui/handlers/playnextscreen.js +26 -0
  21. package/lib/js/ui/{components/shared → handlers}/playnextstreen.test.js +6 -16
  22. package/lib/js/ui/nativemobileuicontainer.js +1 -4
  23. package/lib/js/ui/nativemobileuifactory.js +4 -20
  24. package/lib/npoplayer.js +32 -18
  25. package/lib/package.json +2 -2
  26. package/lib/src/js/markers/updateLiveMarkers.d.ts +1 -1
  27. package/lib/src/js/playeractions/handlers/processsourceconfig.d.ts +2 -2
  28. package/lib/src/js/tracking/handlers/eventlogging.d.ts +1 -1
  29. package/lib/src/js/ui/components/nativemobile/buttons.d.ts +0 -12
  30. package/lib/{js/ui/components/shared → src/js/ui/handlers}/playnextscreen.d.ts +2 -2
  31. package/lib/src/types/interfaces.d.ts +8 -0
  32. package/lib/types/interfaces.d.ts +8 -0
  33. package/package.json +2 -2
  34. package/src/scss/components/_icons.scss +1 -1
  35. package/src/scss/components/_playnext.scss +29 -1
  36. package/src/scss/components/_textbuttons.scss +17 -7
  37. package/src/scss/npoplayer.css +15 -6
  38. package/src/scss/variants/_player-small.scss +30 -0
  39. package/src/scss/vars/_colors.scss +1 -0
  40. package/lib/js/ui/components/nativemobile/playnext.d.ts +0 -11
  41. package/lib/js/ui/components/nativemobile/playnext.js +0 -10
  42. package/lib/js/ui/components/shared/playnextscreen.js +0 -46
  43. package/lib/src/js/ui/components/nativemobile/playnext.d.ts +0 -11
  44. /package/lib/js/ui/{components/shared → handlers}/playnextstreen.test.d.ts +0 -0
  45. /package/lib/src/js/ui/{components/shared → handlers}/playnextstreen.test.d.ts +0 -0
@@ -7,9 +7,9 @@ import { addFragments } from '../ui/components/nativemobile/addFragments';
7
7
  import { CustomMessages } from '../../types/interfaces';
8
8
  import { processNicam } from './handlers/nicamhandler';
9
9
  import { removeFragments } from '../fragments/removefragments';
10
- import { showPlayNextScreenIfNeeded } from './components/shared/playnextscreen';
11
10
  import { getPlayerElement, removePlayerElementClass } from '../utilities/utilities';
12
11
  import { handleLiveStreamNoDvr } from './handlers/domhandlers';
12
+ import { removeReplayClass } from '../playeractions/handlers/removereplayclass';
13
13
  export function nativeMobileUiFactory(player, config = {}) {
14
14
  UIManager.setLocalizationConfig(localizationConfig);
15
15
  const containerElement = getPlayerElement(player, '.bmpui-npo-player');
@@ -24,8 +24,8 @@ export function nativeMobileUiFactory(player, config = {}) {
24
24
  const mobileUIManager = new UIManager(player, nativeMobileUIContainer(player), uiConfig);
25
25
  let _webData = {};
26
26
  const removeFinishedClass = () => {
27
- player.off(PlayerEvent.Seeked, removeFinishedClass);
28
- removePlayerElementClass(player, '.bmpui-npo-player.bmpui-player-state-finished', 'bmpui-player-state-finished');
27
+ player.off(PlayerEvent.Seek, removeFinishedClass);
28
+ removeReplayClass(player);
29
29
  };
30
30
  const clearUI = () => {
31
31
  adBreakActive = false;
@@ -34,7 +34,6 @@ export function nativeMobileUiFactory(player, config = {}) {
34
34
  if (seekbarTitleElement)
35
35
  seekbarTitleElement.textContent = '';
36
36
  removePlayerElementClass(player, '.bmpui-npo-player', 'livestream-no-dvr');
37
- player.off(PlayerEvent.TimeChanged, handleShowPlayNextScreen);
38
37
  removeFragments(mobileUIManager);
39
38
  };
40
39
  const updateUI = () => {
@@ -47,9 +46,6 @@ export function nativeMobileUiFactory(player, config = {}) {
47
46
  if (seekbarTitleElement)
48
47
  seekbarTitleElement.textContent = _webData.title || '';
49
48
  handleLiveStreamNoDvr(player, _webData, containerElement);
50
- if (_webData.playNext?.showPlayNext) {
51
- player.on(PlayerEvent.TimeChanged, handleShowPlayNextScreen);
52
- }
53
49
  const section = _webData.segment ? {
54
50
  start: _webData.segment.inpoint,
55
51
  end: _webData.segment.outpoint,
@@ -61,15 +57,6 @@ export function nativeMobileUiFactory(player, config = {}) {
61
57
  adBreakActive = false;
62
58
  player.off(PlayerEvent.AdBreakFinished, setAdBreakActiveToFalse);
63
59
  };
64
- const handleShowPlayNextScreen = () => {
65
- let contentDuration = player.getDuration();
66
- let playnextOffset = _webData.playNext.offset;
67
- const container = player.getContainer();
68
- if (player.getCurrentTime() >= contentDuration - playnextOffset && !adBreakActive) {
69
- showPlayNextScreenIfNeeded(_webData.playNext.duration, container, undefined, true);
70
- player.off(PlayerEvent.TimeChanged, handleShowPlayNextScreen);
71
- }
72
- };
73
60
  if (window.bitmovin?.customMessageHandler) {
74
61
  const handleData = (data) => {
75
62
  clearUI();
@@ -80,9 +67,6 @@ export function nativeMobileUiFactory(player, config = {}) {
80
67
  };
81
68
  window.bitmovin.customMessageHandler.on(CustomMessages.SET_STREAM_LINK, handleData);
82
69
  window.bitmovin.customMessageHandler.on(CustomMessages.SET_WEB_DATA, handleData);
83
- if (_webData.playNext?.showPlayNext === true) {
84
- player.on(PlayerEvent.TimeChanged, handleShowPlayNextScreen);
85
- }
86
70
  window.bitmovin.customMessageHandler.on(CustomMessages.DO_ERROR, (data) => {
87
71
  if (!data)
88
72
  return;
@@ -118,7 +102,7 @@ export function nativeMobileUiFactory(player, config = {}) {
118
102
  });
119
103
  sendCustomMessage(CustomMessages.ERROR_TRIGGERED, { error: event });
120
104
  };
121
- player.on(PlayerEvent.Seeked, removeFinishedClass);
105
+ player.on(PlayerEvent.Seek, removeFinishedClass);
122
106
  player.on(PlayerEvent.Ready, addEventListeners);
123
107
  player.on(PlayerEvent.Error, (event) => {
124
108
  onPlayerError(event);
package/lib/npoplayer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Player, PlayerEvent, } from 'bitmovin-player';
2
2
  import AdsModuleBM from 'bitmovin-player/modules/bitmovinplayer-advertising-bitmovin';
3
3
  import { logEvent, initPlayerTracker, startPlayerTracker } from './js/tracking/playertracker';
4
- import { hidePlayNextScreen, showPlayNextScreenIfNeeded } from './js/ui/components/shared/playnextscreen';
4
+ import { hidePlayNextScreen, showPlayNextScreenIfNeeded } from './js/ui/handlers/playnextscreen';
5
5
  import * as utility from './js/utilities/utilities';
6
6
  import * as drm from './js/drm/drm';
7
7
  import * as playerAction from './js/playeractions/playeractions';
@@ -24,30 +24,31 @@ import { updateLiveMarkers } from './js/markers/updateLiveMarkers';
24
24
  export { NpoPlayerUIVariants, };
25
25
  export default class NpoPlayer {
26
26
  constructor(_container, _playerConfig, _npotag, _npotaginstance, _variant) {
27
- this.playerConfig = _playerConfig;
28
27
  this.sourceConfig = {};
29
28
  this.streamObject = {
30
29
  stream: { drmType: '', streamProfile: '', streamURL: '', avType: '', sourceProfile: '' },
31
30
  metadata: { title: '', description: '' },
32
- assets: { scrubbingThumbnail: '', subtitles: [] }
31
+ assets: { scrubbingThumbnail: '', subtitles: [] },
32
+ user: { type: 'anonymous' }
33
33
  };
34
- this.container = _container;
35
34
  this.player = null;
36
35
  this.uiManager = null;
37
- this.fragment = null;
38
36
  this.streamTracker = null;
37
+ this.logEmitter = new LogEmitter();
38
+ this.uiComponents = {};
39
+ this.fragment = null;
39
40
  this.streamOptions = {};
40
41
  this.jwt = '';
41
42
  this.apiPayload = { baseURL: '', jwt: '', data: {} };
42
43
  this.adBreakActive = false;
43
44
  this.version = pkg.version;
44
45
  this.drmProfile = { profileName: '', drm: '' };
45
- this.variant = _variant || NpoPlayerUIVariants.DEFAULT;
46
- initPlayerTracker(this, _npotag, _npotaginstance);
47
- this.logEmitter = new LogEmitter();
48
- this.uiComponents = {};
49
46
  this.isShowingPlayNextScreen = false;
50
47
  this.canceledPlayNextScreen = false;
48
+ this.playerConfig = _playerConfig;
49
+ this.container = _container;
50
+ this.variant = _variant || NpoPlayerUIVariants.DEFAULT;
51
+ initPlayerTracker(this, _npotag, _npotaginstance);
51
52
  this.initPlayer(this.container, _playerConfig, this.variant);
52
53
  }
53
54
  initPlayer(_container, playerConfig, variant) {
@@ -90,8 +91,14 @@ export default class NpoPlayer {
90
91
  }.bind(this);
91
92
  if (isUrl && isMedia) {
92
93
  this.sourceConfig = {
93
- ...options.sourceConfig,
94
- 'progressive': source
94
+ ...options.sourceConfig ?? {},
95
+ 'progressive': source,
96
+ analytics: {
97
+ customData2: 'other',
98
+ customData3: 'unknown',
99
+ customData4: this.npoTag?.npoTagInstance?.getParty(),
100
+ customData5: this.version
101
+ },
95
102
  };
96
103
  this.player?.load(this.sourceConfig);
97
104
  getDurationAndStartPlayerTracker();
@@ -130,21 +137,27 @@ export default class NpoPlayer {
130
137
  if (this.streamObject?.stream == undefined)
131
138
  return;
132
139
  const drmType = this.streamObject.stream.drmType ?? null;
133
- this.sourceConfig = await playerAction.processSourceConfig(options.sourceConfig ?? {}, this.streamObject, drmType && drmType.length > 0 ? profile.drm : null, this.streamOptions.useWidevineServerCertificate ?? true);
140
+ this.sourceConfig = await playerAction.processSourceConfig(options.sourceConfig ?? {}, this.streamObject, drmType && drmType.length > 0 ? profile.drm : null, this.streamOptions, this.version, this.npoTag?.npoTagInstance?.getParty());
134
141
  await drm.verifyDRM(this, this.player, payload);
135
142
  setupMediaSessionActionHandlers(this.player, this.sourceConfig, _streamObject);
136
143
  logEvent(this, 'load');
137
144
  let streamDuration = _streamObject.metadata.duration;
138
145
  let streamPrid = this.streamObject.metadata.prid || _streamObject.metadata.prid;
139
- streamDuration = streamDuration == null
140
- ? this.player.on(PlayerEvent.SourceLoaded, getDurationAndStartPlayerTracker)
141
- : startPlayerTracker(this, utility.validateStreamLength(streamDuration, false), this.version, streamPrid);
142
146
  if (this.isShowingPlayNextScreen) {
143
147
  this.hidePlayNextScreen();
144
148
  }
149
+ function initAndStartTracker() {
150
+ if (this.player === null)
151
+ return;
152
+ streamDuration = streamDuration == null
153
+ ? this.player.on(PlayerEvent.SourceLoaded, getDurationAndStartPlayerTracker)
154
+ : startPlayerTracker(this, utility.validateStreamLength(streamDuration, false), this.version, streamPrid);
155
+ }
156
+ let prerollPromise = Promise.resolve();
145
157
  if (this.variant !== NpoPlayerUIVariants.AUDIO) {
146
- await handlePreRolls(this.player, _streamObject, this);
158
+ prerollPromise = handlePreRolls(this.player, _streamObject, this);
147
159
  }
160
+ prerollPromise.then(() => initAndStartTracker.bind(this)());
148
161
  }
149
162
  else {
150
163
  this.doError(`Het is niet gelukt de stream op te halen: \n Input is geen valide token of media object.`, 500);
@@ -191,7 +204,8 @@ export default class NpoPlayer {
191
204
  if (this.uiManager === null || variant !== this.variant) {
192
205
  const uiConfig = {
193
206
  errorMessages: customSpecificErrorMessageOverlayConfig,
194
- disableAutoHideWhenHovered: true
207
+ disableAutoHideWhenHovered: true,
208
+ seekbarSnappingEnabled: false,
195
209
  };
196
210
  this.uiManager = new UIManager(player, createUIContainer(this, player, variant, this.container), uiConfig);
197
211
  this.variant = variant;
@@ -287,7 +301,7 @@ export default class NpoPlayer {
287
301
  updateMarkers(timeLineMarkers) {
288
302
  if (!(this.player && this.uiManager && this.streamObject.stream.isLiveStream))
289
303
  return;
290
- updateLiveMarkers(timeLineMarkers, this.player, this.uiManager);
304
+ updateLiveMarkers(timeLineMarkers, this.player, this.uiManager, this.streamOptions.autoFillTimeLineMarkerDuration ?? true);
291
305
  }
292
306
  ;
293
307
  cancelPlayNextScreen() {
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npo/player",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "NPO Player",
5
5
  "author": "Publieke Omroep <player@npo.nl>",
6
6
  "contributors": [
@@ -84,7 +84,7 @@
84
84
  "dependencies": {
85
85
  "@npotag/tag": "^3.0.1",
86
86
  "bitmovin-player": "8.151.0",
87
- "bitmovin-player-ui": "3.54.0"
87
+ "bitmovin-player-ui": "3.60.0"
88
88
  },
89
89
  "browserslist": [
90
90
  "defaults",
@@ -1,4 +1,4 @@
1
1
  import { PlayerAPI } from "bitmovin-player";
2
2
  import { UIManager } from "bitmovin-player-ui";
3
3
  import { TimeLineMarker } from "types/interfaces";
4
- export declare function updateLiveMarkers(timeLineMarkers: TimeLineMarker[], player: PlayerAPI, uiManager: UIManager): void;
4
+ export declare function updateLiveMarkers(timeLineMarkers: TimeLineMarker[], player: PlayerAPI, uiManager: UIManager, autoFillTimeLineMarkerDuration: boolean): void;
@@ -1,3 +1,3 @@
1
- import { StreamObject } from 'types/interfaces';
1
+ import { StreamObject, StreamOptions } from 'types/interfaces';
2
2
  import { SourceConfig } from 'bitmovin-player';
3
- export declare function processSourceConfig(_sourceConfig: SourceConfig | undefined, _streamObject: StreamObject, drm: string | null | undefined, useWidevineServerCertificate: boolean): Promise<SourceConfig>;
3
+ export declare function processSourceConfig(_sourceConfig: SourceConfig | undefined, _streamObject: StreamObject, drm: string | null | undefined, streamOptions: StreamOptions, version: string, npoTagPartyId: string | undefined): Promise<SourceConfig>;
@@ -1,2 +1,2 @@
1
- import NpoPlayer from "../../../npoplayer";
1
+ import NpoPlayer from '../../../npoplayer';
2
2
  export declare function logEvent(npoplayer: NpoPlayer, event: string, data?: any): void;
@@ -1,18 +1,6 @@
1
1
  import { AirPlayToggleButton, Button, CastToggleButton, ControlBar, FullscreenToggleButton, PictureInPictureToggleButton, PlaybackToggleButton, SettingsPanel, SettingsToggleButton, VolumeToggleButton } from 'bitmovin-player-ui';
2
2
  import { PlayerAPI } from 'bitmovin-player';
3
3
  export declare function createMiddleButtons(player: PlayerAPI): ControlBar;
4
- export declare function createPlayNextButton(player: PlayerAPI): Button<{
5
- cssClass: string;
6
- text: string;
7
- ariaLabel: string;
8
- hidden: false;
9
- }>;
10
- export declare function createCancelPlayNextButton(player: PlayerAPI): Button<{
11
- cssClass: string;
12
- text: string;
13
- ariaLabel: string;
14
- hidden: false;
15
- }>;
16
4
  export declare function createWatchFromStartButton(): Button<{
17
5
  cssClass: string;
18
6
  text: string;
@@ -1,2 +1,2 @@
1
- export declare function showPlayNextScreenIfNeeded(overlayDuration: number, containerEl: HTMLElement, proceedCallBack?: () => void, nativeUI?: boolean): void;
2
- export declare function hidePlayNextScreen(containerEl: HTMLElement, nativeUI?: boolean): void;
1
+ export declare function showPlayNextScreenIfNeeded(overlayDuration: number, containerEl: HTMLElement, proceedCallBack?: () => void): void;
2
+ export declare function hidePlayNextScreen(containerEl: HTMLElement): void;
@@ -10,6 +10,9 @@ export interface StreamObject {
10
10
  stream: StreamObject_Stream;
11
11
  metadata: StreamObject_Metadata;
12
12
  assets: StreamObject_Assets;
13
+ user: {
14
+ type: 'plus' | 'anonymous';
15
+ };
13
16
  }
14
17
  export interface ApiPayload {
15
18
  baseURL: string;
@@ -65,6 +68,7 @@ export interface StreamObject_Metadata {
65
68
  language?: string[];
66
69
  nicam?: string[] | null;
67
70
  poster?: string;
71
+ posterIsDefault?: boolean;
68
72
  prid?: string;
69
73
  sourceIP?: string;
70
74
  ageRating?: string;
@@ -97,6 +101,8 @@ export interface StreamOptions {
97
101
  ster?: SterData;
98
102
  enableSubtitles?: boolean;
99
103
  useWidevineServerCertificate?: boolean;
104
+ customFallbackPoster?: string;
105
+ autoFillTimeLineMarkerDuration?: boolean;
100
106
  }
101
107
  export interface UIComponents {
102
108
  errorMessageOverlay?: ErrorMessageOverlay;
@@ -170,5 +176,7 @@ export interface PlayNext {
170
176
  export type TimeLineMarker = {
171
177
  time: number;
172
178
  title: string;
179
+ duration?: number;
180
+ cssClasses?: string[];
173
181
  };
174
182
  export {};
@@ -10,6 +10,9 @@ export interface StreamObject {
10
10
  stream: StreamObject_Stream;
11
11
  metadata: StreamObject_Metadata;
12
12
  assets: StreamObject_Assets;
13
+ user: {
14
+ type: 'plus' | 'anonymous';
15
+ };
13
16
  }
14
17
  export interface ApiPayload {
15
18
  baseURL: string;
@@ -65,6 +68,7 @@ export interface StreamObject_Metadata {
65
68
  language?: string[];
66
69
  nicam?: string[] | null;
67
70
  poster?: string;
71
+ posterIsDefault?: boolean;
68
72
  prid?: string;
69
73
  sourceIP?: string;
70
74
  ageRating?: string;
@@ -97,6 +101,8 @@ export interface StreamOptions {
97
101
  ster?: SterData;
98
102
  enableSubtitles?: boolean;
99
103
  useWidevineServerCertificate?: boolean;
104
+ customFallbackPoster?: string;
105
+ autoFillTimeLineMarkerDuration?: boolean;
100
106
  }
101
107
  export interface UIComponents {
102
108
  errorMessageOverlay?: ErrorMessageOverlay;
@@ -170,5 +176,7 @@ export interface PlayNext {
170
176
  export type TimeLineMarker = {
171
177
  time: number;
172
178
  title: string;
179
+ duration?: number;
180
+ cssClasses?: string[];
173
181
  };
174
182
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npo/player",
3
- "version": "1.21.0",
3
+ "version": "1.22.0",
4
4
  "description": "NPO Player",
5
5
  "author": "Publieke Omroep <player@npo.nl>",
6
6
  "contributors": [
@@ -84,7 +84,7 @@
84
84
  "dependencies": {
85
85
  "@npotag/tag": "^3.0.1",
86
86
  "bitmovin-player": "8.151.0",
87
- "bitmovin-player-ui": "3.54.0"
87
+ "bitmovin-player-ui": "3.60.0"
88
88
  },
89
89
  "browserslist": [
90
90
  "defaults",
@@ -7,7 +7,7 @@
7
7
  .bmpui-ui-casttogglebutton,
8
8
  .bmpui-ui-airplaytogglebutton,
9
9
  .bmpui-ui-piptogglebutton {
10
- background-image: none;
10
+ background-image: none !important;
11
11
  width: 21px;
12
12
  height: 40px;
13
13
  padding: 0 5px;
@@ -28,8 +28,36 @@
28
28
  }
29
29
 
30
30
  .ui-playNextButton {
31
- background-color: var(--npo-player-textcolor);
31
+ background-color: var(--npo-player-graycolor-light);
32
32
  white-space: nowrap;
33
+ overflow: hidden;
34
+ position: relative;
35
+
36
+ &::before {
37
+ content: '';
38
+ position: absolute;
39
+ left: 0;
40
+ top: 0;
41
+ height: 100%;
42
+ width: 0;
43
+ border-top-left-radius: 10px;
44
+ border-bottom-left-radius: 10px;
45
+ background: var(--npo-player-textcolor);
46
+ animation-name: widthAnimation;
47
+ animation-timing-function: linear;
48
+ animation-duration: var(--animation-duration);
49
+ animation-fill-mode: forwards;
50
+ animation-delay: 0s;
51
+
52
+ @keyframes widthAnimation {
53
+ from {
54
+ width: 0;
55
+ }
56
+ to {
57
+ width: 100%;
58
+ }
59
+ }
60
+ }
33
61
 
34
62
  .bmpui-label {
35
63
  color: var(--npo-player-graycolor-dark);
@@ -11,13 +11,6 @@
11
11
  right: 0px;
12
12
  bottom: 0px;
13
13
  pointer-events: none;
14
-
15
- // strange fix for firefox bug caused by the absence of
16
- // an element containing the backdrop-filter property when
17
- // set to display: none after initially being shown on first pageload
18
- @-moz-document url-prefix() {
19
- backdrop-filter: brightness(1);
20
- }
21
14
  }
22
15
 
23
16
  .bmpui-ui-textbutton {
@@ -30,6 +23,7 @@
30
23
  filter: drop-shadow(0px 4px 16px rgba(0, 0, 0, 0.45));
31
24
 
32
25
  .bmpui-label {
26
+ position: relative;
33
27
  display: block;
34
28
  font-family: var(--fontBold);
35
29
  font-weight: 700;
@@ -37,6 +31,22 @@
37
31
  color: #ffffff;
38
32
  }
39
33
 
34
+ &-icon {
35
+ mask-repeat: no-repeat;
36
+ mask-position: center;
37
+ background-color: currentColor;
38
+ width: 16px;
39
+ height: 16px;
40
+ display: inline-block;
41
+ vertical-align: text-bottom;
42
+ margin-right: 5px;
43
+
44
+
45
+ &-play {
46
+ mask-image: var(--npo-player-icon-play);
47
+ }
48
+ }
49
+
40
50
  &:focus-visible {
41
51
  @include focusStyle();
42
52
  }