# Brightcove Web and Smart TV SDK
The Brightcove Web and Smart TV SDK is a general-purpose SDK for implementing the Brightcove Player in modern applications on web-based platforms - desktop browsers, mobile browsers, and web-based Smart TVs.

## Table of Contents

- [Installation](#installation)
  - [NPM](#npm)
  - [CDN](#cdn)
  - [Specifying a Version](#specifying-a-version)
- [Usage](#usage)
  - [Importing the Player](#importing-the-player)
    - [Playback-Only](#playback-only)
    - [Playback with UI](#playback-with-ui)
  - [Initializing a Player](#initializing-a-player)
  - [Loading Media](#loading-media)
    - [Video Cloud VOD](#video-cloud-vod)
    - [Video Cloud Playlist](#video-cloud-playlist)
    - [Remote Source](#remote-source)
  - [`IntegrationsManager`](#integrationsmanager)
  - [`NetworkingManager`](#networkingmanager)
  - [`UiManager`](#uimanager)
  - [`Playlist` and `PlaylistManager`](#playlist-and-playlistmanager)
  - [Events](#events)
  - [Errors](#errors)
  - [Styling](#styling)
  - [Smart TV Usage](#smart-tv-usage)
  - [Localizations](#localizations)
- [API Documentation](#api-documentation)

## Installation

### NPM
To install the Brightcove Web and Smart TV SDK via npm, run the following command:

```sh
npm install @brightcove/web-sdk
```

After installation, you can import the SDK using your preferred module system:

#### CommonJS
```js
const { Player } = require('@brightcove/web-sdk');
```

#### ES Module
```js
import { Player } from '@brightcove/web-sdk';
```

### CDN
You can also include the SDK directly from a CDN:

#### CommonJS:

````html
<script src="https://players.brightcove.net/sdk/v1/playback/index.cjs.js"></script>
````

#### ES Module:

```html
<script type="module" src="https://players.brightcove.net/sdk/v1/playback/index.es.js"></script>
```

#### IIFE (Immediately Invoked Function Expression):

```html
<script src="https://players.brightcove.net/sdk/v1/playback/index.iife.min.js"></script>
```

### Specifying a Version
To specify a version in the CDN URL:

- Use `v{major}` to include the latest patch within a major version.
- Use `v{major}.{minor}` to include the latest patch within a minor version.
- Use `v{major}.{minor}.{patch}` to include a specific version.

For example:

```html
<script src="https://players.brightcove.net/sdk/v1/playback/index.iife.min.js"></script>
<script src="https://players.brightcove.net/sdk/v1.1/playback/index.iife.min.js"></script>
<script src="https://players.brightcove.net/sdk/v1.1.1/playback/index.iife.min.js"></script>
```

## Usage

### Importing the Player

#### Playback-Only
For applications that only require playback functionality, and no additional UI features, you can use the playback-only player entry point:

```js
import { Player } from '@brightcove/web-sdk/playback';
```

#### Playback with UI
For applications that need playback functionality along with a UI, use the following player entry point:

```js
import { Player } from '@brightcove/web-sdk';
import '@brightcove/web-sdk/styles';
```

### Initializing a Player
```js
import { Player } from '@brightcove/web-sdk';
import '@brightcove/web-sdk/styles';

const player = new Player({
  // Account ID parameter is required to initialize a player
  accountId: '<ACCOUNT_ID>',

  // Examples of optional parameters
  brightcove: {
    policyKey: '<POLICY_KEY>'
  },
  ui: {
    language: 'fr',
    playsinline: true
  }
});

const root = document.querySelector('#player-mount-root');

// Attach the player to a mount root (DOM element in the page).
player.attach(root);

// Dynamically update params in the player configuration
player.updateConfiguration({
  ui: {
    language: 'en',
    playsinline: false
  }
});
```

### Loading Media

#### Video Cloud VOD
```js
const player = new Player({
  accountId: '<ACCOUNT_ID>',
  brightcove: {
    policyKey: '<POLICY_KEY>'
  }
});

async function loadVideo(videoId) {
  const { promise } = player.getVideoByIdFromPlaybackApi({ videoId });

  try {
    let videoModel = await promise;

    player.loadBrightcoveVideoModel(videoModel);
  } catch (error) {
    // Handle error
    console.error('Error loading video:', error);
  }
}

loadVideo('<VIDEO_ID>');
```

#### Video Cloud Playlist
```js
const player = new Player({
  accountId: '<ACCOUNT_ID>',
  brightcove: {
    policyKey: '<POLICY_KEY>'
  }
});

async function loadPlaylist(playlistId) {
  const { promise } = player.getPlaylistByIdFromPlaybackApi({ playlistId });

  try {
    const playlistModel = await promise;
    const playlistManager = player.getPlaylistManager();

    // Create playlist object
    const playlist = playlistManager.createPlaylistFromBrightcoveVideoModels(playlistModel.videos);

    // Pass the playlist object to the PlaylistManager
    playlistManager.setPlaylist(playlist);

    // Load the first playlist item
    player.loadBrightcoveVideoModel(playlist.getCurrentItem());
  } catch (error) {
    // Handle error
    console.error('Error loading playlist:', error);
  }
}

loadPlaylist('<PLAYLIST_ID>');

function advanceToNextItem() {
  try {
    const playlistManager = player.getPlaylistManager();
    const playlist = playlistManager.getPlaylist();

    // Advance to the next item
    playlist.moveToNext();
    player.loadBrightcoveVideoModel(playlist.getCurrentItem());
  } catch (error) {
    // Handle error
    console.error('Error advancing to next item:', error);
  }
}

advanceToNextItem();
```

#### Remote Source
```js
const player = new Player({
  // accountId is still required even when loading remote media
  accountId: '<ACCOUNT_ID>'
});

const source = {
  url: 'http://video.com/index.m3u8'
};

try {
  player.loadRemoteVideo(source);
} catch (error) {
  // Handle error
}
```

### `IntegrationsManager`
You can integrate specific features using modular imports and the `IntegrationsManager`:

```js
import { Player, IntegrationsManager } from '@brightcove/web-sdk';
import { PinningIntegration } from '@brightcove/web-sdk/integrations/pinning';
import { ThumbnailsIntegration } from '@brightcove/web-sdk/integrations/thumbnails';
import '@brightcove/web-sdk/styles';
import '@brightcove/web-sdk/integrations/pinning/styles';
import '@brightcove/web-sdk/integrations/thumbnails/styles';

// Register integrations before creating a Player
IntegrationsManager.registerPinningIntegrationFactory(PinningIntegration);
IntegrationsManager.registerThumbnailsIntegrationFactory(ThumbnailsIntegration);

const player = new Player({
  accountId: '<ACCOUNT_ID>',

  // Integrations can have their own configuration options
  integrations: {
    pinning: {
      posX: 'left',
      posY: 'top',
      closeable: true
    }
  }
});

const root = document.querySelector('#player-mount-root');

player.attach(root);

// Access individual integrations via the IntegrationsManager
const { pinningIntegration } = player.getIntegrationsManager();

// Perform integration-specific operations
pinningIntegration.togglePinning();
```

### `NetworkingManager`
The `NetworkingManager` can be used to hook into the SDK's request/response cycle:

```js
const networkingManager = player.getNetworkingManager();

networkingManager.addRequestInterceptor(Player.RequestType.HlsPlaylist, (request) => {
  console.log('HLS Playlist request interceptor ', request);

  return request;
});

networkingManager.addResponseInterceptor(Player.RequestType.HlsPlaylist, (response) => {
  console.log('HLS Playlist response interceptor ', response);

  return response;
});
```

### `UiManager`
```js
TODO
```

### `Playlist` and `PlaylistManager`
The `PlaylistManager` is used for manipulation of a `Playlist` object, comprising a list of media sources:

```js
const playlistManager = player.getPlaylistManager();

// Create playlist object from a Playback API response
const videoCloudPlaylist = playlistManager.createPlaylistFromBrightcoveVideoModels(/* Array<BrightcoveVideoModel> */);

// Create playlist object from remote sources
const remotePlaylist = playlistManager.createPlaylistFromRemoteSources(/* Array<Source> */);

// Pass the playlist object to the PlaylistManager
playlistManager.setPlaylist(/* videoCloudPlaylist | remotePlaylist */);

// Load the first playlist item
player.loadBrightcoveVideoModel(playlist.getCurrentItem());

// Playlist methods to set a new item index as the current index
playlist.moveToNext();
playlist.moveToPrevious();
playlist.moveTo(/* index number */)
playlist.shuffle();

// Load the new playlist item
player.loadBrightcoveVideoModel(playlist.getCurrentItem());
```

### Events
```js
// Handle only the first emission of the PlayerPlaying event
player.once(Player.Event.PlayerPlaying, (event) => {
  console.log('PlayerPlaying event: ', event);
});

const handlePlayerQualityLevelsChanged = (event) => console.log('PlayerQualityLevelsChanged event: ', event);

// Handle every emission of the PlayerQualityLevelsChanged event
player.addEventListener(Player.Event.PlayerQualityLevelsChanged, handlePlayerQualityLevelsChanged);

// Remove one specific event listener
player.removeEventListener(Player.Event.PlayerQualityLevelsChanged, handlePlayerQualityLevelsChanged);

// Remove all listeners for a specific event
player.removeAllEventListenersForType(Player.Event.PlayerQualityLevelsChanged);

// Remove all event listeners
player.removeAllEventListeners();
```

### Errors
TODO

### Styling
TODO

### Smart TV Usage
TODO

### Localizations
Support for multiple languages and localizations can be included as follows:

```js
import Japanese from '@brightcove/web-sdk/ui/languagePacks/ja';

// .. other imports and code

const uiManager = player.getUiManager();

uiManager.addLanguagePack('ja', Japanese);
```

## API Documentation
Detailed API documentation is available here (TODO: ADD LINK)
