Metadata
Resolved title and poster values for the player store
Resolves what is playing into two values your UI can render: title and poster.
title and poster each resolve independently through the same two tiers: the value you set, then the value the media reports. The first tier that holds a value wins; when neither does, the resolved value is an empty string. Because the tiers stay separate, clearing the value you set reveals the media’s, and a source that reports a poster but no title contributes to one while leaving the other empty.
An empty string counts as a value and stops the chain: set title to '' and the resolved title is ''. Pass null to clear your value.
The metadata feature is included by the videoFeatures, audioFeatures, liveVideoFeatures, and liveAudioFeatures presets; apps that build a custom preset can compose it in directly.
Import
import { metadataFeature } from '@videojs/react';import { metadataFeature } from '@videojs/html';The audioFeatures, liveAudioFeatures, liveVideoFeatures, and videoFeatures feature bundles include this feature.
API Reference
Configuration
Attributes and matching properties the player element accepts. They exist only while this feature is selected.
| Prop | Type | Default | Details |
|---|---|---|---|
contentTitle | MediaContentValue | — | |
| |||
poster | MediaContentValue | — | |
| |||
State
| Property | Type | Details |
|---|---|---|
title | string | |
| ||
poster | string | |
| ||
Selector
To just show the name of what is playing, drop in the Title component — it reads this feature for you. Reach for the selector when building your own UI.
Pass selectMetadata to usePlayer to subscribe to metadata state. Returns undefined if the metadata feature is not configured.
import { selectMetadata, usePlayer } from '@videojs/react';
function ContentTitle() {
const metadata = usePlayer(selectMetadata);
if (!metadata?.title) return null;
return <h2 className="content-title">{metadata.title}</h2>;
}Pass selectMetadata to PlayerController to subscribe to metadata state. Returns undefined if the metadata feature is not configured.
import { createPlayer, UIElement, selectMetadata } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';
const { PlayerController } = createPlayer({ features: videoFeatures });
class ContentTitle extends UIElement {
readonly #metadata = new PlayerController(this, selectMetadata);
}Player inputs
The store publishes the resolved values and takes no writes. A player input is the only way to set one.
Every input is a prop on Player. A player built without the metadata feature has none of them, and none is forwarded.
import { Container, createPlayer } from '@videojs/react';
import { videoFeatures } from '@videojs/react/video';
const { Player } = createPlayer({ features: videoFeatures });
function App({ episode }: { episode: { title: string | null; art: string | null } }) {
return (
<Player title={episode.title} poster={episode.art}>
<Container>
<video src="episode.mp4" />
</Container>
</Player>
);
}Passing null clears your value, so title={null} falls through to the title the media reports.
Every input is an attribute on <video-player>, each with a matching property. A player built without the metadata feature observes none of them.
title already means the tooltip on an HTML element, so the title input goes by content-title in markup, and by contentTitle as a property. The other inputs use their own names.
<video-player content-title="The Pilot" poster="/episode-art.jpg">
<media-container>
<video src="episode.mp4"></video>
</media-container>
</video-player>Removing an attribute clears your value, so it falls through to what the media reports.
const player = document.querySelector('video-player');
player?.setAttribute('content-title', 'The Pilot');
player?.removeAttribute('content-title'); // falls back to the mediaThe flow between an attribute and its property runs one way: an attribute change writes the property, but setting the property leaves the attribute alone. Read the property for the current value.
Media-reported values
The media tier comes from media that reports content data and announces changes to it, and it covers title and poster. A media reports only the keys it can vouch for, so either may be absent while the other arrives. A key that never arrives means that tier never contributes, and the resolved value is whatever you set. Detaching the media clears its values; the values you set survive and apply to the next source.
poster is the feature’s own resolved value, not the media element’s poster attribute. Setting one does not set the other.
A low-resolution stand-in to show while the poster loads is not part of this feature. The poster renders an <img> you control, so give it a background-image and that shows until the poster itself paints over it. Add a poster and loading placeholder walks through that technique for each framework.