diff --git a/.github/workflows/create-documentation-pr.yml b/.github/workflows/create-documentation-pr.yml new file mode 100644 index 0000000..95bab01 --- /dev/null +++ b/.github/workflows/create-documentation-pr.yml @@ -0,0 +1,27 @@ +name: Create documentation PR +on: + # Trigger the workflow on pull requests targeting the main branch + pull_request: + types: [assigned, unassigned, opened, reopened, synchronize, edited, labeled, unlabeled, edited, closed] + branches: + - main + +jobs: + create_documentation_pr: + if: github.event.action != 'closed' + + runs-on: ubuntu-latest + + steps: + - name: Check out current repository code + uses: actions/checkout@v2 + + - name: Create the documentation pull request + uses: apivideo/api.video-create-readme-file-pull-request-action@main + with: + source-file-path: "README.md" + destination-repository: apivideo/api.video-documentation + destination-path: sdks/player + destination-filename: apivideo-player-sdk.md + pat: "${{ secrets.PAT }}" + \ No newline at end of file diff --git a/.github/workflows/update-documentation.yml b/.github/workflows/update-documentation.yml deleted file mode 100644 index e7ce49b..0000000 --- a/.github/workflows/update-documentation.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Update readme.io documentation -on: - push: - branches: - - main -jobs: - update-documentation: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Update readme.io documentation - uses: apivideo/api.video-readmeio-document-sync-action@1.2 - with: - document-slug: video-player-sdk - markdown-file-path: README.md - readme-io-api-key: ${{ secrets.README_IO_API_KEY }} - make-relative-links-absolute: true - \ No newline at end of file diff --git a/README.md b/README.md index 07ad397..b555fcc 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ + [![badge](https://img.shields.io/twitter/follow/api_video?style=social)](https://twitter.com/intent/follow?screen_name=api_video)   [![badge](https://img.shields.io/github/stars/apivideo/api.video-player-sdk?style=social)](https://github.com/apivideo/api.video-player-sdk)   [![badge](https://img.shields.io/discourse/topics?server=https%3A%2F%2Fcommunity.api.video)](https://community.api.video) ![](https://github.com/apivideo/.github/blob/main/assets/apivideo_banner.png)

api.video player SDK

