# Video preset

The general-purpose video preset — a player, feature bundle, skins, and media for on-demand video

`@videojs/html/video` is the general-purpose preset for on-demand video. It bundles the `<video-player>` element, the `videoFeatures` bundle it is configured with, and two skins, and plays through the browser’s native `<video>`. See [Presets](https://videojs.org/docs/framework/html/guides/presets) for how presets fit together and how to customize one.

## Import

```ts
import '@videojs/html/video/player';
import '@videojs/html/video/skin';
```

Import `@videojs/html/video/neutral-skin` instead for the neutral skin. Or load one [CDN](https://videojs.org/docs/framework/html/guides/cdn) bundle that registers the player and a skin together:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.1/video.js"></script>
```

`video-neutral.js` registers the neutral skin instead, and `video-player.js` registers `<video-player>` alone.

## Usage

**index.html**

```html
<script type="module">
  import '@videojs/html/video/player';
  import '@videojs/html/video/skin';
</script>

<video-player>
  <video-skin>
    <video src="video.mp4"></video>
  </video-skin>
</video-player>
```

## Player

`@videojs/html/video/player` registers `<video-player>`, whose class is `VideoPlayerElement`. It is a [player](https://videojs.org/docs/framework/html/reference/components/player) element created by [`createPlayer`](https://videojs.org/docs/framework/html/reference/api/html-create-player) with `videoFeatures`. It owns the player store but no layout. Put a skin or a [`<media-container>`](https://videojs.org/docs/framework/html/reference/components/player-container) inside it.

| Attribute | Property | Description |
| --- | --- | --- |
| `content-title` | `contentTitle` | The title to display. Takes precedence over the title the media reports. |
| `poster` | `poster` | The poster to display. Takes precedence over the poster the media reports. |
| `keep-alive` | — | Keeps the player and its store alive when the element leaves the DOM. Call `destroy()` when you’re done with it. |

`content-title` and `poster` come from the [metadata feature](https://videojs.org/docs/framework/html/reference/api/feature-metadata#player-inputs). The element’s read-only `store` property returns its player store.

The preset root also exports a `PlayerController` bound to the video player’s store. Use it from any custom element inside `<video-player>`; see [`PlayerController`](https://videojs.org/docs/framework/html/reference/api/player-controller).

## Feature bundle

`videoFeatures` is the array of [features](https://videojs.org/docs/framework/html/guides/features) the player is configured with:

| Feature | Description |
| --- | --- |
| [`playbackFeature`](https://videojs.org/docs/framework/html/reference/api/feature-playback) | Play/pause state and actions for the player store |
| [`playbackRateFeature`](https://videojs.org/docs/framework/html/reference/api/feature-playback-rate) | Playback speed state and actions for the player store |
| [`qualityFeature`](https://videojs.org/docs/framework/html/reference/api/feature-quality) | Video rendition state and actions for the player store |
| [`audioTrackFeature`](https://videojs.org/docs/framework/html/reference/api/feature-audio-track) | Audio track state and actions for the player store |
| [`volumeFeature`](https://videojs.org/docs/framework/html/reference/api/feature-volume) | Volume level and mute state for the player store |
| [`timeFeature`](https://videojs.org/docs/framework/html/reference/api/feature-time) | Playback position and duration state for the player store |
| [`sourceFeature`](https://videojs.org/docs/framework/html/reference/api/feature-source) | Media source state and actions for the player store |
| [`bufferFeature`](https://videojs.org/docs/framework/html/reference/api/feature-buffer) | Buffered and seekable time range state for the player store |
| [`fullscreenFeature`](https://videojs.org/docs/framework/html/reference/api/feature-fullscreen) | Fullscreen state and actions for the player store |
| [`pipFeature`](https://videojs.org/docs/framework/html/reference/api/feature-pip) | Picture-in-picture state and actions for the player store |
| [`remotePlaybackFeature`](https://videojs.org/docs/framework/html/reference/api/feature-remote-playback) | Remote playback state and actions for the player store |
| [`controlsFeature`](https://videojs.org/docs/framework/html/reference/api/feature-controls) | User activity and controls visibility state for the player store |
| [`textTrackFeature`](https://videojs.org/docs/framework/html/reference/api/feature-text-tracks) | Subtitles, captions, and chapter track state for the player store |
| [`errorFeature`](https://videojs.org/docs/framework/html/reference/api/feature-error) | Media error state and actions for the player store |
| [`metadataFeature`](https://videojs.org/docs/framework/html/reference/api/feature-metadata) | Resolved title and poster values for the player store |

Its type, `VideoFeatures`, is the tuple of those features in order. Import it from the package root:

```ts
import type { VideoFeatures } from '@videojs/html';
```

To add or remove a feature, pass your own array to `createPlayer`. The skins expect the features they render controls for.

```ts
import { createPlayer, orientationLockFeature } from '@videojs/html';
import { videoFeatures } from '@videojs/html/video';

const { PlayerElement } = createPlayer({
  features: [...videoFeatures, orientationLockFeature],
});

customElements.define('my-video-player', PlayerElement);
```

## Skins

- [VideoSkin](https://videojs.org/docs/framework/html/reference/components/video-skin) — the default skin, with the modern, frosted look.
- [NeutralVideoSkin](https://videojs.org/docs/framework/html/reference/components/video-neutral-skin) — the visually lighter variant, closer to a classic control bar.

## Media

The preset plays through a native [`<video>`](https://videojs.org/docs/framework/html/reference/components/video), so it registers no media component of its own. Swap it for any compatible [media component](https://videojs.org/docs/framework/html/guides/media-sources), such as [`<hlsjs-video>`](https://videojs.org/docs/framework/html/reference/components/hlsjs-video) for HLS.

## Exports

The preset root, `@videojs/html/video`, has no side effects. Importing it never registers an element:

| Export | Description |
| --- | --- |
| `VideoPlayerElement` | The [player](#player) element class. |
| `PlayerController` | The player controller, bound to the video player’s store. |
| `videoFeatures` | The [feature bundle](#feature-bundle). |
| `VideoSkinElement` | The default [skin](#skins) element class. |
| `NeutralVideoSkinElement` | The neutral [skin](#skins) element class. |

Registration entry points are side-effect-only:

| Entry point | Registers |
| --- | --- |
| `@videojs/html/video/player` | `<video-player>` |
| `@videojs/html/video/skin` | `<video-skin>`, `<media-container>`, and the UI elements the skin composes |
| `@videojs/html/video/neutral-skin` | `<video-neutral-skin>`, `<media-container>`, and the UI elements the neutral skin composes |
| `@videojs/html/video/ui` | `<media-container>` and the UI elements of the default skin, without the skin, for a layout you write yourself |
| `@videojs/html/video/neutral-ui` | `<media-container>` and the UI elements of the neutral skin, without the skin |

---

HTML documentation: https://videojs.org/docs/framework/html/llms.txt
All documentation: https://videojs.org/llms.txt
