Skip to content

Getting Started

  1. Install the package

    Terminal window
    npm i @capgo/capacitor-youtube-player
  2. Sync with native projects

    Terminal window
    npx cap sync

Basic Usage

import { YoutubePlayer } from '@capgo/capacitor-youtube-player';
// Initialize the player
const result = await YoutubePlayer.initialize({
playerId: 'youtube-player',
playerSize: { width: 640, height: 360 },
videoId: 'dQw4w9WgXcQ',
fullscreen: false,
playerVars: {
autoplay: 1,
controls: 1
}
});
// Play video
await YoutubePlayer.playVideo(result.player);
// Pause video
await YoutubePlayer.pauseVideo(result.player);
// Listen to player events
YoutubePlayer.addEventListener(result.player, 'onStateChange', (event) => {
console.log('Player state:', event.data);
});

API Reference

initialize(options)

Initialize a YouTube player instance.

const { player, playerReady } = await YoutubePlayer.initialize({
playerId: 'my-player',
playerSize: { width: 1280, height: 720 },
videoId: 'VIDEO_ID',
fullscreen: false,
playerVars: {
autoplay: 0,
controls: 1,
rel: 0
}
});

Video Control Methods

// Play
await YoutubePlayer.playVideo(playerId);
// Pause
await YoutubePlayer.pauseVideo(playerId);
// Stop
await YoutubePlayer.stopVideo(playerId);
// Seek to time
await YoutubePlayer.seekTo(playerId, seconds, allowSeekAhead);
// Load video by ID
await YoutubePlayer.loadVideoById(playerId, { videoId: 'VIDEO_ID' });
// Cue video (load without playing)
await YoutubePlayer.cueVideoById(playerId, { videoId: 'VIDEO_ID' });

Playlist Control

// Load playlist
await YoutubePlayer.loadPlaylist(playerId, {
listType: 'playlist',
list: 'PLAYLIST_ID'
});
// Cue playlist
await YoutubePlayer.cuePlaylist(playerId, {
playlist: ['VIDEO_ID_1', 'VIDEO_ID_2'],
index: 0
});
// Navigate playlist
await YoutubePlayer.nextVideo(playerId);
await YoutubePlayer.previousVideo(playerId);
await YoutubePlayer.playVideoAt(playerId, index);

Audio Control

// Mute/Unmute
await YoutubePlayer.mute(playerId);
await YoutubePlayer.unMute(playerId);
const { result } = await YoutubePlayer.isMuted(playerId);
console.log('Muted:', result.value);
// Volume (0-100)
await YoutubePlayer.setVolume(playerId, 50);
const { result } = await YoutubePlayer.getVolume(playerId);

Playback Control

// Playback rate
await YoutubePlayer.setPlaybackRate(playerId, 1.5);
const { result } = await YoutubePlayer.getPlaybackRate(playerId);
// Available rates
const { result } = await YoutubePlayer.getAvailablePlaybackRates(playerId);
console.log('Available rates:', result.value);
// Loop and shuffle
await YoutubePlayer.setLoop(playerId, true);
await YoutubePlayer.setShuffle(playerId, true);

Quality Control

// Set quality
await YoutubePlayer.setPlaybackQuality(playerId, 'hd720');
// Get current quality
const { result } = await YoutubePlayer.getPlaybackQuality(playerId);
// Get available qualities
const { result } = await YoutubePlayer.getAvailableQualityLevels(playerId);

Player Information

// Duration
const { result } = await YoutubePlayer.getDuration(playerId);
// Current time
const { result } = await YoutubePlayer.getCurrentTime(playerId);
// Loaded fraction
const { result } = await YoutubePlayer.getVideoLoadedFraction(playerId);
// Player state
const { result } = await YoutubePlayer.getPlayerState(playerId);
// Video URL
const { result } = await YoutubePlayer.getVideoUrl(playerId);

Event Listeners

// State change
YoutubePlayer.addEventListener(playerId, 'onStateChange', (event) => {
console.log('State:', event.data); // -1, 0, 1, 2, 3, 5
});
// Ready
YoutubePlayer.addEventListener(playerId, 'onReady', (event) => {
console.log('Player ready');
});
// Error
YoutubePlayer.addEventListener(playerId, 'onError', (event) => {
console.error('Player error:', event.data);
});
// Quality change
YoutubePlayer.addEventListener(playerId, 'onPlaybackQualityChange', (event) => {
console.log('Quality:', event.data);
});
// Rate change
YoutubePlayer.addEventListener(playerId, 'onPlaybackRateChange', (event) => {
console.log('Rate:', event.data);
});
// Remove listener
YoutubePlayer.removeEventListener(playerId, 'onStateChange', callback);