@@ -5,7 +6,7 @@ [api.video](https://api.video) is the video infrastructure for product builders. Lightning fast video APIs for integrating, scaling, and managing on-demand & low latency live streaming features in your app. -# Table of contents +## Table of contents - [Table of contents](#table-of-contents) - [Project description](#project-description) @@ -15,7 +16,7 @@ - [Method #2: typescript](#method-2-typescript) - [Method #2: simple include in a javascript project](#method-2-simple-include-in-a-javascript-project) - [Documentation](#documentation) - - [Instanciation](#instanciation) + - [Instantiation](#instantiation) - [Ads](#ads) - [Methods](#methods) - [`loadConfig(options: SdkOptions)`](#loadconfigoptions-sdkoptions) @@ -59,16 +60,29 @@ -# Project description + + +## Project description SDK to control and interact with the api.video HTML5 Player -# Getting started +## Getting started -## Installation +### Installation -### Method #1: requirejs +#### Method #1: requirejs If you use requirejs you can add the SDK as a dependency to your project with @@ -87,7 +101,7 @@ var sdk = new PlayerSdk("#target", { }); ``` -### Method #2: typescript +#### Method #2: typescript If you use Typescript you can add the SDK as a dependency to your project with @@ -107,7 +121,7 @@ const sdk = new PlayerSdk("#target", { ``` -### Method #2: simple include in a javascript project +#### Method #2: simple include in a javascript project Include the SDK in your HTML file like so: @@ -128,9 +142,9 @@ Then, once the `window.onload` event has been triggered, create your player usin ``` -# Documentation +## Documentation -## Instanciation +### Instantiation The PlayerSdk constructor takes 2 parameters: - `targetSelector: string | Element` a CSS selector targeting the DOM element in which you want to create the player (eg. "#target"), or the DOM element itself @@ -140,12 +154,12 @@ The PlayerSdk constructor takes 2 parameters: | Option name | Mandatory | Type | Description | | -------------: | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------ | | id | **yes** | string | the id of the video (videoId or liveStreamId) | -| token | yes for private video | string | the [private video](https://api.video/blog/tutorials/tutorial-private-videos) url token | -| privateSession | no | string | the [private video](https://api.video/blog/tutorials/tutorial-private-videos) session id if needed | +| token | yes for private video | string | the [private video](https://api.video/blog/tutorials/tutorial-private-videos/) url token | +| privateSession | no | string | the [private video](https://api.video/blog/tutorials/tutorial-private-videos/) session id if needed | | live | no (default: false) | boolean | indicate that the video is a live one | | autoplay | no (default: false) | boolean | start playing the video as soon as it is loaded | | muted | no (default: false) | boolean | the video is muted | -| metadata | no (default: empty) | object | object containing [metadata](https://api.video/blog/tutorials/dynamic-metadata) (see **Full example** below) | +| metadata | no (default: empty) | object | object containing [metadata](https://api.video/blog/tutorials/dynamic-metadata/) (see **Full example** below) | | hideControls | no (default: false) | boolean | the controls are hidden (except unmute button if the video starts muted) | | chromeless | no (default: false) | boolean | chromeless mode: all controls are hidden | | hideTitle | no (default: false) | boolean | the video title is hidden | @@ -159,237 +173,299 @@ The PlayerSdk constructor takes 2 parameters: The sdk instance can be used to control the video playback, and to listen to player events. -### Ads +#### Ads Ads can be displayed in the player. To do so, you need to pass the `ads` option to the sdk constructor. In the `ads` object, pass the `adTagUrl` property with the url of the ad tag. The ad tag must be a VAST 2.0 or 3.0 url. For more information about VAST, check the [IAB documentation](https://www.iab.com/guidelines/vast/). Note: ads are displayed using the [Google IMA SDK](https://developers.google.com/interactive-media-ads/docs/sdks/html5/quickstart). -## Methods +### Methods The sdk instance has the following methods: -#### `loadConfig(options: SdkOptions)` -> Load a new video in the same instance of the player. Available options are the same as the ones passed to the SDK constructor (see available). -> +**`loadConfig(options: SdkOptions)`** + +Load a new video in the same instance of the player. Available options are the same as the ones passed to the SDK constructor (see available). + > Example: -> ```javascript -> player.loadConfig({ -> id: "", -> hideTitle: true, -> hideControls: true, -> }); -> ``` -#### `play()` -> Start playing the video. -#### `pause()` -> Pause the video playback. -#### `mute()` -> Mute the video. -#### `unmute()` -> Unmute the video. -#### `hideControls(controls?: ControlName[])` -> Hide the player controls. -> -> `controls` parameter type definition: -> ```typescript -> type ControlName = "play" | "seekBackward" | "seekForward" | "playbackRate" -> | "volume" | "fullscreen" | "subtitles" | "chapters" -> | "pictureInPicture" | "progressBar" | "chromecast" | "download" | "more"; -> ``` -> +```javascript + player.loadConfig({ + id: "", + hideTitle: true, + hideControls: true, + }); +``` +**`play()`** + +Start playing the video. + +**`pause()`** + +Pause the video playback. + +**`mute()`** + +Mute the video. + +**`unmute()`** + +Unmute the video. + +**`hideControls(controls?: ControlName[])`** + +Hide the player controls. + + +`controls` parameter type definition: +```typescript +type ControlName = "play" | "seekBackward" | "seekForward" | "playbackRate" + | "volume" | "fullscreen" | "subtitles" | "chapters" + | "pictureInPicture" | "progressBar" | "chromecast" | "download" | "more"; +``` > If no value is provided for the "controls" parameter, all controls will be hidden. -> -> **Note**: the only control that can still be visible is the unmute button if the video as started muted. To hide all controls, including this one, use the setChromeless() method -> -> Example: -> ```javascript -> player.hideControls(); -> ``` -> + +**Note**: the only control that can still be visible is the unmute button if the video as started muted. To hide all controls, including this one, use the setChromeless() method + +Example: +```javascript + player.hideControls(); +``` > If a list of control names if provided, the associated controls will be hidden. -> -> Example: -> ```javascript -> player.showControls(); // display all controls ... -> player.hideControls(["download", "subtitles"]); // ... except "download" and "subtitles" -> ``` -> -#### `showControls(controls?: ControlName[])` -> Show the player controls. -> -> `controls` parameter type definition: -> ```typescript -> type ControlName = "play" | "seekBackward" | "seekForward" | "playbackRate" -> | "volume" | "fullscreen" | "subtitles" | "chapters" -> | "pictureInPicture" | "progressBar" | "chromecast" | "download" | "more"; -> ``` -> + +Example: +```javascript + player.showControls(); // display all controls ... + player.hideControls(["download", "subtitles"]); // ... except "download" and "subtitles" +``` +**`showControls(controls?: ControlName[])`** + +Show the player controls. + + +`controls` parameter type definition: +```typescript +type ControlName = "play" | "seekBackward" | "seekForward" | "playbackRate" + | "volume" | "fullscreen" | "subtitles" | "chapters" + | "pictureInPicture" | "progressBar" | "chromecast" | "download" | "more"; +``` > If no value is provided for the "controls" parameter, all controls will be displayed. -> -> Example: -> ```javascript -> player.showControls(); -> ``` -> + +Example: +```javascript + player.showControls(); +``` > If a list of control names if provided, the associated controls will be displayed. -> -> Example: -> ```javascript -> player.hideControls(); // hide all controls ... -> player.showControls(["download", "subtitles"]); // ... except "download" and "subtitles" ... -> // ... -> player.showControls(["progressBar"]); // ... and the progress bar -> ``` -> -#### `setChromeless(chromeless: boolean)` -> Define if the player should be in chromeless mode (all controls hidden). -#### `hideSubtitles()` -> Hide the player subtitles. -#### `showSubtitles()` -> Show the player subtitles. -#### `hideTitles()` -> Hide the video title at the top of the video. -#### `showTitles()` -> Show the video title at the top of the video. -#### `setLoop(loop: boolean)` -> Define if the video should be played in loop. -#### `setAutoplay(autoplay: boolean)` -> Define if the video should start playing as soon as it is loaded -#### `seek(time: number)` -> Add/substract the given number of seconds to/from the playback time. -#### `setPlaybackRate(rate: number)` -> Set the current playback rate. ->Example: ->```javascript -> player.setPlaybackRate(2); // Play at 2x rate ->``` -#### `setCurrentTime(time: number)` -> Set the current playback time (seconds). -> + +Example: +```javascript + player.hideControls(); // hide all controls ... + player.showControls(["download", "subtitles"]); // ... except "download" and "subtitles" ... + // ... + player.showControls(["progressBar"]); // ... and the progress bar +``` +**`setChromeless(chromeless: boolean)`** + +Define if the player should be in chromeless mode (all controls hidden). + +**`hideSubtitles()`** + +Hide the player subtitles. + +**`showSubtitles()`** + +Show the player subtitles. + +**`hideTitles()`** + +Hide the video title at the top of the video. + +**`showTitles()`** + +Show the video title at the top of the video. + +**`setLoop(loop: boolean)`** + +Define if the video should be played in loop. + +**`setAutoplay(autoplay: boolean)`** + +Define if the video should start playing as soon as it is loaded + +**`seek(time: number)`** + +Add/substract the given number of seconds to/from the playback time. + +**`setPlaybackRate(rate: number)`** + +Set the current playback rate. + +Example: +```javascript + player.setPlaybackRate(2); // Play at 2x rate +``` +**`setCurrentTime(time: number)`** + +Set the current playback time (seconds). + >Example: ->```javascript -> player.setCurrentTime(24); // Go the 24th second ->``` -#### `setVolume(volume: number)` -> Change the audio volume to the given value. From 0 to 1 (0 = muted, 1 = 100%). -> -> Example: -> ```javascript -> player.setVolume(0.75); // Set the volume to 75% -> ``` -#### `setVideoStyleObjectFit(value: "contain" | "cover" | "fill" | "none" | "scale-down")` -> Change the [object-fit](https://developer.mozilla.org/fr/docs/Web/CSS/object-fit) CSS value of the video tag. +```javascript + player.setCurrentTime(24); // Go the 24th second +``` +**`setVolume(volume: number)`** + +Change the audio volume to the given value. From 0 to 1 (0 = muted, 1 = 100%). > Example: -> ```javascript -> player.setVideoStyleObjectFit("cover"); // Set the object-fit to cover -> ``` +```javascript + player.setVolume(0.75); // Set the volume to 75% +``` +**`setVideoStyleObjectFit(value: "contain" | "cover" | "fill" | "none" | "scale-down")`** -#### `setVideoStyleTransform(value: string)` -> Change the [transform](https://developer.mozilla.org/fr/docs/Web/CSS/transform) CSS value of the video tag. +Change the [object-fit](https://developer.mozilla.org/fr/docs/Web/CSS/object-fit) CSS value of the video tag. + +Example: +```javascript + player.setVideoStyleObjectFit("cover"); // Set the object-fit to cover +``` + +**`setVideoStyleTransform(value: string)`** + +Change the [transform](https://developer.mozilla.org/fr/docs/Web/CSS/transform) CSS value of the video tag. + + +Example: +```javascript + player.setVideoStyleTransform("rotateY(180deg)"); // Apply a 180deg rotation around the Y axis (mirroring) +``` + +**`setTheme(theme: PlayerTheme)`** + +Change the appearance of the player. + + +`theme` parameter type definition: +```typescript +type PlayerTheme = { + text?: string; + link?: string; + linkHover?: string; + trackPlayed?: string; + trackUnplayed?: string; + trackBackground?: string; + backgroundTop?: string; + backgroundBottom?: string; + backgroundText?: string; + linkActive?: string; +} +``` > Example: -> ```javascript -> player.setVideoStyleTransform("rotateY(180deg)"); // Apply a 180deg rotation around the Y axis (mirroring) -> ``` - -#### `setTheme(theme: PlayerTheme)` -> Change the appearance of the player. -> -> `theme` parameter type definition: -> ```typescript -> type PlayerTheme = { -> text?: string; -> link?: string; -> linkHover?: string; -> trackPlayed?: string; -> trackUnplayed?: string; -> trackBackground?: string; -> backgroundTop?: string; -> backgroundBottom?: string; -> backgroundText?: string; -> linkActive?: string; -> } -> ``` -> -> Example: -> ```javascript -> player.setTheme({ -> link: "red", -> linkHover: "rgba(0, 255, 0, 1)", -> backgroundBottom: "#0000ff", -> }); -> ``` - -#### `requestFullscreen()` -> Request fullscreen mode (this may not work in some cases depending on browser restrictions) -#### `exitFullscreen()` -> Leave fullscreen mode -#### `requestPictureInPicture()` -> Request picture in picture mode (this may not work in some cases depending on browser restrictions) -#### `exitPictureInPicture()` -> Leave picture in picture mode -#### `getPaused(callback?: (paused: boolean) => void): Promise` -> Check weither the video is paused. -#### `getPlaying(callback?: (playing: boolean) => void): Promise` -> Check weither the video is playing. -#### `getMuted(callback?: (muted: boolean) => void): Promise` -> Check weither the video is muted. -#### `getDuration(callback?: (duration: number) => void): Promise` -> Retrieve the duration of the video. -#### `getCurrentTime(callback?: (currentTime: number) => void): Promise` -> Retrieve the current playback time of the video. -#### `getVolume(callback?: (volume: number) => void): Promise` -> Retrieve the current volume. -#### `getLoop(callback?: (loop: boolean) => void): Promise` -> Check whether the video is in loop mode. -#### `getPlaybackRate(callback?: (rate: number) => void): Promise` -> Retrieve the playback rate. -#### `isLiveStream(callback?: (live: boolean) => void): Promise` -> Check whether the video is a live stream. -#### `destroy()` -> Destroy the player instance. -#### `addEventListener(event: string, callback: () => void)` -> Define a callback function that will be called when the given event is triggered by the player. -> -> Available events are the following: -> -> Event name | Description | Parameter -> ---: | --- | --- -> controlsdisabled | Controls are now disabled | - -> controlsenabled | Controls are now enabled | - -> ended | The playback as reached the ended of the video | - -> error | An error occured | - -> firstplay | The video started to play for the first time | - -> fullscreenchange | The player goes to (or goes back from) full screen | - -> mouseenter | The user's mouse entered the player area | - -> mouseleave | The user's mouse leaved the player area | - -> pause | The video has been paused | - -> play | The video started to play (for the first time or after having been paused) | - -> playerresize | The player size has changed | - -> qualitychange | The video quality has changed | `{ resolution: { height: number, width: number } }` -> ratechange | The playback rate has changed | - -> ready | The player is ready to play | - -> resize | The video size has changed -> seeking | The player is seeking | - -> timeupdate | The playback time has changed | `{ currentTime: number }` -> useractive | The user is active | - -> userinactive | The user is inactive | - -> volumechange | The volume has changed | `{ volume: number }` -> -> Examples: -> ```javascript -> // listen to the 'play' event -> player.addEventListener('play', function() { -> console.log('play event received'); -> }); -> -> player.addEventListener('qualitychange', function(ev) { -> console.log(`quality has changed: ${ev.resolution.width}x${ev.resolution.height}`); -> }); -> ``` - -## Full example +```javascript + player.setTheme({ + link: "red", + linkHover: "rgba(0, 255, 0, 1)", + backgroundBottom: "#0000ff", + }); +``` + +**`requestFullscreen()`** + +Request fullscreen mode (this may not work in some cases depending on browser restrictions) + +**`exitFullscreen()`** + +Leave fullscreen mode + +**`requestPictureInPicture()`** + +Request picture in picture mode (this may not work in some cases depending on browser restrictions) + +**`exitPictureInPicture()`** + +Leave picture in picture mode + +**`getPaused(callback?: (paused: boolean) => void): Promise`** + +Check weither the video is paused. + +**`getPlaying(callback?: (playing: boolean) => void): Promise`** + +Check weither the video is playing. + +**`getMuted(callback?: (muted: boolean) => void): Promise`** + +Check weither the video is muted. + +**`getDuration(callback?: (duration: number) => void): Promise`** + +Retrieve the duration of the video. + +**`getCurrentTime(callback?: (currentTime: number) => void): Promise`** + +Retrieve the current playback time of the video. + +**`getVolume(callback?: (volume: number) => void): Promise`** + +Retrieve the current volume. + +**`getLoop(callback?: (loop: boolean) => void): Promise`** + +Check whether the video is in loop mode. + +**`getPlaybackRate(callback?: (rate: number) => void): Promise`** + +Retrieve the playback rate. + +**`isLiveStream(callback?: (live: boolean) => void): Promise`** + +Check whether the video is a live stream. + +**`destroy()`** + +Destroy the player instance. + +**`addEventListener(event: string, callback: () => void)`** + +Define a callback function that will be called when the given event is triggered by the player. + + +Available events are the following: + +Event name | Description | Parameter +---: | --- | --- +controlsdisabled | Controls are now disabled | - +controlsenabled | Controls are now enabled | - +ended | The playback as reached the ended of the video | - +error | An error occured | - +firstplay | The video started to play for the first time | - +fullscreenchange | The player goes to (or goes back from) full screen | - +mouseenter | The user's mouse entered the player area | - +mouseleave | The user's mouse leaved the player area | - +pause | The video has been paused | - +play | The video started to play (for the first time or after having been paused) | - +playerresize | The player size has changed | - +qualitychange | The video quality has changed | `{ resolution: { height: number, width: number } }` +ratechange | The playback rate has changed | - +ready | The player is ready to play | - +resize | The video size has changed +seeking | The player is seeking | - +timeupdate | The playback time has changed | `{ currentTime: number }` +useractive | The user is active | - +userinactive | The user is inactive | - +volumechange | The volume has changed | `{ volume: number }` + +Examples: +```javascript + // listen to the 'play' event + player.addEventListener('play', function() { + console.log('play event received'); + }); + + player.addEventListener('qualitychange', function(ev) { + console.log(`quality has changed: ${ev.resolution.width}x${ev.resolution.height}`); + }); +``` + +### Full example ```html @@ -434,7 +510,7 @@ The sdk instance has the following methods: ``` -## Control an existing embedded player using the SDK +### Control an existing embedded player using the SDK It's also possible to integrate the SDK in a page that already contains an embedded player in order to control it and to listen to its events. Let's consider the following page :