# native-hls-video

HLS video element using the browser's built-in HLS support

HLS video element that relies on the browser’s native HLS support. Works on Safari and other browsers with built-in HLS playback. For cross-browser HLS support, use the [hls.js video component](./hlsjs-video.md) instead.

## Import

```ts
import '@videojs/html/media/native-hls-video';
```

Or load it from the [CDN](../../guides/cdn.md):

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.3/media/native-hls-video.js"></script>
```

## Examples

### Basic Usage

**index.html**

```html
<media-container class="media-container">
  <native-hls-video src="https://stream.mux.com/BV3YZtogl89mg9VcNBhhnHm02Y34zI1nlMuMQfAbl3dM.m3u8" autoplay muted playsinline loop></native-hls-video>
</media-container>
```

**index.css**

```css
.media-container {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
}
```

**index.ts**

```ts
import '@videojs/html/ui/container';
import '@videojs/html/media/native-hls-video';
```

## API Reference

### Attributes

Forwards these standard media attributes to the internal `<video>`. See the [MDN media element reference](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video): `autopictureinpicture`, `autoplay`, `controls`, `controlslist`, `crossorigin`, `disablepictureinpicture`, `disableremoteplayback`, `loading`, `loop`, `muted`, `playsinline`, `poster`, `preload`, `src`.

These Video.js-specific attributes configure media behavior:

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `stream-type` | `'on-demand' \| 'live' \| 'unknown'` | `'unknown'` | Current stream type (`'on-demand'` / `'live'` / `'unknown'`). |

### Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `contentData` | `MediaContentData \| undefined` | — | Read-only. |
| `engine` | `null` | — | Read-only. Underlying playback engine — always `null`. Native HLS has no JS engine; the browser handles playback directly. |
| `error` | `MediaError \| null` | — | Read-only. |
| `isFullscreen` | `boolean` | — | Read-only. |
| `isPictureInPicture` | `boolean` | — | Read-only. |
| `liveEdgeStart` | `number` | — | Read-only. Playback time where the live edge begins. Calculated from the newest available time and the playlist's live-edge offset. `NaN` when the stream is not live or the offset is unavailable. |
| `preload` | `MediaPreloadType` | `'metadata'` | Preload type (`'none'` / `'metadata'` / `'auto'`). |
| `source` | `{ src?: string; drm?: Partial<Record<KeySystem, DrmSystemConfig>>; engine?: NativeHlsEngineConfig } \| null` | `null` | Structured source: what to play (`src`) plus how to play it (`engine.nativeHls`). Assigning it derives `src`. Only a new URL reaches the element, so reassigning an equivalent source neither reloads nor disturbs key exchange. Use `src` or `load()` to reload what is already playing. Changing this source does not emit `sourcechange`. When the hls.js media component uses native HLS playback, it emits its own `sourcechange` and forwards the native playback events. |
| `src` | `string` | `''` | Media source URL. Assigning it replaces the identity half of `source` and leaves `engine` intact, so changing the URL never disturbs key exchange. Like the element's own `src`, assigning it always loads — including the URL already playing. |
| `streamType` | `'on-demand' \| 'live' \| 'unknown'` | `'unknown'` | Current stream type (`'on-demand'` / `'live'` / `'unknown'`). |
| `targetLiveWindow` | `number` | — | Read-only. Describes the kind of live window available. `0` for a sliding live window, `Infinity` for a live event with playback history, and `NaN` for on-demand or unknown. This value is not a duration. |
| `webkitCurrentPlaybackTargetIsWireless` | `boolean \| undefined` | — | Read-only. |
| `webkitPresentationMode` | `WebKitPresentationMode \| undefined` | — | Read-only. |
| `webkitSetPresentationMode` | `((mode: WebKitPresentationMode) => void) \| undefined` | — | Read-only. |

Also exposes these properties from the native media API. See [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) for details: `autoplay`, `buffered`, `controls`, `crossOrigin`, `currentSrc`, `currentTime`, `defaultMuted`, `defaultPlaybackRate`, `disablePictureInPicture`, `disableRemotePlayback`, `duration`, `ended`, `loop`, `muted`, `paused`, `playbackRate`, `played`, `playsInline`, `poster`, `readyState`, `remote`, `seekable`, `seeking`, `textTracks`, `title`, `videoHeight`, `videoWidth`, `volume`.

### Engine options

#### `source.engine.nativeHls`

This element hands playback to the browser, so there’s no JavaScript engine to configure. This carries the one thing native playback still needs from you. [Media Sources](../../guides/media-sources.md) covers how engine options fit into a structured source.

```ts
const video = document.querySelector('native-hls-video');
video.source = {
  src: 'https://example.com/playlist.m3u8',
  engine: {
    nativeHls: {
      drmSystems: { 'com.apple.fps': { licenseUrl: 'https://example.com/license' } },
    },
  },
};
```

| Option | Type | Description |
| --- | --- | --- |
| `drmSystems` | `Partial<Record<KeySystem, DrmSystemConfig>> \| undefined` | License servers for protected content, keyed by EME key system id. An escape hatch for licensing native playback differently from every other path: naming it replaces `source.drm` here, and nowhere else. |

### Methods

Supports these media methods. See [HTMLVideoElement](https://developer.mozilla.org/en-US/docs/Web/API/HTMLVideoElement) for details: `addTextTrack`, `canPlayType`, `exitFullscreen`, `exitPictureInPicture`, `load`, `pause`, `play`, `requestFullscreen`, `requestPictureInPicture`.

### Events

Re-dispatches these standard media events from the internal media element: `abort`, `addtrack`, `canplay`, `canplaythrough`, `change`, `contentdatachange`, `durationchange`, `emptied`, `ended`, `enterpictureinpicture`, `error`, `leavepictureinpicture`, `loadeddata`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `progress`, `ratechange`, `removetrack`, `resize`, `seeked`, `seeking`, `stalled`, `suspend`, `timeupdate`, `volumechange`, `waiting`.

Also emits these Video.js-specific events:

| Event | Description |
| --- | --- |
| `streamtypechange` | Fired when the detected stream type changes. Read `streamType` for the new value. |
| `targetlivewindowchange` | Fired when the target live window changes. Read `targetLiveWindow` for the new value. |

### CSS custom properties

| Variable | Description |
| --- | --- |
| `--media-video-border-radius` | Border radius of the video element. |
| `--media-object-fit` | Object fit for the video. |
| `--media-object-position` | Object position for the video. |
| `--media-caption-track-duration` | Duration of the caption track transition. |
| `--media-caption-track-delay` | Delay before the caption track transition. |
| `--media-caption-track-y` | Vertical offset of the caption track. |