# @broadcastingplatforms/player

Universal video player web component built with Lit. Supports HLS, WebRTC (via nanoStream), and LiveKit.

## Installation

```bash
npm install @broadcastingplatforms/player
# or
pnpm add @broadcastingplatforms/player
```

## Standalone vs Non-Standalone

### Standalone Bundle

Use the standalone bundle when you want a single file with all dependencies (HLS.js, etc.) bundled. Ideal for CDN usage or simple HTML pages.

```html
<script type="module" src="https://unpkg.com/@broadcastingplatforms/player/dist/bp-player.standalone.mjs"></script>

<bp-player
  source='{"sources":[{"type":"video","url":"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"}]}'
  muted
  autoplay
></bp-player>
```

### Non-Standalone (Bundler)

Use the standard import when using a bundler (Vite, webpack, etc.). Dependencies are external and tree-shakeable.

```ts
import '@broadcastingplatforms/player';
```

```html
<bp-player
  source='{"sources":[{"type":"video","url":"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"}]}'
  muted
  autoplay
></bp-player>
```

## Basic Usage

### HLS Video (Big Buck Bunny)

```html
<bp-player
  source='{"sources":[{"type":"video","url":"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"}],"poster":"https://peach.blender.org/wp-content/uploads/bbb-splash.png"}'
  muted
  autoplay
></bp-player>
```

### BPLive Stream

Play a live stream from the BPLive platform:

```html
<bp-player id="live-player" muted autoplay></bp-player>

<script type="module">
  const player = document.getElementById('live-player');

  player.source = { sources: [{ type: 'bplive', streamId: 123 }] };
  player.config = {
    bpLive: {
      discoveryUrl: 'https://api.example.com',
      authToken: await getAuthToken() // Set programmatically, not in HTML
    }
  };
</script>
```

### BPLive Clip

Play a clip from the BPLive platform:

```html
<bp-player id="clip-player" muted autoplay></bp-player>

<script type="module">
  const player = document.getElementById('clip-player');

  player.source = {
    sources: [{ type: 'bplive', clipId: 456, preferredOrientation: 'portrait' }]
  };
  player.config = {
    bpLive: {
      discoveryUrl: 'https://api.example.com',
      authToken: await getAuthToken() // Set programmatically, not in HTML
    }
  };
</script>
```

### With Default UI

```html
<bp-default-ui
  source='{"sources":[{"type":"video","url":"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"}]}'
></bp-default-ui>
```

### Programmatic Control

```ts
import { BPPlayer, type SourceDescription } from '@broadcastingplatforms/player';

const player = document.querySelector('bp-player') as BPPlayer;

// Set source via property (object)
player.source = {
  sources: [{ type: 'video', url: 'https://example.com/stream.m3u8' }],
  poster: 'https://example.com/poster.jpg'
};

player.addEventListener('ready', (e) => {
  const core = e.detail; // PlayerCore instance
  
  core.play();
  core.pause();
  core.seek(30); // seek to 30 seconds
  core.setVolume(0.5);
  core.setMuted(true);
  
  // Access current state
  console.log(core.state.currentTime);
  console.log(core.state.duration);
  console.log(core.state.paused);
});
```

## Attributes

Attributes can be set as JSON strings or as JavaScript properties.

| Attribute | Type | Description |
|-----------|------|-------------|
| `source` | `SourceDescription` (JSON) | Source description with `sources` array and optional `poster` |
| `config` | `ProviderConfig` (JSON) | Provider configuration (HLS, NanoPlayer, LiveKit, BPLive) |
| `autoplay` | `boolean` | Auto-start playback |
| `muted` | `boolean` | Start muted |
| `loop` | `boolean` | Loop playback |

### SourceDescription

```ts
interface SourceDescription {
  sources: PlayerSource[];
  poster?: string;
}
```

### PlayerSource Types

```ts
// Standard video/HLS source
interface VideoSource {
  type: 'video';
  url: string;
}

// BPLive stream source
interface BPLiveStreamSource {
  type: 'bplive';
  streamId: number;
}

// BPLive clip source
interface BPLiveClipSource {
  type: 'bplive';
  clipId: number;
  preferredOrientation?: 'landscape' | 'portrait'; // defaults to 'landscape'
}
```

### ProviderConfig

```ts
interface ProviderConfig {
  bpLive?: BPLiveConfig;
  // ... other provider configs
}

interface BPLiveConfig {
  discoveryUrl: string;  // Base URL of the BPLive API (required)
  authToken?: string;    // Bearer token for authenticated API requests
}
```

### Analytics

Connect analytics via the `ready` event using `@broadcastingplatforms/web-connectors`:

```html
<bp-player
  id="player"
  source='{"sources":[{"type":"video","url":"..."}]}'
></bp-player>

<script type="module">
  import { createMuxConnector } from '@broadcastingplatforms/web-connectors/mux';

  document.getElementById('player').addEventListener('ready', (e) => {
    // Auto-destroys when player is destroyed
    createMuxConnector(e.detail, {
      envKey: 'your-mux-env-key',
      data: { video_title: 'My Video' }
    });
  });
</script>
```

## Events

| Event | Detail | Description |
|-------|--------|-------------|
| `ready` | `PlayerCore` | Fired when player is ready |
| `play` | - | Playback started |
| `pause` | - | Playback paused |
| `ended` | - | Playback ended |
| `timeupdate` | - | Current time updated |
| `error` | - | Playback error occurred |

## Custom Video Elements

For advanced use cases, you can use the custom video elements directly:

```ts
import { HlsVideoElement, NanoVideoElement, LiveKitVideoElement } from '@broadcastingplatforms/player/elements';
```

These are [media-chrome](https://www.media-chrome.org/) compatible custom elements.
