# video-player

The state boundary — creates a store and broadcasts it to all descendants.

The `<video-player>` element is the state boundary of your player. It creates a store and makes it available to every element inside it via context. Every player needs exactly one.

```html
<video-player>
  <!-- Everything inside can access the player store -->
  <media-container>
    <video src="video.mp4"></video>
  </media-container>
</video-player>
```

## How it’s created

For most users, importing from `@videojs/html/video/player` registers a ready-to-use `<video-player>` element with the standard video [features](https://videojs.org/docs/framework/html/guides/features) (bundled as a [preset](https://videojs.org/docs/framework/html/guides/presets)):

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

```html
<video-player>
  <media-container>
    <video src="video.mp4"></video>
  </media-container>
</video-player>
```

If you need a custom feature set or tag name, use `createPlayer()` to get the configured `PlayerElement`. Extend `ContainerElement` separately when you need custom container behavior:

**my-player.ts**

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

const { PlayerElement: MyPlayer } = createPlayer({ features: videoFeatures });

class MyContainer extends ContainerElement {}
customElements.define('my-player', MyPlayer);
customElements.define('my-container', MyContainer);
```

- [`createPlayer` reference](https://videojs.org/docs/framework/html/reference/api/html-create-player)

## What lives inside it

Everything that needs player state goes inside `<video-player>`: skins, containers, UI components, and your own custom components. Anything inside can access the store.

```html
<video-player>
  <video-skin>               <!-- skin — includes container + controls -->
    <video src="..."></video> <!-- media element -->
  </video-skin>
  <my-custom-overlay></my-custom-overlay> <!-- your own element — can use PlayerController -->
</video-player>
```

## No visual presence

Packaged skins make `<video-player>` boxless with `display: contents`. Width, height, positioning, transforms, and `getBoundingClientRect()` do not describe a visible player box there. Put layout and measurements on the [`<media-container>`](https://videojs.org/docs/framework/html/reference/components/player-container) instead.

If you omit `<video-skin>` and import only the player and media elements, those skin styles are not loaded. The player element still owns state, not layout, so add and style a `<media-container>` instead of using the player itself as the layout surface.

## Accessing state

Use the preset’s typed `PlayerController` to subscribe to store state from any custom element inside the player:

**play-pause-button.ts**

```ts
import { UIElement, selectPlayback } from '@videojs/html';
import { PlayerController } from '@videojs/html/video';

class PlayPauseButton extends UIElement {
  readonly #playback = new PlayerController(this, selectPlayback);

  connectedCallback() {
    super.connectedCallback();
    this.addEventListener('click', this.#togglePlayback);
  }

  disconnectedCallback() {
    this.removeEventListener('click', this.#togglePlayback);
    super.disconnectedCallback();
  }

  readonly #togglePlayback = () => this.#playback.value?.togglePaused();
}

customElements.define('play-pause-button', PlayPauseButton);
```

- [PlayerController reference](https://videojs.org/docs/framework/html/reference/api/player-controller)

## Extended player layouts

The player’s scope can extend beyond the fullscreen target. Playlists, transcripts, sidebars, and other supplementary UI can live inside `<video-player>` but outside `<media-container>`. They still have full access to the store, but they won’t go fullscreen with the video.

```html
<video-player>
  <media-container>
    <video src="video.mp4"></video>
    <media-controls><media-controls-content>...</media-controls-content></media-controls>  <!-- goes fullscreen with the video -->
  </media-container>

  <media-transcript></media-transcript>     <!-- outside container — still has store access -->
  <playlist-sidebar></playlist-sidebar>     <!-- outside container — still has store access -->
</video-player>
```

---

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