Complete Example

import { YoutubePlayer } from '@capgo/capacitor-youtube-player';
export class YouTubeService {
private playerId: string | null = null;
async initPlayer(videoId: string) {
try {
const { player, playerReady } = await YoutubePlayer.initialize({
playerId: 'main-player',
playerSize: { width: 1280, height: 720 },
videoId,
fullscreen: false,
playerVars: {
autoplay: 0,
controls: 1,
modestbranding: 1,
rel: 0
}
});
this.playerId = player;
// Set up event listeners
YoutubePlayer.addEventListener(player, 'onReady', () => {
console.log('Player is ready');
});
YoutubePlayer.addEventListener(player, 'onStateChange', (event) => {
this.handleStateChange(event.data);
});
YoutubePlayer.addEventListener(player, 'onError', (event) => {
console.error('YouTube error:', event.data);
});
return player;
} catch (error) {
console.error('Failed to initialize player:', error);
throw error;
}
}
private handleStateChange(state: number) {
switch (state) {
case -1:
console.log('Unstarted');
break;
case 0:
console.log('Ended');
break;
case 1:
console.log('Playing');
break;
case 2:
console.log('Paused');
break;
case 3:
console.log('Buffering');
break;
case 5:
console.log('Video cued');
break;
}
}
async play() {
if (!this.playerId) return;
await YoutubePlayer.playVideo(this.playerId);
}
async pause() {
if (!this.playerId) return;
await YoutubePlayer.pauseVideo(this.playerId);
}
async loadVideo(videoId: string) {
if (!this.playerId) return;
await YoutubePlayer.loadVideoById(this.playerId, { videoId });
}
async loadPlaylist(playlistId: string) {
if (!this.playerId) return;
await YoutubePlayer.loadPlaylist(this.playerId, {
listType: 'playlist',
list: playlistId,
index: 0
});
}
async setQuality(quality: 'small' | 'medium' | 'large' | 'hd720' | 'hd1080') {
if (!this.playerId) return;
await YoutubePlayer.setPlaybackQuality(this.playerId, quality);
}
async getProgress() {
if (!this.playerId) return { current: 0, duration: 0 };
const current = await YoutubePlayer.getCurrentTime(this.playerId);
const duration = await YoutubePlayer.getDuration(this.playerId);
return {
current: current.result.value,
duration: duration.result.value
};
}
async destroy() {
if (!this.playerId) return;
await YoutubePlayer.destroy(this.playerId);
this.playerId = null;
}
}

Player States

StateValueDescription
UNSTARTED-1Video not started
ENDED0Video has ended
PLAYING1Video is playing
PAUSED2Video is paused
BUFFERING3Video is buffering
CUED5Video is cued

Quality Levels

  • small: 240p
  • medium: 360p
  • large: 480p
  • hd720: 720p
  • hd1080: 1080p
  • highres: >1080p
  • default: Auto quality

Best Practices

  1. Initialize once Create player instance once and reuse it:

    let player = await YoutubePlayer.initialize(options);
    // Reuse player for different videos
    await YoutubePlayer.loadVideoById(player, { videoId: 'NEW_ID' });
  2. Handle errors gracefully

    YoutubePlayer.addEventListener(playerId, 'onError', (event) => {
    switch (event.data) {
    case 2:
    console.error('Invalid parameter');
    break;
    case 100:
    console.error('Video not found');
    break;
    case 101:
    case 150:
    console.error('Embedding not allowed');
    break;
    }
    });
  3. Clean up Destroy player when component unmounts:

    useEffect(() => {
    return () => {
    if (playerId) {
    YoutubePlayer.destroy(playerId);
    }
    };
    }, []);
  4. Respect user preferences

    // Don't autoplay unless user initiated
    playerVars: {
    autoplay: 0
    }
  5. Monitor playback

    setInterval(async () => {
    const time = await YoutubePlayer.getCurrentTime(playerId);
    updateProgressBar(time.result.value);
    }, 1000);

Platform Notes

iOS

  • Works on iOS 9.0+
  • Uses WKWebView with YouTube iframe API
  • Fullscreen supported

Android

  • Works on Android 5.0 (API 21)+
  • Uses WebView with YouTube iframe API
  • Fullscreen supported

Web

  • Direct YouTube iframe integration
  • Full API support
  • Best performance

Troubleshooting

Player not loading:

  • Check video ID is valid
  • Verify internet connection
  • Ensure YouTube embedding is allowed for the video

Events not firing:

  • Make sure listeners are added after initialization
  • Check player is ready before adding listeners

Quality issues:

  • Check available quality levels first
  • Some videos don’t support all qualities
  • Quality changes may not be immediate