From 9055b14cf40b3492cca43f4f0cdb8b0f3bc24b35 Mon Sep 17 00:00:00 2001 From: Krzysztof Moch Date: Thu, 6 Mar 2025 12:38:25 +0100 Subject: [PATCH] docs: update structure (#4454) * [Preview] docs: update (#9) Co-authored-by: Bart Widlarz * docs: update links * docs: fix naming * docs: update footer * docs: update content * docs: refine grammar * fix(docs): update typo * docs: update url * refactor: sdk name * docs: add issue boost link * docs: add new roadmap to readme * lint code --------- Co-authored-by: Bart Widlarz Co-authored-by: Kamil --- README.md | 3 + docs/pages/_meta.json | 34 +- docs/pages/component/ads.md | 25 +- docs/pages/component/drm.mdx | 205 ++++--- docs/pages/component/events.mdx | 572 +++++++++---------- docs/pages/component/methods.mdx | 282 ++++++---- docs/pages/component/props.mdx | 913 ++++++++++++++++--------------- docs/pages/index.md | 74 +-- docs/pages/installation.md | 134 +++-- docs/pages/other/_meta.json | 3 +- docs/pages/other/caching.md | 23 +- docs/pages/other/debug.md | 99 ++-- docs/pages/other/downloading.md | 40 ++ docs/pages/other/expo.md | 12 +- docs/pages/other/misc.md | 50 +- docs/pages/other/new-arch.md | 15 +- docs/pages/other/plugin.md | 153 +++--- docs/pages/projects.md | 22 +- docs/pages/updating.md | 39 +- docs/theme.config.jsx | 3 +- 20 files changed, 1455 insertions(+), 1246 deletions(-) create mode 100644 docs/pages/other/downloading.md diff --git a/README.md b/README.md index 8ce122d5..c938d60a 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,9 @@ var styles = StyleSheet.create({ }); ``` +## Roadmap +You can follow our work on the library at [Roadmap](https://github.com/orgs/TheWidlarzGroup/projects/6). + ## Community support We have an discord server where you can ask questions and get help. [Join the discord server](https://discord.gg/WXuM4Tgb9X) diff --git a/docs/pages/_meta.json b/docs/pages/_meta.json index 7724fe19..e210b3f4 100644 --- a/docs/pages/_meta.json +++ b/docs/pages/_meta.json @@ -7,29 +7,39 @@ "type": "separator", "title": "" }, - "updating": "Updating", - "changelog": { - "title": "Changelog", - "newWindow": true, - "href": "https://github.com/TheWidlarzGroup/react-native-video/blob/master/CHANGELOG.md" - }, - "separator_community": { - "type": "separator", - "title": "" - }, "example_apps": { "title": "Example Apps", "newWindow": true, "href": "https://github.com/TheWidlarzGroup/react-native-video/tree/master/examples" }, "projects": "Useful projects", - "separator_enterprise": { + "separator_community": { "type": "separator", "title": "" }, + "video_offline_sdk": { + "title": "Offline Video SDK", + "newWindow": true, + "href": "https://www.thewidlarzgroup.com/offline-video-sdk/?utm_source=rnv&utm_medium=docs&utm_campaign=sidebar&utm_id=offline-video-sdk-button" + }, "enterprise_support": { "title": "Enterprise Support", "newWindow": true, - "href": "https://www.thewidlarzgroup.com/?utm_source=rnv&utm_medium=docs&utm_campaign=navbar&utm_id=enterprise#Contact" + "href": "https://www.thewidlarzgroup.com/?utm_source=rnv&utm_medium=docs#Contact" + }, + "issue_boost": { + "title": "Boost Your Issue", + "newWindow": true, + "href": "https://www.thewidlarzgroup.com/issue-boost/?utm_source=rnv&utm_medium=docs&utm_campaign=sidebar&utm_id=issue-boost-button" + }, + "separator_enterprise": { + "type": "separator", + "title": "" + }, + "updating": "Updating", + "changelog": { + "title": "Changelog", + "newWindow": true, + "href": "https://github.com/TheWidlarzGroup/react-native-video/blob/master/CHANGELOG.md" } } diff --git a/docs/pages/component/ads.md b/docs/pages/component/ads.md index 5b5f1857..0a9cb330 100644 --- a/docs/pages/component/ads.md +++ b/docs/pages/component/ads.md @@ -1,22 +1,26 @@ # Ads ## IMA SDK -`react-native-video` has built-in support for Google IMA SDK for Android and iOS. To enable it please refer to [installation section](/installation) + +`react-native-video` includes built-in support for Google IMA SDK on Android and iOS. To enable it, refer to the [installation section](/installation). ### Usage -To use AVOD, you need to pass `adTagUrl` prop to `Video` component. `adTagUrl` is a VAST uri. -Example: -``` +To use AVOD (Ad-Supported Video on Demand), pass the `adTagUrl` prop to the `Video` component. The `adTagUrl` should be a VAST-compliant URI. + +#### Example: + +```jsx adTagUrl="https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/vmap_ad_samples&sz=640x480&cust_params=sample_ar%3Dpremidpostoptimizedpodbumper&ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&env=vp&impl=s&cmsid=496&vid=short_onecue&correlator=" ``` -> NOTE: Video ads cannot start when you are using the PIP on iOS (more info available at [Google IMA SDK Docs](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/picture_in_picture?hl=en#starting_ads)). If you are using custom controls, you must hide your PIP button when you receive the ```STARTED``` event from ```onReceiveAdEvent``` and show it again when you receive the ```ALL_ADS_COMPLETED``` event. +> **Note:** Video ads cannot start when Picture-in-Picture (PiP) mode is active on iOS. More details are available in the [Google IMA SDK Docs](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/picture_in_picture?hl=en#starting_ads). If you are using custom controls, hide the PiP button when receiving the `STARTED` event from `onReceiveAdEvent` and show it again when receiving the `ALL_ADS_COMPLETED` event. ### Events -To receive events from IMA SDK, you need to pass `onReceiveAdEvent` prop to `Video` component. List of events, you can find [here](https://github.com/TheWidlarzGroup/react-native-video/blob/master/src/types/Ads.ts) -Example: +To receive events from the IMA SDK, pass the `onReceiveAdEvent` prop to the `Video` component. The full list of supported events is available [here](https://github.com/TheWidlarzGroup/react-native-video/blob/master/src/types/Ads.ts). + +#### Example: ```jsx ... @@ -25,11 +29,12 @@ onReceiveAdEvent={event => console.log(event)} ``` ### Localization -To change the language of the IMA SDK, you need to pass `adLanguage` prop to `Video` component. List of supported languages, you can find [here](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/localization#locale-codes) -By default, ios will use system language and android will use `en` +To change the language of the IMA SDK, pass the `adLanguage` prop to the `Video` component. The list of supported languages is available [here](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/localization#locale-codes). -Example: +- By default, **iOS** uses the system language, and **Android** defaults to `en` (English). + +#### Example: ```jsx ... diff --git a/docs/pages/component/drm.mdx b/docs/pages/component/drm.mdx index 22ea1f36..2d7b0fa7 100644 --- a/docs/pages/component/drm.mdx +++ b/docs/pages/component/drm.mdx @@ -4,57 +4,59 @@ import PlatformsList from '../../components/PlatformsList/PlatformsList.tsx'; ## DRM Example -We have available example for DRM usage in the [example app](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/DRMExample.tsx). -To get token needed for DRM playback you can go to [our site](https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=text) and get it. +We provide a sample implementation in the [example app](https://github.com/TheWidlarzGroup/react-native-video/blob/master/examples/bare/src/DRMExample.tsx) demonstrating how to use DRM with `react-native-video`. You’ll need a valid token—visit [our site](https://www.thewidlarzgroup.com/services/free-drm-token-generator-for-video?utm_source=drm&utm_medium=docs) to obtain a **free 24-hour token**. -## Provide DRM data (only tested with http/https assets) +## DRM Offline -You can provide some configuration to allow DRM playback. -This feature will disable the use of `TextureView` on Android. +If you need DRM-protected content available offline, our [Offline Video SDK](https://www.thewidlarzgroup.com/offline-video-sdk/?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=offline-video-sdk-link) enables downloading, storing, and managing streams with and without DRM. It also handles many edge cases you may encounter over time. -DRM object allows this members: +### Prerequisites: +- Use `react-native-video` v6 or v7. If you're still on v5 or lower, [contact us](https://www.thewidlarzgroup.com/?utm_source=rnv&utm_medium=docs&utm_campaign=drm&utm_id=contact#Contact) for assistance. + +> Supporting our software kits helps maintain this open-source project. Thank you! + +## Providing DRM Data (Tested with HTTP/HTTPS Assets) + +You can configure DRM playback by providing a DRM object with the following properties. This feature disables the use of `TextureView` on Android. + +### DRM Properties ### `base64Certificate` -Type: bool\ -Default: false +**Type:** boolean +**Default:** `false` -Whether or not the certificate url returns it on base64. +Indicates whether the certificate URL returns data in Base64 format. ### `certificateUrl` -Type: string\ -Default: undefined +**Type:** string +**Default:** `undefined` -URL to fetch a valid certificate for FairPlay. +The URL used to fetch a valid certificate for FairPlay. ### `getLicense` -Type: function\ -Default: undefined +**Type:** function +**Default:** `undefined` -Rather than setting the `licenseServer` url to get the license, you can manually get the license on the JS part, and send the result to the native part to configure FairplayDRM for the stream +Instead of setting `licenseServer`, you can manually acquire the license in JavaScript and send the result to the native module for FairPlay DRM configuration. -`licenseServer` and `headers` will be ignored. You will obtain as argument the `SPC` -(as ASCII string, you will probably need to convert it to base 64) obtained from -your `contentId` + the provided certificate via `objc [loadingRequest streamingContentKeyRequestDataForApp:certificateData -contentIdentifier:contentIdData options:nil error:&spcError]; ` +The following parameters are available in `getLicense`: +- `contentId`: The content ID from the DRM object or `loadingRequest.request.url?.host` +- `loadedLicenseUrl`: The URL retrieved from `loadingRequest.request.URL.absoluteString`, starting with `skd://` or `clearkey://` +- `licenseServer`: The URL passed in the DRM object +- `spcString`: The SPC used for DRM validation -Also, you will receive following parameter of getLicense: -* `contentId` contentId if passed to `drm` object or loadingRequest.request.url?.host -* `loadedLicenseUrl` URL defined as `loadingRequest.request.URL.absoluteString`, this url starts with `skd://` or `clearkey://` -* `licenseServer` prop if prop is passed to `drm` object. -* `spcString` the SPC used to validate playback with drm server +You should return a Base64-encoded CKC response, either directly or as a `Promise`. -You should return on this method a `CKC` in Base64, either by just returning it or returning a `Promise` that resolves with the `CKC`. - -With this prop you can override the license acquisition flow, as an example: +#### Example: ```js getLicense: (spcString, contentId, licenseUrl, loadedLicenseUrl) => { @@ -64,19 +66,14 @@ getLicense: (spcString, contentId, licenseUrl, loadedLicenseUrl) => { return fetch(`https://license.pallycon.com/ri/licenseManager.do`, { method: 'POST', headers: { - 'pallycon-customdata-v2': - 'd2VpcmRiYXNlNjRzdHJpbmcgOlAgRGFuaWVsIE1hcmnxbyB3YXMgaGVyZQ==', + 'pallycon-customdata-v2': 'your-custom-header', 'Content-Type': 'application/x-www-form-urlencoded', }, body: formData, }) .then((response) => response.text()) - .then((response) => { - return response; - }) - .catch((error) => { - console.error('Error', error); - }); + .then((response) => response) + .catch((error) => console.error('Error', error)); }; ``` @@ -84,123 +81,123 @@ getLicense: (spcString, contentId, licenseUrl, loadedLicenseUrl) => { -Type: string\ -Default: undefined +**Type:** string +**Default:** `undefined` -Specify the content id of the stream, otherwise it will take the host value from `loadingRequest.request.URL.host` (f.e: `skd://testAsset` -> will take `testAsset`) +Sets the content ID for the stream. If not specified, the system uses the host value from `loadingRequest.request.URL.host`. ### `headers` -Type: Object\ -Default: undefined +**Type:** Object +**Default:** `undefined` -You can customize headers send to the licenseServer. +Custom headers for the license server request. -Example: +#### Example: ```js -source={{ - uri: 'https://media.axprod.net/TestVectors/v7-MultiDRM-SingleKey/Manifest_1080p.mpd', -}} -drm={{ - type: DRMType.WIDEVINE, - licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense', - headers: { - 'X-AxDRM-Message': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2ZXJzaW9uIjoxLCJjb21fa2V5X2lkIjoiYjMzNjRlYjUtNTFmNi00YWUzLThjOTgtMzNjZWQ1ZTMxYzc4IiwibWVzc2FnZSI6eyJ0eXBlIjoiZW50aXRsZW1lbnRfbWVzc2FnZSIsImZpcnN0X3BsYXlfZXhwaXJhdGlvbiI6NjAsInBsYXlyZWFkeSI6eyJyZWFsX3RpbWVfZXhwaXJhdGlvbiI6dHJ1ZX0sImtleXMiOlt7ImlkIjoiOWViNDA1MGQtZTQ0Yi00ODAyLTkzMmUtMjdkNzUwODNlMjY2IiwiZW5jcnlwdGVkX2tleSI6ImxLM09qSExZVzI0Y3Iya3RSNzRmbnc9PSJ9XX19.FAbIiPxX8BHi9RwfzD7Yn-wugU19ghrkBFKsaCPrZmU' - }, -}} +drm: { + type: DRMType.WIDEVINE, + licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense', + headers: { + 'X-AxDRM-Message': 'your-drm-header', + }, +} ``` ### `licenseServer` -Type: string\ -Default: false +**Type:** string +**Default:** `undefined` -The URL pointing to the licenseServer that will provide the authorization to play the protected stream. +The license server URL that authorizes protected content playback. ### `multiDrm` - -Type: boolean\ -Default: false -Indicates that drm system shall support key rotation, see: https://developer.android.google.cn/media/media3/exoplayer/drm?hl=en#key-rotation + + +**Type:** boolean +**Default:** `false` + +Indicates whether the DRM system should support key rotation. See [Android Developer Docs](https://developer.android.google.cn/media/media3/exoplayer/drm?hl=en#key-rotation) for more details. ### `type` -Type: DRMType\ -Default: undefined +**Type:** DRMType +**Default:** `undefined` -You can specify the DRM type, either by string or using the exported DRMType enum. -Valid values are, for Android: DRMType.WIDEVINE / DRMType.PLAYREADY / DRMType.CLEARKEY. -for iOS: DRMType.FAIRPLAY +Defines the DRM type: +- **Android:** `DRMType.WIDEVINE`, `DRMType.PLAYREADY`, `DRMType.CLEARKEY` +- **iOS:** `DRMType.FAIRPLAY` ### `localSourceEncryptionKeyScheme` -Set the url scheme for stream encryption key for local assets +**Type:** string -Type: String +Sets the URL scheme for stream encryption keys used in local assets. -Example: +#### Example: -``` +```js localSourceEncryptionKeyScheme="my-offline-key" ``` ## Common Usage Scenarios -### Send cookies to license server +### Sending Cookies to the License Server -You can send Cookies to the license server via `headers` prop. Example: +You can send cookies using the `headers` prop. + +#### Example: ```js drm: { - type: DRMType.WIDEVINE - licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense', - headers: { - 'Cookie': 'PHPSESSID=etcetc; csrftoken=mytoken; _gat=1; foo=bar' - }, + type: DRMType.WIDEVINE, + licenseServer: 'https://drm-widevine-licensing.axtest.net/AcquireLicense', + headers: { + 'Cookie': 'PHPSESSID=your-session-id; csrftoken=mytoken; _gat=1; foo=bar' + }, } ``` -### Custom License Acquisition (only iOS for now) +### Custom License Acquisition (iOS Only) + +#### Example: ```js drm: { - type: DRMType.FAIRPLAY, - getLicense: (spcString) => { - const base64spc = Base64.encode(spcString); - return fetch('YOUR LICENSE SERVER HERE', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Accept: 'application/json', - }, - body: JSON.stringify({ - getFairplayLicense: { - foo: 'bar', - spcMessage: base64spc, - } - }) - }) - .then(response => response.json()) - .then((response) => { - if (response && response.getFairplayLicenseResponse - && response.getFairplayLicenseResponse.ckcResponse) { - return response.getFairplayLicenseResponse.ckcResponse; - } - throw new Error('No correct response'); - }) - .catch((error) => { - console.error('CKC error', error); - }); - } + type: DRMType.FAIRPLAY, + getLicense: (spcString) => { + const base64spc = Base64.encode(spcString); + return fetch('YOUR_LICENSE_SERVER_URL', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + body: JSON.stringify({ + getFairplayLicense: { + foo: 'bar', + spcMessage: base64spc, + } + }) + }) + .then(response => response.json()) + .then((response) => { + if (response?.getFairplayLicenseResponse?.ckcResponse) { + return response.getFairplayLicenseResponse.ckcResponse; + } + throw new Error('No valid response'); + }) + .catch((error) => console.error('CKC error', error)); + } } ``` diff --git a/docs/pages/component/events.mdx b/docs/pages/component/events.mdx index f59d35f2..9eb471b1 100644 --- a/docs/pages/component/events.mdx +++ b/docs/pages/component/events.mdx @@ -2,7 +2,7 @@ import PlatformsList from '../../components/PlatformsList/PlatformsList.tsx'; # Events -This page shows the list of available callbacks to handle player notifications +This page lists all available callbacks for handling player notifications. ## Details @@ -10,233 +10,240 @@ This page shows the list of available callbacks to handle player notifications -Callback function that is called when the audio is about to become 'noisy' due to -a change in audio outputs. Typically this is called when audio output is being switched -from an external source like headphones back to the internal speaker. It's a good -idea to pause the media when this happens so the speaker doesn't start blasting sound. +Triggered when audio output changes (e.g., switching from headphones to speakers). It's recommended to pause the media when this event occurs. -Payload: none +**Payload:** _none_ + +--- ### `onAudioFocusChanged` -Callback function that is called when the audio focus changes. This is called when the audio focus is gained or lost. This is useful for determining if the media should be paused or not. +Called when audio focus is gained or lost. -Payload: -Property | Type | Description ---- | --- | --- -hasAudioFocus | boolean | Boolean indicating whether the media has audio focus - -Example: +**Payload:** +| Property | Type | Description | +|---------------|--------|----------------------------------------------| +| hasAudioFocus | boolean | `true` if media has audio focus, `false` otherwise | +**Example:** ```javascript { - hasAudioFocus: true; + hasAudioFocus: true } ``` +--- + ### `onAudioTracks` -Callback function that is called when audio tracks change +Triggered when available audio tracks change. -Payload: +**Payload:** _Array of objects with track details_ -An **array** of -| Property | Type | Description | -| -------- | ------- | ---------------------------------------------------------------------------------------------------------- | -| index | number | Internal track ID | -| title | string | Descriptive name for the track | -| language | string | 2 letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language | -| bitrate | number | bitrate of track | -| type | string | Mime type of track | -| selected | boolean | true if track is playing | - -Example: +| Property | Type | Description | +|----------|--------|-----------------------------------------------------------------------------| +| index | number | Internal track ID | +| title | string | Descriptive track name | +| language | string | [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code | +| bitrate | number | Track bitrate | +| type | string | Track MIME type | +| selected | boolean | `true` if track is currently playing | +**Example:** ```javascript { audioTracks: [ { language: 'es', title: 'Spanish', type: 'audio/mpeg', index: 0, selected: true }, { language: 'en', title: 'English', type: 'audio/mpeg', index: 1 } - ]; + ] } ``` +--- + ### `onBandwidthUpdate` -Callback function that is called when the available bandwidth changes. +Called when available bandwidth changes. -Payload: - -| Property | Type | Description | -| -------- | ------ | ---------------------------------------------- | -| bitrate | number | The estimated bitrate in bits/sec | -| width | number | The width of the video (android only) | -| height | number | The height of the video (android only) | -| trackId | string | The track ID of the video track (android only) | - -Example on iOS: +**Payload:** +| Property | Type | Description | +|----------|--------|-----------------------------------------------| +| bitrate | number | Estimated bitrate in bits/sec | +| width | number | Video width (Android only) | +| height | number | Video height (Android only) | +| trackId | string | Video track ID (Android only) | +**Example (iOS):** ```javascript { - bitrate: 1000000; + bitrate: 1000000 } ``` -Example on Android: - +**Example (Android):** ```javascript { - bitrate: 1000000; - width: 1920; - height: 1080; - trackId: 'some-track-id'; + bitrate: 1000000, + width: 1920, + height: 1080, + trackId: 'some-track-id' } ``` -Note: On Android, you must set the [reportBandwidth](#reportbandwidth) prop to enable this event. This is due to the high volume of events generated. +> **Note:** On Android, set the [`reportBandwidth`](#reportbandwidth) prop to enable this event. + +--- ### `onBuffer` -Callback function that is called when the player buffers. +Triggered when buffering starts or stops. -Payload: - -| Property | Type | Description | -| ----------- | ------- | ---------------------------------------------- | -| isBuffering | boolean | Boolean indicating whether buffering is active | - -Example: +**Payload:** +| Property | Type | Description | +|------------|--------|---------------------------------| +| isBuffering | boolean | `true` if buffering is active | +**Example:** ```javascript { - isBuffering: true; + isBuffering: true } ``` +--- + ### `onControlsVisibilityChange` -Callback function that is called when the controls are hidden or shown. Not possible on iOS. +Triggered when the video player controls become visible or hidden. -Payload: - -| Property | Type | Description | -| ----------- | ------- | ---------------------------------------------- | -| isVisible | boolean | Boolean indicating whether controls are visible | - -Example: +**Payload:** +| Property | Type | Description | +|----------|--------|-------------------------------------| +| isVisible | boolean | `true` if controls are visible | +**Example:** ```javascript { - isVisible: true; + isVisible: true } ``` +--- + ### `onEnd` -Callback function that is called when the player reaches the end of the media. +Triggered when the media reaches the end. -Payload: none +**Payload:** _none_ + +--- ### `onError` -Callback function that is called when the player experiences a playback error. +Called when a playback error occurs. -Payload: +**Payload:** +| Property | Type | Description | +|---------|--------|---------------------------| +| error | object | Error details | -| Property | Type | Description | -| -------- | ------ | ------------------------------------------------------------- | -| error | object | Object containing properties with information about the error | +--- ### `onExternalPlaybackChange` -Callback function that is called when external playback mode for current playing video has changed. Mostly useful when connecting/disconnecting to Apple TV – it's called on connection/disconnection. +Called when external playback mode changes (e.g., Apple TV connection/disconnection). -Payload: - -| Property | Type | Description | -| ------------------------ | ------- | ----------------------------------------------------------- | -| isExternalPlaybackActive | boolean | Boolean indicating whether external playback mode is active | - -Example: +**Payload:** +| Property | Type | Description | +|-------------------------|--------|--------------------------------------------| +| isExternalPlaybackActive | boolean | `true` if external playback is active | +**Example:** ```javascript { - isExternalPlaybackActive: true; + isExternalPlaybackActive: true } ``` +--- + ### `onFullscreenPlayerWillPresent` -Callback function that is called when the player is about to enter fullscreen mode. +Called before entering fullscreen mode. -Payload: none +**Payload:** _none_ + +--- ### `onFullscreenPlayerDidPresent` -Callback function that is called when the player has entered fullscreen mode. +Called when fullscreen mode is active. -Payload: none +**Payload:** _none_ + +--- ### `onFullscreenPlayerWillDismiss` -Callback function that is called when the player is about to exit fullscreen mode. +Called before exiting fullscreen mode. -Payload: none +**Payload:** _none_ + +--- ### `onFullscreenPlayerDidDismiss` -Callback function that is called when the player has exited fullscreen mode. +Called when fullscreen mode is exited. -Payload: none +**Payload:** _none_ + +--- ### `onLoad` -Callback function that is called when the media is loaded and ready to play. +Triggered when the media is loaded and ready to play. - -NOTE: tracks (`audioTracks`, `textTracks` & `videoTracks`) are not available on the web. - -Payload: +### Payload: | Property | Type | Description | |-------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | currentTime | number | Time in seconds where the media will start | | duration | number | Length of the media in seconds | -| naturalSize | object | Properties:
_ width - Width in pixels that the video was encoded at
_ height - Height in pixels that the video was encoded at
\* orientation - "portrait", "landscape" or "square" | -| audioTracks | array | An array of audio track info objects with the following properties:
_ index - Index number
_ title - Description of the track
_ language - 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or 3 letter [ISO639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) language code
_ type - Mime type of track | -| textTracks | array | An array of text track info objects with the following properties:
_ index - Index number
_ title - Description of the track
_ language - 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or 3 letter [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) language code
_ type - Mime type of track | -| videoTracks | array | An array of video track info objects with the following properties:
_ trackId - ID for the track
_ bitrate - Bit rate in bits per second
_ codecs - Comma separated list of codecs
_ height - Height of the video
\* width - Width of the video | +| naturalSize | object | Properties:
  width - Width in pixels that the video was encoded at
  height - Height in pixels that the video was encoded at
  orientation - "portrait", "landscape" or "square" | +| audioTracks | array | An array of audio track info objects with the following properties:
  index - Index number
  title - Description of the track
  language - 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or 3 letter [ISO639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) language code
  type - Mime type of track | +| textTracks | array | An array of text track info objects with the following properties:
  index - Index number
  title - Description of the track
  language - 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) or 3 letter [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) language code
  type - Mime type of track | +| videoTracks | array | An array of video track info objects with the following properties:
  trackId - ID for the track
  bitrate - Bit rate in bits per second
  codecs - Comma separated list of codecs
  height - Height of the video
  width - Width of the video | | trackId | string | Provide key information about the video track, typically including: `Resolution`, `Bitrate`. | -Example: +**Example:** -```javascript +```js { canPlaySlowForward: true, canPlayReverse: false, @@ -265,49 +272,51 @@ Example: { index: 1, bitrate: 7981888, codecs: "avc1.640028", height: 1080, trackId: "f2-v1-x3", width: 1920 }, { index: 2, bitrate: 1994979, codecs: "avc1.4d401f", height: 480, trackId: "f3-v1-x3", width: 848 } ], - trackId: "720p 2400kbps" + trackId: "720p 2400kbps", } ``` +> **Note:** `audioTracks`, `textTracks`, and `videoTracks` are not available on the web. + +--- + ### `onLoadStart` -Callback function that is called when the media starts loading. +Triggered when media starts loading. -Payload: - -| Property | Type | Description | -| --------- | ----------- | ---------------------------------------------------------------- | -| isNetwork | boolean | Boolean indicating if the media is being loaded from the network | -| type | string | Type of the media. Not available on Windows | -| uri | string | URI for the media source. Not available on Windows | - -Example: +**Payload:** +| Property | Type | Description | +|----------|--------|-------------------------------------| +| isNetwork | boolean | `true` if media is loaded from a network | +| type | string | Media type (not available on Windows) | +| uri | string | Media source URI (not available on Windows) | +**Example:** ```javascript { isNetwork: true, type: '', - uri: 'https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8' + uri: 'https://example.com/video.mp4' } ``` +--- + ### `onPlaybackStateChanged` -Callback function that is called when the playback state changes. +Triggered when playback state changes. -Payload: - -| Property | Type | Description | -| --------- | ----------- | -------------------------------------------------- | -| isPlaying | boolean | Boolean indicating if the media is playing or not | -| isSeeking | boolean | Boolean indicating if the player is seeking or not | - -Example: +**Payload:** +| Property | Type | Description | +|----------|--------|-------------------------------------| +| isPlaying | boolean | `true` if media is playing | +| isSeeking | boolean | `true` if seeking is in progress | +**Example:** ```javascript { isPlaying: true, @@ -315,56 +324,62 @@ Example: } ``` +--- + ### `onPictureInPictureStatusChanged` -Callback function that is called when picture in picture becomes active or inactive. +Triggered when Picture-in-Picture (PiP) mode is activated or deactivated. -| Property | Type | Description | -| -------- | ------- | ------------------------------------------------------- | -| isActive | boolean | Boolean indicating whether picture in picture is active | - -Example: +**Payload:** +| Property | Type | Description | +|----------|--------|----------------------------------| +| isActive | boolean | `true` if PiP mode is active | +**Example:** ```javascript { - isActive: true; + isActive: true } ``` +--- + ### `onPlaybackRateChange` -Callback function that is called when the rate of playback changes - either paused or starts/resumes. +Triggered when playback speed changes. -| Property | Type | Description | -| ------------ | ------ | --------------------------------------------------------------------------------------------------------------- | -| playbackRate | number | 0 when playback is paused, 1 when playing at normal speed. Other values when playback is slowed down or sped up | - -Example: +**Payload:** +| Property | Type | Description | +|-------------|--------|---------------------------------| +| playbackRate | number | `0` (paused), `1` (normal speed), other values indicate speed changes | +**Example:** ```javascript { - playbackRate: 0, // indicates paused + playbackRate: 0 // indicates paused } ``` +--- + ### `onProgress` -Callback function that is called every progressUpdateInterval milliseconds with info about which position the media is currently playing. +Triggered every `progressUpdateInterval` milliseconds, providing information about the current playback position. -| Property | Type | Description | -| ---------------- | ------ | ------------------------------------------------------------------------------------------------- | -| currentTime | number | Current position in seconds | -| playableDuration | number | Position to where the media can be played to using just the buffer in seconds | -| seekableDuration | number | Position to where the media can be seeked to in seconds. Typically, the total length of the media | - -Example: +**Payload:** +| Property | Type | Description | +|----------------|--------|-------------------------------------------------------------------------| +| currentTime | number | Current playback position (seconds) | +| playableDuration | number | Duration that can be played using only the buffer (seconds) | +| seekableDuration | number | Duration that can be seeked to (usually the total length of the media) | +**Example:** ```javascript { currentTime: 5.2, @@ -373,80 +388,82 @@ Example: } ``` +--- + ### `onReadyForDisplay` -Callback function that is called when the first video frame is ready for display. This is when the poster is removed. +Triggered when the first video frame is ready to be displayed. This is when the poster is removed. -Payload: none +**Payload:** _none_ -- iOS: [readyForDisplay](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/1615830-readyfordisplay?language=objc) -- Android [STATE_READY](https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/Player.html#STATE_READY) +- iOS: [`readyForDisplay`](https://developer.apple.com/documentation/avkit/avplayerviewcontroller/1615830-readyfordisplay?language=objc) +- Android: [`STATE_READY`](https://exoplayer.dev/doc/reference/com/google/android/exoplayer2/Player.html#STATE_READY) + +--- ### `onReceiveAdEvent` -Callback function that is called when an AdEvent is received from the IMA's SDK. +Triggered when an AdEvent is received from the IMA SDK. Enum `AdEvent` possible values for [Android](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.AdEvent) and [iOS](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/reference/Enums/IMAAdEventType):
-Events + AdEvent -| Event | Platform | Description | -| -------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `AD_BREAK_ENDED` | iOS | Fired the first time each ad break ends. Applications must reenable seeking when this occurs (only used for dynamic ad insertion). | -| `AD_BREAK_READY` | Android, iOS | Fires when an ad rule or a VMAP ad break would have played if autoPlayAdBreaks is false. | -| `AD_BREAK_STARTED` | iOS | Fired first time each ad break begins playback. If an ad break is watched subsequent times this will not be fired. Applications must disable seeking when this occurs (only used for dynamic ad insertion). | -| `AD_BUFFERING` | Android | Fires when the ad has stalled playback to buffer. | -| `AD_CAN_PLAY` | Android | Fires when the ad is ready to play without buffering, either at the beginning of the ad or after buffering completes. | -| `AD_METADATA` | Android | Fires when an ads list is loaded. | -| `AD_PERIOD_ENDED` | iOS | Fired every time the stream switches from advertising or slate to content. This will be fired even when an ad is played a second time or when seeking into an ad (only used for dynamic ad insertion). | -| `AD_PERIOD_STARTED` | iOS | Fired every time the stream switches from content to advertising or slate. This will be fired even when an ad is played a second time or when seeking into an ad (only used for dynamic ad insertion). | -| `AD_PROGRESS` | Android | Fires when the ad's current time value changes. The event `data` will be populated with an AdProgressData object. | -| `ALL_ADS_COMPLETED` | Android, iOS | Fires when the ads manager is done playing all the valid ads in the ads response, or when the response doesn't return any valid ads. | -| `CLICK` | Android, iOS | Fires when the ad is clicked. | -| `COMPLETED` | Android, iOS | Fires when the ad completes playing. | -| `CONTENT_PAUSE_REQUESTED` | Android | Fires when content should be paused. This usually happens right before an ad is about to cover the content. | -| `CONTENT_RESUME_REQUESTED` | Android | Fires when content should be resumed. This usually happens when an ad finishes or collapses. | -| `CUEPOINTS_CHANGED` | iOS | Cuepoints changed for VOD stream (only used for dynamic ad insertion). | -| `DURATION_CHANGE` | Android | Fires when the ad's duration changes. | -| `ERROR` | Android, iOS | Fires when an error occurred while loading the ad and prevent it from playing. | -| `FIRST_QUARTILE` | Android, iOS | Fires when the ad playhead crosses first quartile. | -| `IMPRESSION` | Android | Fires when the impression URL has been pinged. | -| `INTERACTION` | Android | Fires when an ad triggers the interaction callback. Ad interactions contain an interaction ID string in the ad data. | -| `LINEAR_CHANGED` | Android | Fires when the displayed ad changes from linear to nonlinear, or the reverse. | -| `LOADED` | Android, iOS | Fires when ad data is available. | -| `LOG` | Android, iOS | Fires when a non-fatal error is encountered. The user need not take any action since the SDK will continue with the same or next ad playback depending on the error situation. | -| `MIDPOINT` | Android, iOS | Fires when the ad playhead crosses midpoint. | -| `PAUSED` | Android, iOS | Fires when the ad is paused. | -| `RESUMED` | Android, iOS | Fires when the ad is resumed. | -| `SKIPPABLE_STATE_CHANGED` | Android | Fires when the displayed ads skippable state is changed. | -| `SKIPPED` | Android, iOS | Fires when the ad is skipped by the user. | -| `STARTED` | Android, iOS | Fires when the ad starts playing. | -| `STREAM_LOADED` | iOS | Stream request has loaded (only used for dynamic ad insertion). | -| `TAPPED` | iOS | Fires when the ad is tapped. | -| `THIRD_QUARTILE` | Android, iOS | Fires when the ad playhead crosses third quartile. | -| `UNKNOWN` | iOS | An unknown event has fired | -| `USER_CLOSE` | Android | Fires when the ad is closed by the user. | -| `VIDEO_CLICKED` | Android | Fires when the non-clickthrough portion of a video ad is clicked. | -| `VIDEO_ICON_CLICKED` | Android | Fires when a user clicks a video icon. | -| `VOLUME_CHANGED` | Android | Fires when the ad volume has changed. | -| `VOLUME_MUTED` | Android | Fires when the ad volume has been muted. | + | Event | Platform | Description | + | -------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | `AD_BREAK_ENDED` | iOS | Fired the first time each ad break ends. Applications must reenable seeking when this occurs (only used for dynamic ad insertion). | + | `AD_BREAK_READY` | Android, iOS | Fires when an ad rule or a VMAP ad break would have played if autoPlayAdBreaks is false. | + | `AD_BREAK_STARTED` | iOS | Fired first time each ad break begins playback. If an ad break is watched subsequent times this will not be fired. Applications must disable seeking when this occurs (only used for dynamic ad insertion). | + | `AD_BUFFERING` | Android | Fires when the ad has stalled playback to buffer. | + | `AD_CAN_PLAY` | Android | Fires when the ad is ready to play without buffering, either at the beginning of the ad or after buffering completes. | + | `AD_METADATA` | Android | Fires when an ads list is loaded. | + | `AD_PERIOD_ENDED` | iOS | Fired every time the stream switches from advertising or slate to content. This will be fired even when an ad is played a second time or when seeking into an ad (only used for dynamic ad insertion). | + | `AD_PERIOD_STARTED` | iOS | Fired every time the stream switches from content to advertising or slate. This will be fired even when an ad is played a second time or when seeking into an ad (only used for dynamic ad insertion). | + | `AD_PROGRESS` | Android | Fires when the ad's current time value changes. The event `data` will be populated with an AdProgressData object. | + | `ALL_ADS_COMPLETED` | Android, iOS | Fires when the ads manager is done playing all the valid ads in the ads response, or when the response doesn't return any valid ads. | + | `CLICK` | Android, iOS | Fires when the ad is clicked. | + | `COMPLETED` | Android, iOS | Fires when the ad completes playing. | + | `CONTENT_PAUSE_REQUESTED` | Android | Fires when content should be paused. This usually happens right before an ad is about to cover the content. | + | `CONTENT_RESUME_REQUESTED` | Android | Fires when content should be resumed. This usually happens when an ad finishes or collapses. | + | `CUEPOINTS_CHANGED` | iOS | Cuepoints changed for VOD stream (only used for dynamic ad insertion). | + | `DURATION_CHANGE` | Android | Fires when the ad's duration changes. | + | `ERROR` | Android, iOS | Fires when an error occurred while loading the ad and prevent it from playing. | + | `FIRST_QUARTILE` | Android, iOS | Fires when the ad playhead crosses first quartile. | + | `IMPRESSION` | Android | Fires when the impression URL has been pinged. | + | `INTERACTION` | Android | Fires when an ad triggers the interaction callback. Ad interactions contain an interaction ID string in the ad data. | + | `LINEAR_CHANGED` | Android | Fires when the displayed ad changes from linear to nonlinear, or the reverse. | + | `LOADED` | Android, iOS | Fires when ad data is available. | + | `LOG` | Android, iOS | Fires when a non-fatal error is encountered. The user need not take any action since the SDK will continue with the same or next ad playback depending on the error situation. | + | `MIDPOINT` | Android, iOS | Fires when the ad playhead crosses midpoint. | + | `PAUSED` | Android, iOS | Fires when the ad is paused. | + | `RESUMED` | Android, iOS | Fires when the ad is resumed. | + | `SKIPPABLE_STATE_CHANGED` | Android | Fires when the displayed ads skippable state is changed. | + | `SKIPPED` | Android, iOS | Fires when the ad is skipped by the user. | + | `STARTED` | Android, iOS | Fires when the ad starts playing. | + | `STREAM_LOADED` | iOS | Stream request has loaded (only used for dynamic ad insertion). | + | `TAPPED` | iOS | Fires when the ad is tapped. | + | `THIRD_QUARTILE` | Android, iOS | Fires when the ad playhead crosses third quartile. | + | `UNKNOWN` | iOS | An unknown event has fired | + | `USER_CLOSE` | Android | Fires when the ad is closed by the user. | + | `VIDEO_CLICKED` | Android | Fires when the non-clickthrough portion of a video ad is clicked. | + | `VIDEO_ICON_CLICKED` | Android | Fires when a user clicks a video icon. | + | `VOLUME_CHANGED` | Android | Fires when the ad volume has changed. | + | `VOLUME_MUTED` | Android | Fires when the ad volume has been muted. |
-Payload: - +**Payload:** | Property | Type | Description | -| -------- | ----------------------------------------- | --------------------- | +|----------|-----------------------------------------|---------------------| | event | AdEvent | The ad event received | -| data | Record<string, string> \| undefined | The ad event data | - -Example: +| data | Record<string, string> \| undefined | Additional ad event data | +**Example:** ```json { "data": { @@ -456,173 +473,172 @@ Example: } ``` +--- + ### `onRestoreUserInterfaceForPictureInPictureStop` -Callback function that corresponds to Apple's [`restoreUserInterfaceForPictureInPictureStopWithCompletionHandler`](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). Call `restoreUserInterfaceForPictureInPictureStopCompleted` inside of this function when done restoring the user interface. +Corresponds to Apple's [`restoreUserInterfaceForPictureInPictureStopWithCompletionHandler`](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). +Call `restoreUserInterfaceForPictureInPictureStopCompleted` inside this function when the UI is restored. -Payload: none +**Payload:** _none_ + +--- ### `onSeek` -Callback function that is called when a seek completes. - -Payload: +Triggered when a seek operation completes. +**Payload:** | Property | Type | Description | -| ----------- | ------ | ------------------------------- | -| currentTime | number | The current time after the seek | -| seekTime | number | The requested time | - -Example: +|------------|--------|---------------------------------| +| currentTime | number | Current time after seeking | +| seekTime | number | Requested seek time | +**Example:** ```javascript { - currentTime: 100.5; - seekTime: 100; + currentTime: 100.5, + seekTime: 100 } ``` -Both the currentTime & seekTime are reported because the video player may not seek to the exact requested position in order to improve seek performance. +> **Note:** On iOS, this callback is not reported when native controls are enabled. -Note: on iOS, when controls are enable, this callback is not reported. This is a known limitation. +--- ### `onTimedMetadata` -Callback function that is called when timed metadata becomes available - -Payload: +Triggered when timed metadata is available. +**Payload:** | Property | Type | Description | -| -------- | ----- | ------------------------- | +|----------|------|--------------------------| | metadata | array | Array of metadata objects | -Example: - +**Example:** ```javascript { metadata: [ - {value: 'Streaming Encoder', identifier: 'TRSN'}, - {value: 'Internet Stream', identifier: 'TRSO'}, - {value: 'Any Time You Like', identifier: 'TIT2'}, - ]; + { value: 'Streaming Encoder', identifier: 'TRSN' }, + { value: 'Internet Stream', identifier: 'TRSO' }, + { value: 'Any Time You Like', identifier: 'TIT2' } + ] } ``` +--- + ### `onTextTrackDataChanged` -Callback function that is called when new subtitle data is available. It provides the actual subtitle content for the current selected text track, if available (mainly WebVTT). +Triggered when new subtitle data becomes available. -Payload: - -| Property | Type | Description | -| ---------------- | -------- | -------------------------------------------------- | -| `subtitleTracks` | `string` | The subtitles text content in a compatible format. | - -Example: +**Payload:** +| Property | Type | Description | +|----------------|--------|--------------------------------------------------| +| subtitleTracks | string | The subtitle text content in a compatible format | +**Example:** ```javascript { - subtitleTracks: "This blade has a dark past.", + subtitleTracks: "This blade has a dark past." } ``` -For details on how to control the visibility of subtitles, see the [subtitleStyle](./props.mdx#subtitleStyle) section. +--- ### `onTextTracks` -Callback function that is called when text tracks change +Triggered when available text (subtitle) tracks change. -Payload: - -| Property | Type | Description | -| -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| index | number | Internal track ID | -| title | string | Descriptive name for the track | -| language | string | 2 letter [ISO 639-1 code](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) representing the language | -| type | string | Mime type of the track
_ TextTrackType.SRT - SubRip (.srt)
_ TextTrackType.TTML - TTML (.ttml)
\* TextTrackType.VTT - WebVTT (.vtt)
iOS only supports VTT, Android supports all 3 | -| selected | boolean | true if track is playing | - -Example: +**Payload:** +| Property | Type | Description | +|----------|--------|--------------------------------------------------------------------------------------------------------------| +| index | number | Internal track ID | +| title | string | Track name | +| language | string | 2 letter [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) language code | +| type | string | Track MIME type (_VTT_, _SRT_, _TTML_) | +| selected | boolean | `true` if the track is currently playing | +**Example:** ```javascript { textTracks: [ { index: 0, - title: 'Any Time You Like', - type: 'srt', - selected: true, - }, - ]; + title: 'English Subtitles', + type: 'vtt', + selected: true + } + ] } ``` +--- + ### `onVideoTracks` -Callback function that is called when video tracks change +Triggered when video tracks change. -Payload: - -| Property | Type | Description | -| -------- | ------- | --------------------------------------------------------------- | -| index | number | index of the track | -| trackId | string | Internal track ID | -| codecs | string | MimeType of codec used for this track | -| width | number | Track width | -| height | number | Track height | -| bitrate | number | Bitrate in bps | -| selected | boolean | true if track is selected for playing | -| rotation | number | 0, 90, 180 or 270 rotation to apply to the track (android only) | - -Example: +**Payload:** +| Property | Type | Description | +|----------|---------|-----------------------------------| +| index | number | Track index | +| trackId | string | Internal track ID | +| codecs | string | Codec type | +| width | number | Video width | +| height | number | Video height | +| bitrate | number | Track bitrate (bps) | +| selected | boolean | `true` if the track is playing | +| rotation | number | Rotation angle (0, 90, 180, 270) | +**Example:** ```javascript { videoTracks: [ { - index: O, - trackId: "0", - codecs: 'video/mp4', + index: 0, + trackId: "1", + codecs: "video/mp4", width: 1920, height: 1080, - bitrate: 10000, + bitrate: 5000000, selected: true, - rotation: 0, - }, - ]; + rotation: 0 + } + ] } ``` +--- + ### `onVolumeChange` -Callback function that is called when the volume of player changes. +Triggered when the player volume changes. -> Note: This event applies to the volume of the player, not the volume of the device. +> **Note:** This event applies to the player's volume, not the device's system volume. -Payload: - -| Property | Type | Description | -| -------- | ------ | ------------------------------------------ | -| volume | number | The volume of the player (between 0 and 1) | - -Example: +**Payload:** +| Property | Type | Description | +|----------|--------|---------------------------------| +| volume | number | Volume level (0 to 1) | +**Example:** ```javascript { - volume: 0.5; + volume: 0.5 } ``` diff --git a/docs/pages/component/methods.mdx b/docs/pages/component/methods.mdx index 223fbd2f..b648448f 100644 --- a/docs/pages/component/methods.mdx +++ b/docs/pages/component/methods.mdx @@ -2,284 +2,336 @@ import PlatformsList from '../../components/PlatformsList/PlatformsList.tsx'; # Methods -This page shows the list of available methods +This page shows the list of available methods. + +## Details ### `dismissFullscreenPlayer` -`dismissFullscreenPlayer(): Promise` +```tsx +dismissFullscreenPlayer(): Promise +``` -Take the player out of fullscreen mode. +Exits fullscreen mode. -> [!WARNING] -> deprecated, use setFullScreen method instead +> **Deprecated:** Use `setFullScreen(false)` instead. + +--- ### `pause` -`pause(): Promise` +```tsx +pause(): Promise +``` -Pause the video. +Pauses the video. + +--- ### `presentFullscreenPlayer` -`presentFullscreenPlayer(): Promise` +```tsx +presentFullscreenPlayer(): Promise +``` -Put the player in fullscreen mode. +Enters fullscreen mode. -On iOS, this displays the video in a fullscreen view controller with controls. +- On **iOS**, this opens a fullscreen view controller with controls. +- On **Android**, this makes the player fullscreen but requires styling to match screen dimensions. -On Android, this puts the navigation controls in fullscreen mode. It is not a complete fullscreen implementation, so you will still need to apply a style that makes the width and height match your screen dimensions to get a fullscreen video. +> **Deprecated:** Use `setFullScreen(true)` instead. -> [!WARNING] -> deprecated, use setFullScreen method instead +--- ### `resume` -`resume(): Promise` +```tsx +resume(): Promise +``` -Resume the video. +Resumes video playback. + +--- ### `restoreUserInterfaceForPictureInPictureStopCompleted` -`restoreUserInterfaceForPictureInPictureStopCompleted(restored)` +```tsx +restoreUserInterfaceForPictureInPictureStopCompleted(restored) +``` -This function corresponds to the completion handler in Apple's [restoreUserInterfaceForPictureInPictureStop](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). IMPORTANT: This function must be called after `onRestoreUserInterfaceForPictureInPictureStop` is called. +Must be called after `onRestoreUserInterfaceForPictureInPictureStop`. +Corresponds to Apple's [`restoreUserInterfaceForPictureInPictureStop`](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). + +--- ### `save` -`save(): Promise<{ uri: string }>` +```tsx +save(): Promise<{ uri: string }> +``` -Save video to your Photos with current filter prop. Returns promise. +Saves the video to the user's **Photos app** with the current filter. -Notes: +#### Notes: +- Supports **MP4** export only. +- Exports to the **cache directory** with a generated UUID filename. +- Requires **internet connection** if the video is not already buffered. +- Video remains in the **Photos app** until manually deleted. +- Works with **cached videos**. -- Currently only supports highest quality export -- Currently only supports MP4 export -- Currently only supports exporting to user's cache directory with a generated UUID filename. -- User will need to remove the saved video through their Photos app -- Works with cached videos as well. (Checkout video-caching example) -- If the video is has not began buffering (e.g. there is no internet connection) then the save function will throw an error. -- If the video is buffering then the save function promise will return after the video has finished buffering and processing. +#### Future improvements: +- Support for **multiple quality options**. +- Support for **more formats**. +- Support for **custom directory and filename**. -Future: - -- Will support multiple qualities through options -- Will support more formats in the future through options -- Will support custom directory and file name through options +--- ### `enterPictureInPicture` -`enterPictureInPicture()` - -To use this feature on Android with Expo, you must set 'enableAndroidPictureInPicture' true within expo plugin config (app.json) - -```json - "plugins": [ - [ - "react-native-video", - { - "enableAndroidPictureInPicture": true, - } - ] - ] +```tsx +enterPictureInPicture() ``` -To use this feature on Android with Bare React Native, you must: +Activates Picture-in-Picture (PiP) mode. -- [Declare PiP support](https://developer.android.com/develop/ui/views/picture-in-picture#declaring) in your AndroidManifest.xml -- setting `android:supportsPictureInPicture` to `true` +#### Android setup: +For **Expo**, enable PiP in `app.json`: + +```json +"plugins": [ + [ + "react-native-video", + { + "enableAndroidPictureInPicture": true + } + ] +] +``` + +For **Bare React Native**, update `AndroidManifest.xml`: ```xml + ``` -NOTE: Foreground picture in picture is not supported on Android due to limitations of react native (Single Activity App). So, If you call `enterPictureInPicture`, application will switch to background on Android. -NOTE: Video ads cannot start when you are using the PIP on iOS (more info available at [Google IMA SDK Docs](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/picture_in_picture?hl=en#starting_ads)). If you are using custom controls, you must hide your PIP button when you receive the `STARTED` event from `onReceiveAdEvent` and show it again when you receive the `ALL_ADS_COMPLETED` event. +> **Note:** +> - On **Android**, entering PiP moves the app to the **background**. +> - On **iOS**, **video ads cannot start** in PiP mode ([Google IMA SDK](https://developers.google.com/interactive-media-ads/docs/sdks/ios/client-side/picture_in_picture?hl=en#starting_ads)). + +--- ### `exitPictureInPicture` -`exitPictureInPicture()` +```tsx +exitPictureInPicture() +``` -Exits the active picture in picture; if it is not active, the function call is ignored. +Exits Picture-in-Picture (PiP) mode. -### `restoreUserInterfaceForPictureInPictureStopCompleted` - - - -`restoreUserInterfaceForPictureInPictureStopCompleted(restored)` - -This function corresponds to the completion handler in Apple's [restoreUserInterfaceForPictureInPictureStop](https://developer.apple.com/documentation/avkit/avpictureinpicturecontrollerdelegate/1614703-pictureinpicturecontroller?language=objc). IMPORTANT: This function must be called after `onRestoreUserInterfaceForPictureInPictureStop` is called. +--- ### `seek` -`seek(seconds)` +```tsx +seek(seconds: number) +``` -Seek to the specified position represented by seconds. seconds is a float value. +Seeks to the specified position (**in seconds**). -`seek()` can only be called after the `onLoad` event has fired. Once completed, the [onSeek](./events#onseek) event will be called. +#### Notes: +- **Must be called after** `onLoad`. +- Triggers the [`onSeek`](./events#onseek) event. -#### Exact seek +#### **iOS Exact Seek:** +```tsx +seek(seconds, tolerance: number) +``` +- Default **tolerance**: ±100ms. +- Set `tolerance = 0` for **precise seeking**. - - -By default iOS seeks within 100 milliseconds of the target position. If you need more accuracy, you can use the seek with tolerance method: - -`seek(seconds, tolerance)` - -tolerance is the max distance in milliseconds from the seconds position that's allowed. Using a more exact tolerance can cause seeks to take longer. If you want to seek exactly, set tolerance to 0. +--- ### `setVolume` -`setVolume(value): Promise` +```tsx +setVolume(value: number): Promise +``` -This function will change the volume exactly like [volume](./props#volume) property. default value and range are the same then. +Changes the **volume** level. Same behavior as the [`volume`](./props#volume) prop. + +--- ### `getCurrentPosition` -`getCurrentPosition(): Promise` +```tsx +getCurrentPosition(): Promise +``` -This function retrieves and returns the precise current position of the video playback, measured in seconds. -This function will throw an error if player is not initialized. +Returns the **current playback position** in seconds. +> **Throws an error** if the player is not initialized. + +--- ### `setSource` -`setSource(source: ReactVideoSource): Promise` +```tsx +setSource(source: ReactVideoSource): Promise +``` -This function will change the source exactly like [source](./props#source) property. -Changing source with this function will overide source provided as props. +Updates the media source **dynamically**. + +> **Note:** This **overrides** the `source` prop. + +--- ### `setFullScreen` -`setFullScreen(fullscreen): Promise` +```tsx +setFullScreen(fullscreen: boolean): Promise +``` -If you set it to `true`, the player enters fullscreen mode. If you set it to `false`, the player exits fullscreen mode. +Toggles fullscreen mode. -On iOS, this displays the video in a fullscreen view controller with controls. +- `true` → Enters fullscreen. +- `false` → Exits fullscreen. -On Android, this puts the navigation controls in fullscreen mode. It is not a complete fullscreen implementation, so you will still need to apply a style that makes the width and height match your screen dimensions to get a fullscreen video. +--- ### `nativeHtmlVideoRef` -A ref to the underlying html video element. This can be used if you need to integrate a 3d party, web only video library (like hls.js, shaka, video.js...). +A **reference to the native HTML `