---
description: Unofficial Capacitor plugin to embed and control YouTube players on Android, iOS, and Web with inline playback, typed events, and playback controls.
title: Capacitor YouTube Player Plugin for Android, iOS & Web - Capawesome
image: https://capawesome.io/docs/assets/images/social/sdks/capacitor/youtube-player.png
---

<!doctype html> 

[Skip to content ](#capacitor-youtube-player-plugin) 

[📲 Introducing **Build Sharing** — get your builds onto testers' devices with a link & QR code. No account required. ](/blog/share-mobile-app-builds-with-testers/) 

* [ SDKs ](/docs/sdks/)
* [ Formbricks ](/docs/sdks/capacitor/formbricks/)
* [ Geocoder ](/docs/sdks/capacitor/geocoder/)
* [ Google Sign-In ](/docs/sdks/capacitor/google-sign-in/)
* [ Grafana Faro ](/docs/sdks/capacitor/grafana-faro/)
* [ Gyroscope ](/docs/sdks/capacitor/gyroscope/)
* [ Haptics ](/docs/sdks/capacitor/haptics/)
* [ Home Indicator ](/docs/sdks/capacitor/home-indicator/)
* [ In-App Browser ](/docs/sdks/capacitor/in-app-browser/)
* [ Install Referrer ](/docs/sdks/capacitor/install-referrer/)
* [ Intercom ](/docs/sdks/capacitor/intercom/)
* [ Intune ](/docs/sdks/capacitor/intune/)
* [ Keep Awake ](/docs/sdks/capacitor/keep-awake/)
* [ libSQL ](/docs/sdks/capacitor/libsql/)
* [ Light Sensor ](/docs/sdks/capacitor/light-sensor/)
* [ Live Update ](/docs/sdks/capacitor/live-update/)
* [ Localization ](/docs/sdks/capacitor/localization/)
* [ Mail Composer ](/docs/sdks/capacitor/mail-composer/)
* [ Managed Configurations ](/docs/sdks/capacitor/managed-configurations/)
* [ Maps Launcher ](/docs/sdks/capacitor/maps-launcher/)
* [ Media Session ](/docs/sdks/capacitor/media-session/)
* [ ML Kit ](/docs/sdks/capacitor/mlkit/)
* [ Navigation Bar ](/docs/sdks/capacitor/navigation-bar/)
* [ Network ](/docs/sdks/capacitor/network/)
* [ NFC ](/docs/sdks/capacitor/nfc/)
* [ Node.js ](/docs/sdks/capacitor/nodejs/)
* [ OAuth ](/docs/sdks/capacitor/oauth/)
* [ Passkeys ](/docs/sdks/capacitor/passkeys/)
* [ Password Autofill ](/docs/sdks/capacitor/password-autofill/)
* [ PDF Generator ](/docs/sdks/capacitor/pdf-generator/)
* [ PDF Viewer ](/docs/sdks/capacitor/pdf-viewer/)
* [ Pedometer ](/docs/sdks/capacitor/pedometer/)
* [ Permissions ](/docs/sdks/capacitor/permissions/)
* [ Phone Dialer ](/docs/sdks/capacitor/phone-dialer/)
* [ Photo Editor ](/docs/sdks/capacitor/photo-editor/)
* [ Photo Manipulator ](/docs/sdks/capacitor/photo-manipulator/)
* [ PixLive ](/docs/sdks/capacitor/pixlive/)
* [ PostHog ](/docs/sdks/capacitor/posthog/)
* [ Printer ](/docs/sdks/capacitor/printer/)
* [ Privacy Screen ](/docs/sdks/capacitor/privacy-screen/)
* [ Proximity Sensor ](/docs/sdks/capacitor/proximity-sensor/)
* [ Purchases ](/docs/sdks/capacitor/purchases/)
* [ RealtimeKit ](/docs/sdks/capacitor/realtimekit/)
* [ Root Detection ](/docs/sdks/capacitor/root-detection/)
* [ Screen Brightness ](/docs/sdks/capacitor/screen-brightness/)
* [ Screen Orientation ](/docs/sdks/capacitor/screen-orientation/)
* [ Screen Reader ](/docs/sdks/capacitor/screen-reader/)
* [ Screenshot ](/docs/sdks/capacitor/screenshot/)
* [ Secure Preferences ](/docs/sdks/capacitor/secure-preferences/)
* [ Settings Launcher ](/docs/sdks/capacitor/settings-launcher/)
* [ Shake ](/docs/sdks/capacitor/shake/)
* [ Silent Mode ](/docs/sdks/capacitor/silent-mode/)
* [ SIM ](/docs/sdks/capacitor/sim/)
* [ SMS Composer ](/docs/sdks/capacitor/sms-composer/)
* [ Speech Recognition ](/docs/sdks/capacitor/speech-recognition/)
* [ Speech Synthesis ](/docs/sdks/capacitor/speech-synthesis/)
* [ Share Target ](/docs/sdks/capacitor/share-target/)
* [ Square Mobile Payments ](/docs/sdks/capacitor/square-mobile-payments/)
* [ SQLite ](/docs/sdks/capacitor/sqlite/)
* [ Superwall ](/docs/sdks/capacitor/superwall/)
* [ System WebView ](/docs/sdks/capacitor/system-webview/)
* [ Text Interaction ](/docs/sdks/capacitor/text-interaction/)
* [ Text Zoom ](/docs/sdks/capacitor/text-zoom/)
* [ Thermal State ](/docs/sdks/capacitor/thermal-state/)
* [ Toast ](/docs/sdks/capacitor/toast/)
* [ Torch ](/docs/sdks/capacitor/torch/)
* [ Vault ](/docs/sdks/capacitor/vault/)
* [ Volume ](/docs/sdks/capacitor/volume/)
* [ Wallet ](/docs/sdks/capacitor/wallet/)
* [ Wifi ](/docs/sdks/capacitor/wifi/)
* YouTube Player [ YouTube Player ](/docs/sdks/capacitor/youtube-player/)
* [ iOS ](#ios)
* [ Web ](#web)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Type Aliases ](#type-aliases)
* [ Frame Synchronization ](#frame-synchronization)
* [ YouTube Terms of Service ](#youtube-terms-of-service)
* [ Platform Support ](#platform-support)
* [ FAQ ](#faq)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ License ](#license)
* [ Zip ](/docs/sdks/capacitor/zip/)
* [ Cordova ](/docs/sdks/cordova/)
* [ Cloud ](/docs/cloud/)
* [ Integrations ](/docs/cloud/live-updates/integrations/)
* Concepts
* Reference
* [ Troubleshooting ](/docs/cloud/live-updates/troubleshooting/)
* [ FAQ ](/docs/cloud/live-updates/faq/)
* [ Native Builds ](/docs/cloud/native-builds/)
* [ Set Up Environments ](/docs/cloud/native-builds/environments/)
* [ Overwrite Native Configurations ](/docs/cloud/native-builds/native-configurations/)
* [ Auto-Increment Build Numbers ](/docs/cloud/native-builds/auto-incrementing-build-numbers/)
* [ Configure the Web Build Script ](/docs/cloud/native-builds/web-build-script/)
* [ Build from a Monorepo ](/docs/cloud/native-builds/monorepo/)
* [ Use pnpm, Yarn, or bun ](/docs/cloud/native-builds/package-managers/)
* [ Install Private npm Packages ](/docs/cloud/native-builds/npm-private-registry/)
* [ Override the Java Version ](/docs/cloud/native-builds/override-java-version/)
* [ Custom iOS Provisioning Profiles ](/docs/cloud/native-builds/custom-ios-provisioning-profiles/)
* [ Build without Git ](/docs/cloud/native-builds/build-without-git/)
* [ Access Git Behind a Firewall ](/docs/cloud/native-builds/firewall-access/)
* [ Integrations ](/docs/cloud/native-builds/integrations/)
* Reference
* [ Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [ FAQ ](/docs/cloud/native-builds/faq/)
* [ App Store Publishing ](/docs/cloud/app-store-publishing/)
* [ Submit a Build ](/docs/cloud/app-store-publishing/submit-a-build/)
* [ Submit Automatically After a Build ](/docs/cloud/app-store-publishing/submit-automatically/)
* [ Troubleshooting ](/docs/cloud/app-store-publishing/troubleshooting/)
* [ FAQ ](/docs/cloud/app-store-publishing/faq/)
* [ Automations ](/docs/cloud/automations/)
* [ Reference ](/docs/cloud/automations/reference/)
* [ Troubleshooting ](/docs/cloud/automations/troubleshooting/)
* [ FAQ ](/docs/cloud/automations/faq/)
* [ Assist ](/docs/cloud/assist/)
* [ CLI ](/docs/cloud/cli/)
* APIs and SDKs
* [ Webhooks ](/docs/cloud/webhooks/)
* [ Integrations ](/docs/cloud/integrations/)
* Account
* [ Organization ](/docs/cloud/organizations/)
* [ Two-Factor Enforcement ](/docs/cloud/organizations/two-factor-authentication/)
* [ Audit Logs ](/docs/cloud/organizations/audit-logs/)
* [ Billing ](/docs/cloud/organizations/billing/)
* [ License Keys ](/docs/cloud/license-keys/)
* [ AI ](/docs/ai/)
* [ Insiders ](/docs/insiders/)
* [ Billing & Plans ](/docs/insiders/billing-and-plans/)
* [ FAQ ](/docs/insiders/faq/)
* [ License ](https://capawesome.io/legal/eula/)
* [ Support ](/docs/support/)
* [ Contributing ](/docs/contributing/)
* Contributing code
* [ Code of Conduct ](/docs/contributing/code-of-conduct/)
* [ Questions ](https://docs.github.com/en/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion#creating-a-discussion)
* [ Blog ](/blog/)
* Categories

* [ iOS ](#ios)
* [ Web ](#web)
* [ Configuration ](#configuration)
* [ Usage ](#usage)
* [ API ](#api)
* [ Type Aliases ](#type-aliases)
* [ Frame Synchronization ](#frame-synchronization)
* [ YouTube Terms of Service ](#youtube-terms-of-service)
* [ Platform Support ](#platform-support)
* [ FAQ ](#faq)
* [ Newsletter ](#newsletter)
* [ Changelog ](#changelog)
* [ License ](#license)

# Capacitor YouTube Player Plugin[¶](#capacitor-youtube-player-plugin "Permanent link")

Unofficial Capacitor plugin to embed and control [YouTube](https://www.youtube.com/) players on Android, iOS, and Web.[1](#fn:1)

[ ![Deliver Live Updates to your Capacitor app with Capawesome Cloud](../../../assets/external/cloud.capawesome.io/assets/banners/cloud-build-and-deploy-capacitor-apps.69628c3f.png) ](https://cloud.capawesome.io/) 

## Features[¶](#features "Permanent link")

The Capacitor YouTube Player plugin embeds YouTube videos as inline, frame-positioned players in your Capacitor app. Here are some of the key features:

* 🖥️ **Cross-platform**: Supports Android, iOS, and Web.
* 🎞️ **Inline Playback**: Embed players inline on all platforms, including iOS.
* 🧩 **Multi-Instance**: Create and control multiple players at the same time by ID.
* 📐 **Frame Positioning**: Position and resize players with CSS pixel frames and keep them in sync with your layout.
* 🎛️ **Playback Controls**: Load, cue, play, pause, seek, mute, volume, and playback rate.
* 📡 **Typed Events**: Listen for ready, state, time, rate, error, and fullscreen events with typed listeners.
* 📜 **Terms Compliant**: Built on the official YouTube IFrame Player API with TOS-compliant plumbing (see [YouTube Terms of Service](#youtube-terms-of-service)).
* 📦 **CocoaPods & SPM**: Supports CocoaPods and Swift Package Manager for iOS.
* 🔁 **Up-to-date**: Always supports the latest Capacitor version.

Missing a feature? Just [open an issue](https://github.com/capawesome-team/capacitor-plugins/issues) and we'll take a look!

## Use Cases[¶](#use-cases "Permanent link")

The YouTube Player plugin is typically used wherever you want to embed YouTube videos in your app, for example:

* **Media apps**: Embed trailers, music videos, or episodes inline in your content.
* **Onboarding & help**: Show tutorial and how-to videos directly in your app.
* **News & blogs**: Render YouTube embeds in articles with native playback performance.
* **Education**: Build course screens with multiple video lessons on one page.

## Compatibility[¶](#compatibility "Permanent link")

| Plugin Version | Capacitor Version | Status         |
| -------------- | ----------------- | -------------- |
| 0.x.x          | \>=8.x.x          | Active support |

## Installation[¶](#installation "Permanent link")

You can use our **AI-Assisted Setup** to install the plugin. Add the [Capawesome Skills](https://github.com/capawesome-team/skills) to your AI tool using the following command:

`[](#%5F%5Fcodelineno-0-1)npx skills add capawesome-team/skills --skill capacitor-plugins
`

Then use the following prompt:

`` [](#%5F%5Fcodelineno-1-1)Use the `capacitor-plugins` skill from `capawesome-team/skills` to install the `@capawesome/capacitor-youtube-player` plugin in my project.
 ``

If you prefer **Manual Setup**, install the plugin by running the following commands and follow the platform-specific instructions below:

`[](#%5F%5Fcodelineno-2-1)npm install @capawesome/capacitor-youtube-player
[](#%5F%5Fcodelineno-2-2)npx cap sync
`

### Android[¶](#android "Permanent link")

On Android, the plugin uses the [android-youtube-player](https://github.com/PierfrancescoSoffritti/android-youtube-player) library, an open-source wrapper around the official YouTube IFrame Player API.

#### Variables[¶](#variables "Permanent link")

This plugin will use the following project variables (defined in your app's `variables.gradle` file):

* `$androidYoutubePlayerVersion` version of `com.pierfrancescosoffritti.androidyoutubeplayer:core` (default: `13.0.0`)

#### Permissions[¶](#permissions "Permanent link")

The plugin automatically adds the `android.permission.ACCESS_NETWORK_STATE` permission to your app's manifest. It is used to recover the player when the network connection is lost and restored. No action is required on your part.

### iOS[¶](#ios "Permanent link")

On iOS, the plugin uses the [YoutubePlayerView](https://github.com/mukeshydv/YoutubePlayerView) library, an open-source wrapper around the official YouTube IFrame Player API. It can be integrated via Swift Package Manager or CocoaPods. No additional configuration is required.

### Web[¶](#web "Permanent link")

The web implementation loads the [YouTube IFrame Player API](https://developers.google.com/youtube/iframe%5Fapi%5Freference) from YouTube at runtime. This requires an active network connection. If your app enforces a [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP), make sure to allow the YouTube domains (e.g. `https://www.youtube.com` for `script-src` and `frame-src`).

## Configuration[¶](#configuration "Permanent link")

No configuration required for this plugin.

## Usage[¶](#usage "Permanent link")

The following examples show how to use the plugin.

### Create a player[¶](#create-a-player "Permanent link")

Measure a placeholder element in your layout and create a player at its position:

`[](#%5F%5Fcodelineno-3-1)import { YoutubePlayer } from '@capawesome/capacitor-youtube-player';
[](#%5F%5Fcodelineno-3-2)
[](#%5F%5Fcodelineno-3-3)const createPlayer = async () => {
[](#%5F%5Fcodelineno-3-4)  const rect = document
[](#%5F%5Fcodelineno-3-5)    .querySelector('#player-placeholder')
[](#%5F%5Fcodelineno-3-6)    .getBoundingClientRect();
[](#%5F%5Fcodelineno-3-7)  await YoutubePlayer.createPlayer({
[](#%5F%5Fcodelineno-3-8)    id: 'my-player',
[](#%5F%5Fcodelineno-3-9)    frame: {
[](#%5F%5Fcodelineno-3-10)      x: rect.x,
[](#%5F%5Fcodelineno-3-11)      y: rect.y,
[](#%5F%5Fcodelineno-3-12)      width: rect.width,
[](#%5F%5Fcodelineno-3-13)      height: rect.height,
[](#%5F%5Fcodelineno-3-14)    },
[](#%5F%5Fcodelineno-3-15)    videoId: 'dQw4w9WgXcQ',
[](#%5F%5Fcodelineno-3-16)    options: {
[](#%5F%5Fcodelineno-3-17)      mute: true,
[](#%5F%5Fcodelineno-3-18)    },
[](#%5F%5Fcodelineno-3-19)  });
[](#%5F%5Fcodelineno-3-20)};
`

### Control playback[¶](#control-playback "Permanent link")

`[](#%5F%5Fcodelineno-4-1)import { YoutubePlayer } from '@capawesome/capacitor-youtube-player';
[](#%5F%5Fcodelineno-4-2)
[](#%5F%5Fcodelineno-4-3)const controlPlayback = async () => {
[](#%5F%5Fcodelineno-4-4)  await YoutubePlayer.play({ id: 'my-player' });
[](#%5F%5Fcodelineno-4-5)  await YoutubePlayer.seekTo({ id: 'my-player', seconds: 42 });
[](#%5F%5Fcodelineno-4-6)  await YoutubePlayer.setVolume({ id: 'my-player', volume: 50 });
[](#%5F%5Fcodelineno-4-7)  await YoutubePlayer.setPlaybackRate({ id: 'my-player', rate: 1.5 });
[](#%5F%5Fcodelineno-4-8)  await YoutubePlayer.pause({ id: 'my-player' });
[](#%5F%5Fcodelineno-4-9)};
`

### Listen for events[¶](#listen-for-events "Permanent link")

`[](#%5F%5Fcodelineno-5-1)import { YoutubePlayer } from '@capawesome/capacitor-youtube-player';
[](#%5F%5Fcodelineno-5-2)
[](#%5F%5Fcodelineno-5-3)const addListeners = async () => {
[](#%5F%5Fcodelineno-5-4)  await YoutubePlayer.addListener('playerReady', event => {
[](#%5F%5Fcodelineno-5-5)    console.log('Player ready:', event.id);
[](#%5F%5Fcodelineno-5-6)  });
[](#%5F%5Fcodelineno-5-7)  await YoutubePlayer.addListener('playerStateChange', event => {
[](#%5F%5Fcodelineno-5-8)    console.log('Player state:', event.id, event.state);
[](#%5F%5Fcodelineno-5-9)  });
[](#%5F%5Fcodelineno-5-10)  await YoutubePlayer.addListener('playerError', event => {
[](#%5F%5Fcodelineno-5-11)    console.error('Player error:', event.id, event.code);
[](#%5F%5Fcodelineno-5-12)  });
[](#%5F%5Fcodelineno-5-13)};
`

### Remove a player[¶](#remove-a-player "Permanent link")

`[](#%5F%5Fcodelineno-6-1)import { YoutubePlayer } from '@capawesome/capacitor-youtube-player';
[](#%5F%5Fcodelineno-6-2)
[](#%5F%5Fcodelineno-6-3)const removePlayer = async () => {
[](#%5F%5Fcodelineno-6-4)  await YoutubePlayer.removePlayer({ id: 'my-player' });
[](#%5F%5Fcodelineno-6-5)};
`

## API[¶](#api "Permanent link")

* [createPlayer(...)](#createplayer)
* [cueVideo(...)](#cuevideo)
* [getCurrentTime(...)](#getcurrenttime)
* [getDuration(...)](#getduration)
* [loadVideo(...)](#loadvideo)
* [mute(...)](#mute)
* [pause(...)](#pause)
* [play(...)](#play)
* [removePlayer(...)](#removeplayer)
* [seekTo(...)](#seekto)
* [setPlaybackRate(...)](#setplaybackrate)
* [setPlayerFrame(...)](#setplayerframe)
* [setVolume(...)](#setvolume)
* [unmute(...)](#unmute)
* [addListener('currentTimeChange', ...)](#addlistenercurrenttimechange-)
* [addListener('fullscreenChange', ...)](#addlistenerfullscreenchange-)
* [addListener('playbackRateChange', ...)](#addlistenerplaybackratechange-)
* [addListener('playerError', ...)](#addlistenerplayererror-)
* [addListener('playerReady', ...)](#addlistenerplayerready-)
* [addListener('playerStateChange', ...)](#addlistenerplayerstatechange-)
* [removeAllListeners()](#removealllisteners)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)

### createPlayer(...)[¶](#createplayer "Permanent link")

`[](#%5F%5Fcodelineno-7-1)createPlayer(options: CreatePlayerOptions) => Promise<CreatePlayerResult>
`

Create a new YouTube player.

On Android and iOS, the player is rendered as a native view that is positioned above the web view at the given frame. The frame is not scrolled with the web content. Use `setPlayerFrame(...)` to keep the frame in sync with your layout (see the README for a recipe).

The player must be at least 200×200 CSS pixels, as required by the [YouTube Terms of Service](https://developers.google.com/youtube/terms/required-minimum-functionality#embedded-player-size).

| Param       | Type                                        |
| ----------- | ------------------------------------------- |
| **options** | [CreatePlayerOptions](#createplayeroptions) |

**Returns:** `Promise<[CreatePlayerResult](#createplayerresult)>`

**Since:** 0.1.0

---

### cueVideo(...)[¶](#cuevideo "Permanent link")

`[](#%5F%5Fcodelineno-8-1)cueVideo(options: CueVideoOptions) => Promise<void>
`

Load a video into the player without starting playback.

| Param       | Type                                |
| ----------- | ----------------------------------- |
| **options** | [CueVideoOptions](#cuevideooptions) |

**Since:** 0.1.0

---

### getCurrentTime(...)[¶](#getcurrenttime "Permanent link")

`[](#%5F%5Fcodelineno-9-1)getCurrentTime(options: GetCurrentTimeOptions) => Promise<GetCurrentTimeResult>
`

Get the current playback time of the player.

On Android, the value is answered from the most recent value pushed by the player (updated multiple times per second during playback).

| Param       | Type                                            |
| ----------- | ----------------------------------------------- |
| **options** | [GetCurrentTimeOptions](#getcurrenttimeoptions) |

**Returns:** `Promise<[GetCurrentTimeResult](#getcurrenttimeresult)>`

**Since:** 0.1.0

---

### getDuration(...)[¶](#getduration "Permanent link")

`[](#%5F%5Fcodelineno-10-1)getDuration(options: GetDurationOptions) => Promise<GetDurationResult>
`

Get the duration of the currently loaded video.

On Android, the value is answered from the most recent value pushed by the player.

| Param       | Type                                      |
| ----------- | ----------------------------------------- |
| **options** | [GetDurationOptions](#getdurationoptions) |

**Returns:** `Promise<[GetDurationResult](#getdurationresult)>`

**Since:** 0.1.0

---

### loadVideo(...)[¶](#loadvideo "Permanent link")

`[](#%5F%5Fcodelineno-11-1)loadVideo(options: LoadVideoOptions) => Promise<void>
`

Load a video into the player and start playback.

| Param       | Type                                  |
| ----------- | ------------------------------------- |
| **options** | [LoadVideoOptions](#loadvideooptions) |

**Since:** 0.1.0

---

### mute(...)[¶](#mute "Permanent link")

`[](#%5F%5Fcodelineno-12-1)mute(options: MuteOptions) => Promise<void>
`

Mute the player.

| Param       | Type                        |
| ----------- | --------------------------- |
| **options** | [MuteOptions](#muteoptions) |

**Since:** 0.1.0

---

### pause(...)[¶](#pause "Permanent link")

`[](#%5F%5Fcodelineno-13-1)pause(options: PauseOptions) => Promise<void>
`

Pause playback.

| Param       | Type                          |
| ----------- | ----------------------------- |
| **options** | [PauseOptions](#pauseoptions) |

**Since:** 0.1.0

---

### play(...)[¶](#play "Permanent link")

`[](#%5F%5Fcodelineno-14-1)play(options: PlayOptions) => Promise<void>
`

Start or resume playback.

| Param       | Type                        |
| ----------- | --------------------------- |
| **options** | [PlayOptions](#playoptions) |

**Since:** 0.1.0

---

### removePlayer(...)[¶](#removeplayer "Permanent link")

`[](#%5F%5Fcodelineno-15-1)removePlayer(options: RemovePlayerOptions) => Promise<void>
`

Remove the player and release all its resources.

| Param       | Type                                        |
| ----------- | ------------------------------------------- |
| **options** | [RemovePlayerOptions](#removeplayeroptions) |

**Since:** 0.1.0

---

### seekTo(...)[¶](#seekto "Permanent link")

`[](#%5F%5Fcodelineno-16-1)seekTo(options: SeekToOptions) => Promise<void>
`

Seek to the given time.

| Param       | Type                            |
| ----------- | ------------------------------- |
| **options** | [SeekToOptions](#seektooptions) |

**Since:** 0.1.0

---

### setPlaybackRate(...)[¶](#setplaybackrate "Permanent link")

`[](#%5F%5Fcodelineno-17-1)setPlaybackRate(options: SetPlaybackRateOptions) => Promise<void>
`

Set the playback rate of the player.

| Param       | Type                                              |
| ----------- | ------------------------------------------------- |
| **options** | [SetPlaybackRateOptions](#setplaybackrateoptions) |

**Since:** 0.1.0

---

### setPlayerFrame(...)[¶](#setplayerframe "Permanent link")

`[](#%5F%5Fcodelineno-18-1)setPlayerFrame(options: SetPlayerFrameOptions) => Promise<void>
`

Update the frame of the player.

Call this method whenever the layout changes (e.g. on scroll, resize or orientation change) to keep the player in sync with your layout.

| Param       | Type                                            |
| ----------- | ----------------------------------------------- |
| **options** | [SetPlayerFrameOptions](#setplayerframeoptions) |

**Since:** 0.1.0

---

### setVolume(...)[¶](#setvolume "Permanent link")

`[](#%5F%5Fcodelineno-19-1)setVolume(options: SetVolumeOptions) => Promise<void>
`

Set the volume of the player.

On iOS, the operating system does not allow changing the volume programmatically, so this method has no effect. Use `mute()` and `unmute()` instead.

| Param       | Type                                  |
| ----------- | ------------------------------------- |
| **options** | [SetVolumeOptions](#setvolumeoptions) |

**Since:** 0.1.0

---

### unmute(...)[¶](#unmute "Permanent link")

`[](#%5F%5Fcodelineno-20-1)unmute(options: UnmuteOptions) => Promise<void>
`

Unmute the player.

| Param       | Type                            |
| ----------- | ------------------------------- |
| **options** | [UnmuteOptions](#unmuteoptions) |

**Since:** 0.1.0

---

### addListener('currentTimeChange', ...)[¶](#addlistenercurrenttimechange "Permanent link")

`[](#%5F%5Fcodelineno-21-1)addListener(eventName: 'currentTimeChange', listenerFunc: (event: CurrentTimeChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the current playback time of a player changes.

The event is emitted multiple times per second during playback. The exact frequency depends on the platform.

| Param            | Type                                                               |
| ---------------- | ------------------------------------------------------------------ |
| **eventName**    | 'currentTimeChange'                                                |
| **listenerFunc** | (event: [CurrentTimeChangeEvent](#currenttimechangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('fullscreenChange', ...)[¶](#addlistenerfullscreenchange "Permanent link")

`[](#%5F%5Fcodelineno-22-1)addListener(eventName: 'fullscreenChange', listenerFunc: (event: FullscreenChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when a player enters or exits fullscreen.

Only available on Android and Web.

| Param            | Type                                                             |
| ---------------- | ---------------------------------------------------------------- |
| **eventName**    | 'fullscreenChange'                                               |
| **listenerFunc** | (event: [FullscreenChangeEvent](#fullscreenchangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('playbackRateChange', ...)[¶](#addlistenerplaybackratechange "Permanent link")

`[](#%5F%5Fcodelineno-23-1)addListener(eventName: 'playbackRateChange', listenerFunc: (event: PlaybackRateChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the playback rate of a player changes.

On iOS, this event is only emitted for `setPlaybackRate(...)` calls.

| Param            | Type                                                                 |
| ---------------- | -------------------------------------------------------------------- |
| **eventName**    | 'playbackRateChange'                                                 |
| **listenerFunc** | (event: [PlaybackRateChangeEvent](#playbackratechangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('playerError', ...)[¶](#addlistenerplayererror "Permanent link")

`[](#%5F%5Fcodelineno-24-1)addListener(eventName: 'playerError', listenerFunc: (event: PlayerErrorEvent) => void) => Promise<PluginListenerHandle>
`

Called when an error occurs in a player.

| Param            | Type                                                   |
| ---------------- | ------------------------------------------------------ |
| **eventName**    | 'playerError'                                          |
| **listenerFunc** | (event: [PlayerErrorEvent](#playererrorevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('playerReady', ...)[¶](#addlistenerplayerready "Permanent link")

`[](#%5F%5Fcodelineno-25-1)addListener(eventName: 'playerReady', listenerFunc: (event: PlayerReadyEvent) => void) => Promise<PluginListenerHandle>
`

Called when a player has finished loading and is ready to receive commands.

| Param            | Type                                                   |
| ---------------- | ------------------------------------------------------ |
| **eventName**    | 'playerReady'                                          |
| **listenerFunc** | (event: [PlayerReadyEvent](#playerreadyevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### addListener('playerStateChange', ...)[¶](#addlistenerplayerstatechange "Permanent link")

`[](#%5F%5Fcodelineno-26-1)addListener(eventName: 'playerStateChange', listenerFunc: (event: PlayerStateChangeEvent) => void) => Promise<PluginListenerHandle>
`

Called when the state of a player changes.

| Param            | Type                                                               |
| ---------------- | ------------------------------------------------------------------ |
| **eventName**    | 'playerStateChange'                                                |
| **listenerFunc** | (event: [PlayerStateChangeEvent](#playerstatechangeevent)) => void |

**Returns:** `Promise<[PluginListenerHandle](#pluginlistenerhandle)>`

**Since:** 0.1.0

---

### removeAllListeners()[¶](#removealllisteners "Permanent link")

`[](#%5F%5Fcodelineno-27-1)removeAllListeners() => Promise<void>
`

Remove all listeners for this plugin.

**Since:** 0.1.0

---

### Interfaces[¶](#interfaces "Permanent link")

#### CreatePlayerResult[¶](#createplayerresult "Permanent link")

| Prop   | Type   | Description                                  | Since |
| ------ | ------ | -------------------------------------------- | ----- |
| **id** | string | The unique identifier of the created player. | 0.1.0 |

#### CreatePlayerOptions[¶](#createplayeroptions "Permanent link")

| Prop        | Type                                              | Description                                                                                                                                                 | Since |
| ----------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **frame**   | [PlayerFrame](#playerframe)                       | The frame of the player in CSS pixels, relative to the viewport. Must be at least 200×200 CSS pixels.                                                       | 0.1.0 |
| **id**      | string                                            | The unique identifier of the player. If not provided, a random identifier is generated.                                                                     | 0.1.0 |
| **options** | [PlayerOptions](#playeroptions)                   | The player options.                                                                                                                                         | 0.1.0 |
| **videoId** | string                                            | The ID of the YouTube video to load into the player. If not provided, the player is created without a video. Load one with loadVideo(...) or cueVideo(...). | 0.1.0 |
| **web**     | [CreatePlayerWebOptions](#createplayerweboptions) | Options that are only available on Web.                                                                                                                     | 0.1.0 |

#### PlayerFrame[¶](#playerframe "Permanent link")

The frame of a player in CSS pixels, relative to the viewport.

| Prop       | Type   | Description                                                   | Since |
| ---------- | ------ | ------------------------------------------------------------- | ----- |
| **height** | number | The height of the player in CSS pixels. Must be at least 200. | 0.1.0 |
| **width**  | number | The width of the player in CSS pixels. Must be at least 200.  | 0.1.0 |
| **x**      | number | The x-coordinate of the player in CSS pixels.                 | 0.1.0 |
| **y**      | number | The y-coordinate of the player in CSS pixels.                 | 0.1.0 |

#### PlayerOptions[¶](#playeroptions "Permanent link")

| Prop             | Type    | Description                                                                                                                           | Default | Since |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----- |
| **autoplay**     | boolean | Whether the video starts playing automatically when the player is created.                                                            | false   | 0.1.0 |
| **ccLoadPolicy** | boolean | Whether closed captions are shown by default, even if the user has turned captions off.                                               | false   | 0.1.0 |
| **controls**     | boolean | Whether the player controls are displayed.                                                                                            | true    | 0.1.0 |
| **end**          | number  | The time in seconds at which the player should stop playing the video.                                                                |         | 0.1.0 |
| **fullscreen**   | boolean | Whether the fullscreen button is displayed. Only available on Android and Web.                                                        | false   | 0.1.0 |
| **ivLoadPolicy** | boolean | Whether video annotations are shown by default.                                                                                       | false   | 0.1.0 |
| **mute**         | boolean | Whether the player is muted when it is created.                                                                                       | false   | 0.1.0 |
| **rel**          | boolean | Whether related videos from other channels are shown when playback ends. If false, related videos are limited to the video's channel. | false   | 0.1.0 |
| **start**        | number  | The time in seconds from which the video should start playing.                                                                        |         | 0.1.0 |

#### CreatePlayerWebOptions[¶](#createplayerweboptions "Permanent link")

| Prop          | Type   | Description                                                                                                                                                                                                          | Since |
| ------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
| **elementId** | string | The ID of an existing DOM element to mount the player into. If provided, the player fills this element instead of being positioned at the given frame, and setPlayerFrame(...) has no effect. Only available on Web. | 0.1.0 |

#### CueVideoOptions[¶](#cuevideooptions "Permanent link")

| Prop             | Type   | Description                                                                      | Default | Since |
| ---------------- | ------ | -------------------------------------------------------------------------------- | ------- | ----- |
| **id**           | string | The unique identifier of the player.                                             |         | 0.1.0 |
| **startSeconds** | number | The time in seconds from which the video should start playing once it is played. | 0       | 0.1.0 |
| **videoId**      | string | The ID of the YouTube video to cue.                                              |         | 0.1.0 |

#### GetCurrentTimeResult[¶](#getcurrenttimeresult "Permanent link")

| Prop            | Type   | Description                           | Since |
| --------------- | ------ | ------------------------------------- | ----- |
| **currentTime** | number | The current playback time in seconds. | 0.1.0 |

#### GetCurrentTimeOptions[¶](#getcurrenttimeoptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### GetDurationResult[¶](#getdurationresult "Permanent link")

| Prop         | Type   | Description                                                                             | Since |
| ------------ | ------ | --------------------------------------------------------------------------------------- | ----- |
| **duration** | number | The duration of the currently loaded video in seconds. Returns 0 if no video is loaded. | 0.1.0 |

#### GetDurationOptions[¶](#getdurationoptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### LoadVideoOptions[¶](#loadvideooptions "Permanent link")

| Prop             | Type   | Description                                                    | Default | Since |
| ---------------- | ------ | -------------------------------------------------------------- | ------- | ----- |
| **id**           | string | The unique identifier of the player.                           |         | 0.1.0 |
| **startSeconds** | number | The time in seconds from which the video should start playing. | 0       | 0.1.0 |
| **videoId**      | string | The ID of the YouTube video to load.                           |         | 0.1.0 |

#### MuteOptions[¶](#muteoptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### PauseOptions[¶](#pauseoptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### PlayOptions[¶](#playoptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### RemovePlayerOptions[¶](#removeplayeroptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### SeekToOptions[¶](#seektooptions "Permanent link")

| Prop        | Type   | Description                          | Since |
| ----------- | ------ | ------------------------------------ | ----- |
| **id**      | string | The unique identifier of the player. | 0.1.0 |
| **seconds** | number | The time in seconds to seek to.      | 0.1.0 |

#### SetPlaybackRateOptions[¶](#setplaybackrateoptions "Permanent link")

| Prop     | Type   | Description                                                                 | Since |
| -------- | ------ | --------------------------------------------------------------------------- | ----- |
| **id**   | string | The unique identifier of the player.                                        | 0.1.0 |
| **rate** | number | The playback rate. Must be one of 0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75 or 2. | 0.1.0 |

#### SetPlayerFrameOptions[¶](#setplayerframeoptions "Permanent link")

| Prop      | Type                        | Description                                                                                               | Since |
| --------- | --------------------------- | --------------------------------------------------------------------------------------------------------- | ----- |
| **frame** | [PlayerFrame](#playerframe) | The new frame of the player in CSS pixels, relative to the viewport. Must be at least 200×200 CSS pixels. | 0.1.0 |
| **id**    | string                      | The unique identifier of the player.                                                                      | 0.1.0 |

#### SetVolumeOptions[¶](#setvolumeoptions "Permanent link")

| Prop       | Type   | Description                              | Since |
| ---------- | ------ | ---------------------------------------- | ----- |
| **id**     | string | The unique identifier of the player.     | 0.1.0 |
| **volume** | number | The volume as a value between 0 and 100. | 0.1.0 |

#### UnmuteOptions[¶](#unmuteoptions "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### PluginListenerHandle[¶](#pluginlistenerhandle "Permanent link")

| Prop       | Type                |
| ---------- | ------------------- |
| **remove** | () => Promise<void> |

#### CurrentTimeChangeEvent[¶](#currenttimechangeevent "Permanent link")

| Prop            | Type   | Description                           | Since |
| --------------- | ------ | ------------------------------------- | ----- |
| **currentTime** | number | The current playback time in seconds. | 0.1.0 |
| **id**          | string | The unique identifier of the player.  | 0.1.0 |

#### FullscreenChangeEvent[¶](#fullscreenchangeevent "Permanent link")

| Prop           | Type    | Description                          | Since |
| -------------- | ------- | ------------------------------------ | ----- |
| **fullscreen** | boolean | Whether the player is in fullscreen. | 0.1.0 |
| **id**         | string  | The unique identifier of the player. | 0.1.0 |

#### PlaybackRateChangeEvent[¶](#playbackratechangeevent "Permanent link")

| Prop     | Type   | Description                          | Since |
| -------- | ------ | ------------------------------------ | ----- |
| **id**   | string | The unique identifier of the player. | 0.1.0 |
| **rate** | number | The new playback rate.               | 0.1.0 |

#### PlayerErrorEvent[¶](#playererrorevent "Permanent link")

| Prop     | Type                                | Description                          | Since |
| -------- | ----------------------------------- | ------------------------------------ | ----- |
| **code** | [PlayerErrorCode](#playererrorcode) | The error code.                      | 0.1.0 |
| **id**   | string                              | The unique identifier of the player. | 0.1.0 |

#### PlayerReadyEvent[¶](#playerreadyevent "Permanent link")

| Prop   | Type   | Description                          | Since |
| ------ | ------ | ------------------------------------ | ----- |
| **id** | string | The unique identifier of the player. | 0.1.0 |

#### PlayerStateChangeEvent[¶](#playerstatechangeevent "Permanent link")

| Prop      | Type                        | Description                          | Since |
| --------- | --------------------------- | ------------------------------------ | ----- |
| **id**    | string                      | The unique identifier of the player. | 0.1.0 |
| **state** | [PlayerState](#playerstate) | The new state of the player.         | 0.1.0 |

### Type Aliases[¶](#type-aliases "Permanent link")

#### PlayerErrorCode[¶](#playererrorcode "Permanent link")

The error code of a player error.

`'html5-error' | 'invalid-parameter' | 'not-embeddable' | 'unknown' | 'video-not-found'`

#### PlayerState[¶](#playerstate "Permanent link")

The state of a player.

`'buffering' | 'cued' | 'ended' | 'paused' | 'playing' | 'unstarted'`

## Frame Synchronization[¶](#frame-synchronization "Permanent link")

On Android and iOS, the player is a native view that is rendered **above** the web view. It is not part of the DOM and therefore does not scroll or resize with your web content. Instead, you position it with CSS pixel frames and keep it in sync with your layout by calling `setPlayerFrame(...)` whenever the layout changes:

`[](#%5F%5Fcodelineno-28-1)import { YoutubePlayer } from '@capawesome/capacitor-youtube-player';
[](#%5F%5Fcodelineno-28-2)
[](#%5F%5Fcodelineno-28-3)const syncPlayerFrame = async () => {
[](#%5F%5Fcodelineno-28-4)  const rect = document
[](#%5F%5Fcodelineno-28-5)    .querySelector('#player-placeholder')
[](#%5F%5Fcodelineno-28-6)    .getBoundingClientRect();
[](#%5F%5Fcodelineno-28-7)  await YoutubePlayer.setPlayerFrame({
[](#%5F%5Fcodelineno-28-8)    id: 'my-player',
[](#%5F%5Fcodelineno-28-9)    frame: {
[](#%5F%5Fcodelineno-28-10)      x: rect.x,
[](#%5F%5Fcodelineno-28-11)      y: rect.y,
[](#%5F%5Fcodelineno-28-12)      width: rect.width,
[](#%5F%5Fcodelineno-28-13)      height: rect.height,
[](#%5F%5Fcodelineno-28-14)    },
[](#%5F%5Fcodelineno-28-15)  });
[](#%5F%5Fcodelineno-28-16)};
[](#%5F%5Fcodelineno-28-17)
[](#%5F%5Fcodelineno-28-18)window.addEventListener('scroll', syncPlayerFrame);
[](#%5F%5Fcodelineno-28-19)window.addEventListener('resize', syncPlayerFrame);
`

If you use a framework with its own scroll container (e.g. `ion-content`), attach the listener to that container's scroll event instead. On the Web, the player is positioned with `position: fixed`, so the same synchronization code works on all platforms. Alternatively, on the Web you can mount the player into an existing DOM element using the `web.elementId` option, in which case no frame synchronization is needed.

Since the player is rendered above the web view, HTML content can never overlap the player. Keep this in mind when designing your layout (see also [YouTube Terms of Service](#youtube-terms-of-service)).

## YouTube Terms of Service[¶](#youtube-terms-of-service "Permanent link")

By using this plugin, you agree to the [YouTube Terms of Service](https://www.youtube.com/t/terms) and the [YouTube API Services Terms of Service](https://developers.google.com/youtube/terms/api-services-terms-of-service). The plugin is designed to make it easy to comply with the [required minimum functionality](https://developers.google.com/youtube/terms/required-minimum-functionality) for embedded players:

* **Minimum player size**: Embedded players must be at least 200×200 pixels. The plugin enforces this and rejects smaller frames with the `FRAME_INVALID` error code.
* **No background playback**: Videos must not play in the background. The plugin automatically pauses all players when the app is moved to the background.
* **No overlays**: The player (including its ads) must not be obscured by other content. Since the native player view is always rendered above the web view, HTML content cannot overlap it by design.
* **Correct origin**: The plugin sets the `origin` player parameter correctly on all platforms, which avoids embed errors (e.g. error 152/153) without any header workarounds.
* **No player modification**: The plugin embeds the official YouTube player unaltered. Your app must not modify, build upon, or block any portion or functionality of the player — including any ads it serves.
* **Branding**: If your app displays YouTube logos or other brand assets alongside the player, follow the [YouTube Branding Guidelines](https://developers.google.com/youtube/terms/branding-guidelines).

## Platform Support[¶](#platform-support "Permanent link")

Not every feature is available on all platforms. The following table lists the per-platform differences of the plugin's API:

| Feature                | Android | iOS | Web |
| ---------------------- | ------- | --- | --- |
| Playback controls      | ✅       | ✅   | ✅   |
| fullscreen option      | ✅       | ❌   | ✅   |
| fullscreenChange event | ✅       | ❌   | ✅   |
| Native mute            | ✅       | 🔄  | ✅   |

Additional platform-specific behavior:

* **iOS mute emulation**: The iOS player library exposes no native mute API, so `mute()` is emulated by setting the volume to `0`. `unmute()` restores the last volume set via `setVolume(...)` (or `100`). If `setVolume(...)` is called while the player is muted, the volume is only applied on the next `unmute()` call.
* **iOS playback rate event**: On iOS, the `playbackRateChange` event is only emitted for `setPlaybackRate(...)` calls, since the iOS player library exposes no playback rate callback.
* **iOS error mapping**: On iOS, videos that are not allowed to be played in embedded players may be reported with the error code `unknown` instead of `not-embeddable`, due to the error mapping of the iOS player library.
* **Android getters**: On Android, `getCurrentTime(...)` and `getDuration(...)` are answered from the most recent values pushed by the player, which are updated multiple times per second during playback.
* **`currentTimeChange` frequency**: The event is emitted about 10 times per second on Android and about twice per second on iOS and Web.

## FAQ[¶](#faq "Permanent link")

### How is this plugin different from other similar plugins?[¶](#how-is-this-plugin-different-from-other-similar-plugins "Permanent link")

This plugin can render multiple native player instances at once, each positioned to an exact frame that you keep in sync with your layout. It exposes a full, strongly typed event set on Android, iOS, and Web, and embeds the official YouTube player unaltered. It is built to comply with the behaviors the YouTube Terms of Service require — a minimum player size, no background playback, nothing drawn over the player, and a correct origin — so you stay compliant by default. It is actively maintained and backed by dedicated support.

### Why is my frame rejected with `FRAME_INVALID`?[¶](#why-is-my-frame-rejected-with-frame%5Finvalid "Permanent link")

Embedded YouTube players must be at least 200×200 CSS pixels, as required by the YouTube Terms of Service. Make sure the `width` and `height` of your frame are at least `200`.

### Why does the player not scroll with my content?[¶](#why-does-the-player-not-scroll-with-my-content "Permanent link")

On Android and iOS, the player is a native view rendered above the web view and is not part of the DOM. Use `setPlayerFrame(...)` to keep it in sync with your layout (see [Frame Synchronization](#frame-synchronization)).

### Can I display HTML content above the player?[¶](#can-i-display-html-content-above-the-player "Permanent link")

No. The native player view is always rendered above the web view. This is also a requirement of the YouTube Terms of Service, which prohibit obscuring the player.

### Does playback continue in the background?[¶](#does-playback-continue-in-the-background "Permanent link")

No. The YouTube Terms of Service prohibit background playback, so the plugin automatically pauses all players when the app is moved to the background.

### Can I use this plugin with Ionic, React, Vue or Angular?[¶](#can-i-use-this-plugin-with-ionic-react-vue-or-angular "Permanent link")

Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects.

## Newsletter[¶](#newsletter "Permanent link")

Stay up to date with the latest news and updates about the Capawesome, Capacitor, and Ionic ecosystem by subscribing to our [Capawesome Newsletter](https://cloud.capawesome.io/newsletter/).

## Changelog[¶](#changelog "Permanent link")

See [CHANGELOG.md](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/youtube-player/CHANGELOG.md).

## License[¶](#license "Permanent link")

See [LICENSE](https://github.com/capawesome-team/capacitor-plugins/blob/main/packages/youtube-player/LICENSE).

---

1. This project is not affiliated with, endorsed by, sponsored by, or approved by Google LLC or YouTube LLC or any of their affiliates or subsidiaries. "YouTube" is a trademark of Google LLC. [↩](#fnref:1 "Jump back to footnote 1 in the text")

July 13, 2026 

Back to top

```json
{"@context": "https://schema.org", "@graph": [{"@type": "TechArticle", "@id": "https://capawesome.io/docs/sdks/capacitor/youtube-player/#article", "headline": "Capacitor YouTube Player Plugin for Android, iOS & Web", "name": "Capacitor YouTube Player Plugin for Android, iOS & Web", "description": "Unofficial Capacitor plugin to embed and control YouTube players on Android, iOS, and Web with inline playback, typed events, and playback controls.", "inLanguage": "en", "url": "https://capawesome.io/docs/sdks/capacitor/youtube-player/", "mainEntityOfPage": "https://capawesome.io/docs/sdks/capacitor/youtube-player/", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "about": {"@id": "https://capawesome.io/docs/sdks/capacitor/youtube-player/#software"}}, {"@type": "SoftwareSourceCode", "@id": "https://capawesome.io/docs/sdks/capacitor/youtube-player/#software", "name": "Capacitor YouTube Player Plugin for Android, iOS & Web", "description": "Unofficial Capacitor plugin to embed and control YouTube players on Android, iOS, and Web with inline playback, typed events, and playback controls.", "url": "https://capawesome.io/docs/sdks/capacitor/youtube-player/", "programmingLanguage": "TypeScript", "runtimePlatform": "Capacitor", "codeRepository": "https://github.com/capawesome-team", "author": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}, "publisher": {"@type": "Organization", "name": "Capawesome", "url": "https://capawesome.io", "logo": {"@type": "ImageObject", "url": "https://capawesome.io/assets/images/logo.svg"}}}]}
{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "How is this plugin different from other similar plugins?", "acceptedAnswer": {"@type": "Answer", "text": "This plugin can render multiple native player instances at once, each positioned to an exact frame that you keep in sync with your layout. It exposes a full, strongly typed event set on Android, iOS, and Web, and embeds the official YouTube player unaltered. It is built to comply with the behaviors the YouTube Terms of Service require — a minimum player size, no background playback, nothing drawn over the player, and a correct origin — so you stay compliant by default. It is actively maintained and backed by dedicated support."}}, {"@type": "Question", "name": "Why is my frame rejected with FRAME_INVALID?", "acceptedAnswer": {"@type": "Answer", "text": "Embedded YouTube players must be at least 200×200 CSS pixels, as required by the YouTube Terms of Service. Make sure the width and height of your frame are at least 200."}}, {"@type": "Question", "name": "Why does the player not scroll with my content?", "acceptedAnswer": {"@type": "Answer", "text": "On Android and iOS, the player is a native view rendered above the web view and is not part of the DOM. Use setPlayerFrame(...) to keep it in sync with your layout (see Frame Synchronization)."}}, {"@type": "Question", "name": "Can I display HTML content above the player?", "acceptedAnswer": {"@type": "Answer", "text": "No. The native player view is always rendered above the web view. This is also a requirement of the YouTube Terms of Service, which prohibit obscuring the player."}}, {"@type": "Question", "name": "Does playback continue in the background?", "acceptedAnswer": {"@type": "Answer", "text": "No. The YouTube Terms of Service prohibit background playback, so the plugin automatically pauses all players when the app is moved to the background."}}, {"@type": "Question", "name": "Can I use this plugin with Ionic, React, Vue or Angular?", "acceptedAnswer": {"@type": "Answer", "text": "Yes, the plugin is framework-agnostic. It works in any Capacitor app regardless of the web framework, including Ionic with Angular, React, or Vue, as well as plain JavaScript projects."}}], "url": "https://capawesome.io/docs/sdks/capacitor/youtube-player/"}
```
