🚀. Socket Launch Week Day 2:Introducing Manifest Alerts.Learn more →
Sign In

@nrk/player-elements

Package Overview
Dependencies
Maintainers
200
Versions
421
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package was removed
Sorry, it seems this package was removed from the registry

@nrk/player-elements

Source
npmnpm
Version
17.2.11
Version published
Weekly downloads
0
Maintainers
200
Weekly downloads
 
Created
Source

Player elements

Headless building blocks for creating a web players handling NRK content.

General design

The elements in this package uses attributes for configuration and specifically the type attribute is used for some automagic, specifically to find the player element in the dom. All elements inherit from @nrkno/reactive-element (https://github.com/nrkno/web-custom-elements/tree/master/packages/reactive-element) to handle updates and react to changes in the dom.

An important concept in player-elements is also shadowed properties. You can specify properties in an element that shadows the same properties in another element, and you will get updates when they are updated in the element you are shadowing. For instance, in the volume controller it shadows muted and volume from player. When some button triggers the PlayerActions.toggleMute action, the property muted is toggled in the player instance. Since muted is shadowed in the VolumeElement class, it is changed there also. Shadowing is handled in the @nrkno/element-shadow-properties-mixin package from @nrk/web-custom-elements.

Styling

Elements have default styles in the release, based on a dash-type suffix.

These styles exists for the following elements:

  • PlayerElement : class -player
  • ControlsElement: class -controls
  • PosterElement: class -poster
  • ScrubberElement: class -scrubber
  • VolumeElement: class -volume
  • SubtitleElement: class -subtitles

The point here is that if you create a plain player inheriting from PlayerElement and give it the -player class, you get the default player look and the same applies for all other elements. But you are of course free to both change the HTML of the elements and the css, for customising the look and feel. A good approach can be to use both -player class and your own classes to use the base css and extend it.

In addition there are some helper classes for positioning and reset. Important helper classes are for controlling player aspect ratio. The following classes can do that (from helper classes)

  • .aspect-ratio--235x1
  • .aspect-ratio--4x3
  • .aspect-ratio--1x1
  • .aspect-ratio--2x3
  • .aspect-ratio--9x16
  • .aspect-ratio--16x9

player-element

The player element (class PlayerElement) is the central custom element used for creating a player. Without it, you would not have a player at all. The player element use player-core internally for handling playback and sends commands to a player core session when the user uses the player. As other elements in this package, it is configured via html attributes.

Supported attributes are (attribute names in HTML must be lowercase):

NameData typeRequiredDescription
srcstringyesThe media source to play. See below for format spec
autoplaybooleannoStart to play media (if the browser allows it)
blockedcontentagenumbernoAge restriction. Content rated with this value or higher will be blocked and error thrown
mutedbooleannoMute audio or not
aidiagnosticsidstringnoid sent with all application insigth events
loopbooleannoLoop playback
starttimenumber | DatenoStart playback at time specified, in seconds for on-demand streams or a Date inside the stream for live streams.
volumenumbernoVolume level 0-1.0
userObjectnoA UserState object representing a logged in user
preferredmanifeststringnoThe preferred manifest is either synstolk, tegntolk, all-speech-subtitles or default
preferredsubtitlestringnoEither none for no subtitles or string representing the subtitle label
preferredbandwithstringnoPreferred bandwith use for streaming. One of "low" | "mid" | "high" | "auto" | "highest"
playbackratenumbernoThe rate of playback, 1.0 is normal playback, 0.5 is 50% speed, 1.5 is 1.5x speed
psapioriginstringnobaseUrl for psapi
psapirecommendationsoriginstringnobaseUrl for psapi recommendations
npawaccountcodestringnoaccount name for NPAW tracking. No tracking is done without it
snowplowurlstringnoRequired for enabling snowplow tracking. collector Url for snowplow tracking
snowplowappidstringnoRequired for enabling snowplow tracking. appId for snowplow tracking, see https://github.com/nrkno/snowplow-tooling
snowplowserviceidstringnoserviceid for snowplow tracking, see Service schema for valid values
snowplowosstringnoOperating systems name as a string to use for snowplow tracking
cdnoverridestringnoOverride psapi calls to only use this cdn. One of {akamai, globalconnect, telenor}
featuresArraynoSerialized list of feature toggle keys for the player
availablechannelidsArraynoList of channel ids that are available to the current user

Subclasses of this element must implement their version of the method initPlayerCoreInstance() since they are responsible for loading the player-core lib, often done dynamically. The method should set the PlayerCore instance on the property this.player.

The PlayerCore constructor must have the this element and a list of configured adapters as parameters and an optional configuration object. See https://static.nrk.no/player-core/latest/docs/classes/core_player_core.PlayerCore.html#constructor for details. Most noteworthy is the crossOrigin setting on mediaElementOptions which must be set to anonymous if subtitles will be loaded from https://undertekst.nrk.no, which is the most common case for NRK players. PlayerCore default value for this setting is none due to technical limitations in the Telenor CDN configuration regarding accept-ranges requests and cors headers.

Src specification

The src attribute has multiple modes depending on what you want to play. It has three parts

[scheme]:[type]:id

Scheme can only be nrk at present, and the scheme and type part is not optional. Type can be either program, channel or clip. A program type will expect id to be a PRF program if for use with PSAPI, channel expects id to be a psapi channel id (nrk1, nrk2 etc) while clip will expect id to be a Potion clip id. The lookup of manifest and metadata for nrk content is handled by the player-psapi-client package. Examples:

  • nrk:channel:nrk1
  • nrk:program:MSUS08000119
  • nrk:clip:79d1a9e9-48cd-4e2f-869c-b0b0bbaec0be
  • nrk:clip:261025

startTime and startTimeLive

If starttime is unset or undefined, an on-demand stream will start at the beginning (time=0) while a live stream will start at the "now" time. If one wants to start playback at another position in the stream, startTime (on-demand) or startTimeLive (live streams) must be set. An on-demand stream always starts at 0, so startTime is seconds from start. A live stream does not, and it will have timestamps for start and end internally after loading. Therefore, startTimeLive is a timestamp (Date) specifying when to start the playback within the live stream.

Data in the player element

The PlayerElement uses player-psapi-client to load data from psapi for the src specified, in two separate calls for metadata and manifest data. Both are available as reactive properties on player for other elements to shadow or access.

See documentation for the metadata and manifest endpoints on PSAPI playback docs and there is typescript api doc for Manifest and Metadata interfaces.

Throw errors for testing purposes

The player element has a non-exported method fakeError(type: string | PlaybackErrorTypes, fatal?: boolean) method which can be handy for test, debug and development.

When the player-element is selected in browser development console one can call the following in the browser console:

$0.fakeError('CHANNEL_GEOBLOCK_ERROR');

The make the player emit that error as a PlayerError event, for context listening for that event (smart-tv-player tizen app is one such context). Call the method without any arguments to get an unspecified error and usage information for the method in the console.

poster-element

The poster-element (class PosterElement) is an element used for showing content to the user before playback starts, typically the key art for the content loaded, a play button, age limit and other elements. The poster is hidden when playback starts. When the poster is added to a parent player, it shadows some data from the player, which is useful. When metadata is fetched in the player, the poster gets it too, so we can display it there. This metadata is:

  • title (string)
  • subtitle (string)
  • isLive (boolean)
  • startTime (Date, if live)
  • legalAgeText (string)
  • duration (number, in seconds)
  • srcset (string)
  • availability
    • to (Date)
    • from (Date)
    • available (boolean)
    • reason (string)
    • messageType (string)
    • endUserMessage (string)

The last three properties are only specified if available is false.

It sets a accessibleDescription text based on these metadata and picks the image matching the player dimensions which is set as src. If you set the src on poster itself, that takes presedence over the choosing logic for the image src. The poster should also take care of showing end user messages (included in availability) from PSApi when the src is non-playable due to normal circumstances like content no longer available, not yet started, geoblocked etc.

controls-element

The controls element (class ControlsElement) is a container for other controls in the player, handling various states and events for the player. Default is that click in the controls element not hitting a specific control toggles playback. The controls element is hidden before playback starts and visible afterwards (just as poster is visible before playback and hidden afterwards). Normally the controls element itself is invisible, but the controls inside are shown when appropriate.

Keyboard-element

The keyboard element handles all keyboard navigation like seeking, muting, toggling playback and more, and is and should be headless. Add this to your player, and it will handle your keyboard navigation needs. Override it and implement your own if you need.

KeyAction
Spacetoggle playback
Entertoggle playback
Arrow leftseek back by default seekable step in player.
Arrow rightseek forward by default seekable step in player.
Arrow upIncrease volume 10%
Arrow downDecrease volume 10%
0-9jump in time, 0%, 10%, 20%, 30% into stream etc.
Homejump to start
EndJump to end
KStart playback
MToggle mute
JSeek back, same as arrow
LSeek forward, same as arrow
FToggle full screen mode (WIP)
PToggle player in player mode (WIP)

Also, if a modifier key (ctrl, shift, alt or meta) is pressed while seeking, the seek distance is 5x as big. The base seek step is calculated based on the range of the stream, but never less than 1 second.

Scrubber-element

The scrubber (class ScrubberElement) is the element showing the user where they are in the stream, and how much time has passed and remains. It is letting them use touch or mouse to navigate the stream. The scrubber element default class -scrubber has some sensible default styles for a basic scrubber and uses two variables --player-playhead-height and --player-progressbar-height for many calculations. These can be overriden in your bundle to customise the look of the scrubber.

The ScrubberElement class expects to find HTML elements of several types to function. The scrubber responds to a lot of interaction and dispatches events to the player. These types are

  • range
  • progressbar
    • playhead
    • progressbar-full
    • progressbar-played
  • start-time
  • end-time
  • playhead-time
  • pointer-time

Example markup

<input
  autofocus
  class="reset-input-range"
  action="${PlayerActions.SeekTo}"
  action:events="click,change"
  type="range"
  min="0"
  max="100"
  step="1"
  aria-label="Spol"
/>
<div type="progressbar" aria-hidden="true">
  <div type="playhead"></div>
  <div type="progressbar-full"></div>
  <div type="progressbar-played"></div>
</div>
<div type="start-time" aria-hidden="true"></div>
<div type="end-time" aria-hidden="true"></div>
<div type="playhead-time" aria-hidden="true"></div>
<div type="pointer-time" aria-hidden="true"></div>

Volume-element

The volume element (class VolumeElement) is a volume controller handling volume adjustments and muting/unmuting. The base class handles volume level and muting/unmuting but can look the way you want, the only css on the -volume class is display: block, everything else is up to you. Example markup:

<button action="${PlayerActions.ToggleMute}" type="mute-button" aria-label="${this.muted ? 'Lyd pÄ' : 'Lyd av'}">
  <svg></svg>
</button>
<div class="volume-control absolute top left">
  <input
    class="absolute reset-input-range"
    action="${PlayerActions.SetVolume}"
    type="range"
    min="0"
    max="1"
    step="0.1"
    aria-label="Juster lydnivÄ"
    .value="${this.volume}"
  />
  <div class="slider absolute" aria-hidden="true">
    <div class="slider-fill" style="width: ${sliderProgress}%;"></div>
    <div class="slider-thumb-track">
      <div class="absolute slider-thumb" style="left: ${sliderProgress}%;"></div>
    </div>
  </div>
</div>

The volume controller shadow the mute and volume properties from the player.

Tracker element

The tracker is element taking care of all tracking of playback. For snowplow tracking attributes snowplowappid and snowplowurl and possibly snowplowserviceid needs to be set. See table of attributes for the player-element for more info.

See player-tracker

Subtitle element

Subtitles are handled by PlaybackStateMixin and SubtitleElement in combination. All state regarding subtitles is represented in the SubtitleState object on the Player element, set up by PlaybackStateMixin, but rendering is handled by extending the generic SubtitleElement and listening on update events for SubtitleState and rendering activeCues when they change. SubtitleElement also handles speaking the subtitle text, through the PlayerActions.Speak action.

SubtitleElement also has methods for parsing webVTT formatting and applying classes to it, but this can be overridden when needed.

Subtitles has default styles on the -subtitles class. A suitable HTML structure for subtitles using these styles should be

<player-subtitle-element class="-subtitles" type="subtitles">
  <div class="subtitles__line">
    <span class="subtitle__text">Subtitle text</span>
  </div>
</player-subtitle-element>

FAQs

Package last updated on 28 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts