Skip to content
Breaking changes

v10.0.0-beta.30

Compare changes on GitHub

Shaka Player joins the lineup, and it landed twice in one release: first as a working element, then again with everything the hls.js media already had. Around it, two APIs move to where they belong — orientation lock onto the provider, poster placeholders out of the player entirely.

Breaking changes

  • Orientation lock is provider configuration (#1999). features.orientationLock({ type }) is gone. Select the feature as a value — features.orientationLock — and set the type on the provider: the orientation-lock-type attribute in HTML, the orientationLockType prop in React. Clearing the value restores landscape. Read it with selectOrientationLock, or set it imperatively with setOrientationLockType. The factory-configured feature form goes with it: ConfigurablePlayerFeature, ConfigurablePlayerFeatureConfig, OrientationLockFeatureConfig, forConfig, definePlayerSlice, and definePlayerFeature’s two-argument overload are all removed.
  • Built-in poster placeholders are removed (#2063). The React posterPlaceholder input, the HTML poster-placeholder attribute, the skin placeholder prop and placeholdersrc attribute, and --media-poster-placeholder with its blur layers are all gone. Supply the placeholder yourself: pass renderPoster to a React skin, or slot an <img slot="poster"> carrying a CSS background in HTML. Nothing needs a replacement API — both customization points already existed.

Shaka Player, twice

<shaka-video> for HTML and <ShakaVideo> for React play DASH and HLS from one engine, with Shaka’s DRM stack behind the standardized source.drm API (#2276). source.type is handed to Shaka as the type to parse the manifest as, which is what makes an extensionless URL playable. source.drm — the same engine-neutral shape hls.js and native HLS read — becomes Shaka’s license servers and certificate URIs, with engine.shaka as the escape hatch for the richer config. Video renditions and audio tracks mirror into videoRenditions and audioTracks; pinning a rendition turns ABR off and hands adaptation back when the selection clears. Errors are reported only when Shaka gives up: a failure it means to retry warns in development instead, and a load superseded by a newer one is never announced at all.

A fast follow brought it level with the hls.js media (#2285). Importing the media used to crash any server runtime, because every shaka-player dist reads a bare self while its UMD wrapper evaluates; a shim lends it one and takes it back, and the constructor bails before the browser-support probe when there is no DOM. The element now ships Shaka’s es2021 bundle instead of the ES5 default, taking @videojs/html/media/shaka-video from 225.3 kB to 204.2 kB. On top of that: streamType detection with a user override, targetLiveWindow and a read-time liveEdgeStart with the same seek-to-live on first play the hls.js media performs, preload mapped onto when and how load() runs, and ABR restricted to element size by default. There’s no reference page for it yet.

Titles, metadata, and configuration

Drop <media-title> or <Title> into a skin and it renders the title the store resolved (#1997). Set it on the player with the content-title attribute in HTML or the title prop in React; the component reads metadata and nothing else. With no title to show, HTML sets the native hidden attribute plus data-hidden and React renders nothing, so an empty title takes itself out of the layout. Registration is opt-in through @videojs/html/ui/title until a skin renders one, so no skin pays for bytes it doesn’t use. See the reference for HTML and React.

The metadata feature is documented now, and the feature reference builder grew a Configuration section to do it (#2000). Generated pages describe the inputs a selected feature adds to the provider — type, default, React prop, and HTML attribute — rather than state and actions alone. Read it for HTML and React.

Orientation lock is the first feature to use that table, having moved to provider configuration in the same stack (#1999); see Breaking changes. Making the type responsive exposed three ways the lock could desync from the screen, all from one variable standing for both “last requested” and “type we hold”. The primitive tracks desired and held separately now and reconciles one request at a time, so a rejected lock no longer suppresses every later request for the same type, overlapping requests can’t leave the screen describing one type while the store reports another, and a platform that always rejects stops getting re-asked several times a second during playback. Details in the orientation lock feature for HTML and React.

Posters, previews, and menus

With placeholders out of the player, the skins render the poster and stop there — and they leave it visible while it loads, so a background you supplied can be seen instead of being hidden behind a transparent image. The new guide covers React image components, bare Poster, packaged HTML skins, and ejected ones: HTML and React, with the component itself for HTML and React.

Storyboard hover previews never loaded on a cross-origin-isolated page (#2273). Under Cross-Origin-Embedder-Policy: require-corp a cross-origin subresource is blocked unless it’s CORS-enabled, and the thumbnail image was always fetched no-CORS with no way to configure it through the skins. It inherits the media element’s CORS mode now when crossOrigin is unset, which is safe because a cross-origin thumbnail track only loads on a CORS-enabled media element in the first place — reaching the inherit path means the author already opted in. null opts back out; thumbnails supplied directly through the thumbnails prop never inherit. The skins needed no change. See the thumbnail reference for HTML and React.

Settings submenus sized themselves wrong because child layout offsets counted the container’s leading padding twice, so the synced menu height didn’t match the rendered content (#2283). The same pass drops persistent will-change hints from menu panels and control transitions, which could contribute to animation stutter in Safari, while keeping the transient indicator and button hints that earn their place. Covered in the menu reference for HTML and React.

Under the hood: SPF

SPF caps rendition selection to the player’s rendered size, on by default (#2242). A small embed stops pulling renditions larger than it can show. The cap is the smallest ladder tier that still covers the player plus everything below it, not a hard at-or-below-area cut, which would underserve a player sitting between tiers. playerResolutionCap slots into the video switch chain after the user filter, so a manual pick still wins, and before the ranker, which then chooses within the cap. Measurement goes through a resize observer composed with a device-pixel-ratio watcher, since browser zoom or a move to another display changes the ratio without resizing the element. capRenditionToPlayerSize gates the measurement and useDevicePixelRatio gates whether the cap scales to device pixels. Renditions declaring no resolution are never capped out, and picture-in-picture and iOS native fullscreen aren’t handled yet — the element keeps its layout box while the viewer watches a different surface.

Background video with an undecodable ladder no longer stalls in silence (#2286). An HEVC or AV1 source the environment can’t decode leaves HTMLMediaElement.error null at readyState 0, and it was the one cause the unplayable-source reporting couldn’t reach: codecs live in the multivariant playlist, so the whole ladder gets pruned before anything resolves and no cause is ever produced. Moving reportAbsentTrackType to the tail of the constraint chain fixes it, where an empty input means “nothing playable here” whether the renditions were pruned or never offered. First-fatal-wins is unchanged, so media.error still surfaces the real cause when there is one; only the logged sequence grows. Read the background video reference for HTML and React.