# spotify-audio

Audio component that plays Spotify tracks, episodes, playlists, and shows through the Spotify embed

The [Spotify embed](https://developer.spotify.com/documentation/embeds) accepts tracks, episodes, albums, playlists, shows, and artists. Podcast episodes play in full for signed-out listeners; music plays as a preview until the listener logs in to Spotify.

## Import

```bash
pnpm add @videojs/spotify-audio
```

```ts
import '@videojs/html/media/spotify-audio';
```

Or load it from the [CDN](https://videojs.org/docs/framework/html/guides/cdn):

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@videojs/cdn@10.0.0-rc.4/media/spotify-audio.js"></script>
```

## Load a source

`src` takes an `open.spotify.com` URL for any embeddable entity, including the localized (`/intl-de/`) and already-embedded (`/embed/`) forms, or a `spotify:<type>:<id>` URI. A `t` parameter sets the start position in seconds.

```html
<spotify-audio src="https://open.spotify.com/episode/7makk4oTQel546B0PZlDM5" controls></spotify-audio>
```

## Controls

Spotify’s own chrome is the only UI the embed offers, so `controls` decides whether the element is visible at all. With `controls`, it shows Spotify’s player. Without it, the element hides itself and plays as an invisible transport: a hidden iframe still loads and plays, so a [player skin](https://videojs.org/docs/framework/html/guides/skins)’s buttons drive playback while the embed takes no room on the page.

## Behavior

The Spotify embed exposes less than a native `<audio>` element:

- No volume and no mute: the embed takes neither command and reports neither value, so a player skin shows no volume controls at all.
- No playback rate and no text tracks.
- `loop` replays the entity from the top when it ends; without it, the embed continues into whatever Spotify queues next.

## Examples

### Basic Usage

**index.html**

```html
<spotify-audio class="spotify-audio" src="https://open.spotify.com/episode/7makk4oTQel546B0PZlDM5" controls></spotify-audio>
```

**index.css**

```css
.spotify-audio {
  width: 100%;
  height: 152px;
}
```

**index.ts**

```ts
import '@videojs/html/media/spotify-audio';
```

## API Reference

### Attributes

These attributes configure the embedded media adapter:

| Attribute | Type | Default |
| --- | --- | --- |
| `autoplay` | `boolean` | `false` |
| `controls` | `boolean` | `false` |
| `loop` | `boolean` | `false` |
| `playsinline` | `boolean` | `true` |
| `poster` | `string` | `''` |
| `preload` | `MediaPreloadType` | `'metadata'` |
| `src` | `string` | `''` |

### Properties

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `autoplay` | `boolean` | `false` | |
| `buffered` | `TimeRangeLike` | — | Read-only. |
| `controls` | `boolean` | `false` | |
| `currentSrc` | `string` | — | Read-only. |
| `currentTime` | `number` | — | |
| `duration` | `number` | — | Read-only. |
| `ended` | `boolean` | — | Read-only. |
| `engine` | `{ iframeElement: HTMLIFrameElement; loadUri(uri: string): void; play(): void; resume(): void; pause(): void; togglePlay(): void; seek(seconds: number): void; destroy(): void; addListener(type: 'ready', listener: (() => void)): void; addListener(type: 'playback_update', listener: ((event: SpotifyPlaybackUpdateEvent) => void)): void } \| null` | — | Read-only. Underlying Spotify iframe API controller (null until the API loads). |
| `error` | `MediaError \| null` | — | Read-only. |
| `loop` | `boolean` | `false` | |
| `paused` | `boolean` | — | Read-only. |
| `played` | `{ length: number; start(index: number): number; end(index: number): number }` | — | Read-only. |
| `playsInline` | `boolean` | `true` | |
| `poster` | `string` | `''` | |
| `preload` | `MediaPreloadType` | `'metadata'` | |
| `readyState` | `number` | — | Read-only. |
| `seekable` | `TimeRangeLike` | — | Read-only. |
| `seeking` | `boolean` | — | Read-only. |
| `source` | `{ src?: string; engine?: SpotifySourceEngineConfig } \| null` | `null` | Spotify URL or URI in `src`, plus embed options under `engine.spotify`. Replacing it re-derives `src`. |
| `src` | `string` | `''` | |
| `textTracks` | `TextTrackListLike` | — | Read-only. Always empty: the embed exposes no captions or other text tracks. |

### Engine options

#### `source.engine.spotify`

Pass [Spotify embed options](https://developer.spotify.com/documentation/embeds) under `source.engine.spotify`, spelled exactly as Spotify spells them, plus anything Spotify adds next. [Media Sources](https://videojs.org/docs/framework/html/guides/media-sources) covers how engine options fit into a structured source.

```ts
const audio = document.querySelector('spotify-audio');
audio.source = {
  src: 'https://open.spotify.com/episode/7makk4oTQel546B0PZlDM5',
  engine: { spotify: { t: 90, theme: 0 } },
};
```

| Option | Type | Description |
| --- | --- | --- |
| `preferVideo` | `boolean \| undefined` | Embed the video variant of an episode when it has one. Not a URL parameter: the video embed lives at its own path. |
| `referrerPolicy` | `ReferrerPolicy \| undefined` | `referrerpolicy` for the embed iframe. Not a Spotify embed parameter. |
| `t` | `number \| undefined` | Start position in seconds. |
| `theme` | `0 \| undefined` | `0` renders the embed in its dark theme. Defaults to the light theme. Spotify documents no other value, and the embed goes by whether the parameter is there, so leaving it out is the only way to ask for the default. |

### Methods

Supports these media methods: `load`, `pause`, `play`.

### Events

Implements these standard media events through the embedded player: `durationchange`, `emptied`, `ended`, `error`, `loadedmetadata`, `loadstart`, `pause`, `play`, `playing`, `seeked`, `seeking`, `timeupdate`, `waiting`.

Also emits these Video.js-specific events:

| Event | Description |
| --- | --- |
| `loadcomplete` | |
| `sourcechange` | Fired when `source` changes, either directly or by resolving a new `src`. Read `source` for the new value. |

---

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