capacitor-youtube-player
Version:
Capacitor Youtube Player
433 lines (426 loc) • 22.2 kB
JavaScript
'use strict';
var core = require('@capacitor/core');
const YoutubePlayer = core.registerPlugin('YoutubePlayer', {
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.YoutubePlayerPluginWeb()),
});
class Log {
constructor(logEnabled = false) {
this.logEnabled = false;
this.logEnabled = logEnabled;
}
log(msg, ...suportingDetails) {
this.emitLogMessage("log", msg, suportingDetails);
}
debug(msg, ...suportingDetails) {
this.emitLogMessage("debug", msg, suportingDetails);
}
warn(msg, ...suportingDetails) {
this.emitLogMessage("warn", msg, suportingDetails);
}
error(msg, ...suportingDetails) {
this.emitLogMessage("error", msg, suportingDetails);
}
info(msg, ...suportingDetails) {
this.emitLogMessage("info", msg, suportingDetails);
}
emitLogMessage(msgType, msg, suportingDetails) {
if (this.logEnabled) {
suportingDetails.length > 0 ? console[msgType]("[Youtube Player Plugin Web]: " + msg, suportingDetails)
: console[msgType]("[Youtube Player Plugin Web]: " + msg);
}
}
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function YT() {
return window['YT'];
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function Player() {
return YT().Player;
}
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
function PlayerState() {
return YT().PlayerState;
}
class YoutubePlayerPluginWeb extends core.WebPlugin {
constructor() {
super({
name: 'YoutubePlayerPluginWeb',
platforms: ['web']
});
this.players = [];
this.playersEventsState = new Map();
this.playerApiLoaded = false;
this.defaultSizes = {
height: 270,
width: 367
};
}
async loadPlayerApi() {
this.playerLogger.log("loadPlayerApi");
return await new Promise(resolve => {
window.onYouTubeIframeAPIReady = () => {
this.playerLogger.log("onYouTubeIframeAPIReady");
this.playerApiLoaded = true;
resolve(true);
};
// This code loads the IFrame Player API code asynchronously.
const tag = document.createElement('script');
tag.type = 'text/javascript';
tag.src = "https://www.youtube.com/iframe_api";
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
});
}
checkSize(options) {
const playerSize = {
height: options.playerSize.height || this.defaultSizes.height,
width: options.playerSize.width || this.defaultSizes.width
};
if (playerSize.height > window.innerHeight)
playerSize.height = window.innerHeight;
if (playerSize.width > window.innerWidth)
playerSize.width = window.innerWidth;
return playerSize;
}
// This function creates an <iframe> (and YouTube player)
// after the API code downloads.
async createPlayer(options) {
this.playerLogger.log("createPlayer");
const playerSize = this.checkSize(options);
return await new Promise(resolve => {
const player = Player();
this.players[options.playerId] = new player(options.playerId, Object.assign(Object.assign({ playerVars: options.playerVars }, playerSize), { fullscreen: options.fullscreen, videoId: options.videoId, events: {
// The API will call this function when the video player is ready.
'onReady': (event) => {
var _a;
this.playerLogger.log(`player "${options.playerId}" -> onPlayerReady`);
const state = { events: { onReady: { text: 'onReady', value: true } } };
this.playersEventsState.set(options.playerId, state);
if (((_a = options === null || options === void 0 ? void 0 : options.playerVars) === null || _a === void 0 ? void 0 : _a.autoplay) === 1) {
event.target.mute();
event.target.playVideo();
}
return resolve({ playerReady: true, player: this.players[options.playerId] });
},
'onStateChange': (event) => {
this.playerLogger.log(`player "${options.playerId}" -> onPlayerStateChange`);
switch (event.data) {
case PlayerState().PLAYING:
this.playerLogger.log(`player "${options.playerId}" -> playing`);
this.playersEventsState.get(options.playerId).events.onStateChange = { text: 'playing', value: PlayerState().PLAYING };
if (options.fullscreen) {
const iframe = document.getElementById(options.playerId);
const requestFullScreen = iframe === null || iframe === void 0 ? void 0 : iframe.requestFullscreen;
if (requestFullScreen) {
requestFullScreen.bind(iframe)();
}
}
break;
case PlayerState().PAUSED:
this.playerLogger.log(`player "${options.playerId}" -> paused`);
this.playersEventsState.get(options.playerId).events.onStateChange = { text: 'paused', value: PlayerState().PAUSED };
break;
case PlayerState().ENDED:
this.playerLogger.log(`player "${options.playerId}" -> ended`);
this.playersEventsState.get(options.playerId).events.onStateChange = { text: 'ended', value: PlayerState().ENDED };
break;
case PlayerState().BUFFERING:
this.playerLogger.log(`player "${options.playerId}" -> buffering`);
this.playersEventsState.get(options.playerId).events.onStateChange = { text: 'buffering', value: PlayerState().BUFFERING };
break;
case PlayerState().CUED:
this.playerLogger.log(`player "${options.playerId}" -> cued`);
this.playersEventsState.get(options.playerId).events.onStateChange = { text: 'cued', value: PlayerState().CUED };
break;
}
},
'onPlaybackQualityChange': (event) => {
this.playerLogger.log(`player "${options.playerId}" -> onPlayerPlaybackQualityChange quality ${event.data}`);
this.playersEventsState.get(options.playerId).events.onPlaybackQualityChange = { text: 'onPlaybackQualityChange', value: event.data };
},
'onError': (error) => {
this.playerLogger.error(`player "${options.playerId}" -> onPlayerError`, { error: error });
this.playersEventsState.get(options.playerId).events.onError = { text: 'onError', value: error };
}
} }));
});
}
async initialize(options) {
this.playerLogger = new Log(options.debug);
this.playerLogger.log("initialize");
if (!this.playerApiLoaded) {
const result = await this.loadPlayerApi();
this.playerLogger.log("loadPlayerApi result", { result: result });
}
if (this.playerApiLoaded) {
const playerReady = await this.createPlayer(options);
this.playerLogger.log("loadPlayerApi initialize completed", { playerReady: playerReady });
return Promise.resolve(playerReady);
}
}
async destroy(playerId) {
this.playerLogger.log(`player "${playerId}" -> destroy`);
this.players[playerId].destroy();
return Promise.resolve({ result: { method: 'destroy', value: true } });
}
// Methods playback controls and player settings.
/*********/
// Stops and cancels loading of the current video. This function should be reserved for rare situations when you know that the user will not be watching
// additional video in the player. If your intent is to pause the video, you should just call the pauseVideo function. If you want to change the video
// that the player is playing, you can call one of the queueing functions without calling stopVideo first.
async stopVideo(playerId) {
this.playerLogger.log(`player "${playerId}" -> stopVideo`);
this.players[playerId].stopVideo();
return Promise.resolve({ result: { method: 'stopVideo', value: true } });
}
// Plays the currently cued/loaded video. The final player state after this function executes will be playing (1).
async playVideo(playerId) {
this.playerLogger.log(`player "${playerId}" -> playVideo`);
this.players[playerId].playVideo();
return Promise.resolve({ result: { method: 'playVideo', value: true } });
}
// Pauses the currently playing video. The final player state after this function executes will be paused (2) unless the player is in the ended (0)
// state when the function is called, in which case the player state will not change.
async pauseVideo(playerId) {
this.playerLogger.log(`player "${playerId}" -> pauseVideo`);
this.players[playerId].pauseVideo();
return Promise.resolve({ result: { method: 'pauseVideo', value: true } });
}
// Seeks to a specified time in the video. If the player is paused when the function is called, it will remain paused. If the function is called from
// another state (playing, video cued, etc.), the player will play the video.
async seekTo(playerId, seconds, allowSeekAhead) {
this.playerLogger.log(`player "${playerId}" -> seekTo ${seconds} seconds`);
this.players[playerId].seekTo(seconds, allowSeekAhead);
return Promise.resolve({ result: { method: 'seekTo', value: true, seconds: seconds, allowSeekAhead: allowSeekAhead } });
}
// Loads and plays the specified video.
async loadVideoById(playerId, options) {
this.playerLogger.log(`player "${playerId}" -> loadVideoById with options ${options}`);
this.players[playerId].loadVideoById(options);
return Promise.resolve({ result: { method: 'loadVideoById', value: true, options: options } });
}
// Loads the specified video's thumbnail and prepares the player to play the video. The player does not request the FLV until playVideo() or seekTo() is called.
async cueVideoById(playerId, options) {
this.playerLogger.log(`player "${playerId}" -> cueVideoById with options ${options}`);
this.players[playerId].cueVideoById(options);
return Promise.resolve({ result: { method: 'cueVideoById', value: true, options: options } });
}
async loadVideoByUrl(playerId, options) {
this.playerLogger.log(`player "${playerId}" -> loadVideoByUrl with options ${options}`);
this.players[playerId].loadVideoByUrl(options);
return Promise.resolve({ result: { method: 'loadVideoByUrl', value: true, options: options } });
}
async cueVideoByUrl(playerId, options) {
this.playerLogger.log(`player "${playerId}" -> cueVideoByUrl with options ${options}`);
this.players[playerId].cueVideoByUrl(options);
return Promise.resolve({ result: { method: 'cueVideoByUrl', value: true, options: options } });
}
/*********/
// Methods for playing playlist.
/*********/
async cuePlaylist(playerId, playlistOptions) {
this.playerLogger.log(`player "${playerId}" -> cuePlaylist with options ${JSON.stringify(playlistOptions)}`);
this.players[playerId].cuePlaylist(playlistOptions);
return Promise.resolve({ result: { method: 'cuePlaylist', value: true } });
}
async loadPlaylist(playerId, playlistOptions) {
this.playerLogger.log(`player "${playerId}" -> loadPlaylist with options ${playlistOptions}`);
this.players[playerId].loadPlaylist(playlistOptions);
return Promise.resolve({ result: { method: 'loadPlaylist', value: true } });
}
/*********/
// Methods for playing video in playlist.
/*********/
async nextVideo(playerId) {
this.playerLogger.log(`player "${playerId}" -> nextVideo`);
this.players[playerId].nextVideo();
return Promise.resolve({ result: { method: 'nextVideo', value: true } });
}
async previousVideo(playerId) {
this.playerLogger.log(`player "${playerId}" -> previousVideo`);
this.players[playerId].previousVideo();
return Promise.resolve({ result: { method: 'previousVideo', value: true } });
}
async playVideoAt(playerId, index) {
this.playerLogger.log(`player "${playerId}" -> playVideoAt`);
this.players[playerId].playVideoAt(index);
return Promise.resolve({ result: { method: 'playVideoAt', value: true } });
}
/*********/
// Methods for adjusting the playback speed.
async getPlaybackRate(playerId) {
this.playerLogger.log(`player "${playerId}" -> getPlaybackRate`);
return Promise.resolve({ result: { method: 'getPlaybackRate', value: this.players[playerId].getPlaybackRate() } });
}
async setPlaybackRate(playerId, rate) {
this.playerLogger.log(`player "${playerId}" -> setPlaybackRate`);
this.players[playerId].setPlaybackRate(rate);
return Promise.resolve({ result: { method: 'setPlaybackRate', value: true } });
}
async getAvailablePlaybackRates(playerId) {
this.playerLogger.log(`player -> getAvailablePlaybackRates`);
return Promise.resolve({ result: { method: 'getAvailablePlaybackRates', value: this.players[playerId].getAvailablePlaybackRates() } });
}
/*********/
/*********/
// Methods for playlist playback settings
/*********/
async setLoop(playerId, loop) {
this.playerLogger.log(`player "${playerId}" -> setLoop`);
this.players[playerId].setLoop(loop);
return Promise.resolve({ result: { method: 'setLoop', value: true } });
}
async setShuffle(playerId, shuffle) {
this.playerLogger.log(`player "${playerId}" -> setShuffle`);
this.players[playerId].setShuffle(shuffle);
return Promise.resolve({ result: { method: 'setShuffle', value: true } });
}
/*********/
// Methods changing the player volume.
/*********/
// Mutes the player.
async mute(playerId) {
this.playerLogger.log(`player "${playerId}" -> mute`);
this.players[playerId].mute();
return Promise.resolve({ result: { method: 'mute', value: true } });
}
// Unmutes the player.
async unMute(playerId) {
this.playerLogger.log(`player "${playerId}" -> unMute`);
this.players[playerId].unMute();
return Promise.resolve({ result: { method: 'unMute', value: true } });
}
// Returns true if the player is muted, false if not.
async isMuted(playerId) {
this.playerLogger.log(`player "${playerId}" -> isMuted`);
return Promise.resolve({ result: { method: 'isMuted', value: this.players[playerId].isMuted() } });
}
// Sets the volume. Accepts an integer between 0 and 100.
async setVolume(playerId, volume) {
this.playerLogger.log(`player "${playerId}" -> setVolume ${volume}`);
this.players[playerId].setVolume(volume);
return Promise.resolve({ result: { method: 'setVolume', value: volume } });
}
// Returns the player's current volume, an integer between 0 and 100. Note that getVolume() will return the volume even if the player is muted.
async getVolume(playerId) {
this.playerLogger.log(`player "${playerId}" -> getVolume`);
return Promise.resolve({ result: { method: 'getVolume', value: this.players[playerId].getVolume() } });
}
/*********/
// Methods setting the player size.
/*********/
// Sets the size in pixels of the <iframe> that contains the player.
async setSize(playerId, width, height) {
this.playerLogger.log(`player "${playerId}" -> setSize width: ${width} height: ${height}`);
this.players[playerId].setSize(width, height);
return Promise.resolve({ result: { method: 'setSize', value: { width: width, height: height } } });
}
/*********/
// Methods playback status.
/*********/
// Returns a number between 0 and 1 that specifies the percentage of the video that the player shows as buffered.
// This method returns a more reliable number than the now-deprecated getVideoBytesLoaded and getVideoBytesTotal methods.
async getVideoLoadedFraction(playerId) {
this.playerLogger.log(`player "${playerId}" -> getVideoLoadedFraction`);
return Promise.resolve({ result: { method: 'getVideoLoadedFraction', value: this.players[playerId].getVideoLoadedFraction() } });
}
// Returns the state of the player. Possible values are:
// -1 – unstarted
// 0 – ended
// 1 – playing
// 2 – paused
// 3 – buffering
// 5 – video cued
async getPlayerState(playerId) {
this.playerLogger.log(`player "${playerId}" -> getPlayerState`);
return Promise.resolve({ result: { method: 'getPlayerState', value: this.players[playerId].getPlayerState() } });
}
async getAllPlayersEventsState() {
this.playerLogger.log("getAllPlayersEventsState");
return Promise.resolve({ result: { method: 'getAllPlayersEventsState', value: this.playersEventsState } });
}
// Returns the elapsed time in seconds since the video started playing.
async getCurrentTime(playerId) {
this.playerLogger.log(`player "${playerId}" -> getCurrentTime`);
return Promise.resolve({ result: { method: 'getCurrentTime', value: this.players[playerId].getCurrentTime() } });
}
async toggleFullScreen(playerId, isFullScreen) {
this.playerLogger.log(`player "${playerId}" -> toggleFullScreen`);
let { height, width } = this.defaultSizes;
if (!isFullScreen) {
height = window.innerHeight;
width = window.innerWidth;
}
this.players[playerId].setSize(width, height);
return Promise.resolve({ result: { method: 'toggleFullScreen', value: isFullScreen } });
}
/*********/
// Methods playback quality.
/*********/
async getPlaybackQuality(playerId) {
this.playerLogger.log(`player "${playerId}" -> getPlaybackQuality`);
return Promise.resolve({ result: { method: 'getPlaybackQuality', value: this.players[playerId].getPlaybackQuality() } });
}
async setPlaybackQuality(playerId, playbackQuality) {
this.playerLogger.log(`player "${playerId}" -> setPlaybackQuality`);
this.players[playerId].setPlaybackQuality(playbackQuality);
return Promise.resolve({ result: { method: 'setPlaybackQuality', value: true } });
}
async getAvailableQualityLevels(playerId) {
this.playerLogger.log(`player "${playerId}" -> getAvailableQualityLevels`);
return Promise.resolve({ result: { method: 'getAvailableQualityLevels', value: this.players[playerId].getAvailableQualityLevels() } });
}
/*********/
// Methods for retrieving video information.
/*********/
async getDuration(playerId) {
this.playerLogger.log(`player "${playerId}" -> getDuration`);
return Promise.resolve({ result: { method: 'getDuration', value: this.players[playerId].getDuration() } });
}
async getVideoUrl(playerId) {
this.playerLogger.log(`player "${playerId}" -> getVideoUrl`);
return Promise.resolve({ result: { method: 'getVideoUrl', value: this.players[playerId].getVideoUrl() } });
}
async getVideoEmbedCode(playerId) {
this.playerLogger.log(`player "${playerId}" -> getVideoEmbedCode`);
return Promise.resolve({ result: { method: 'getVideoEmbedCode', value: this.players[playerId].getVideoEmbedCode() } });
}
/*********/
// Methods for retrieving playlist information.
/*********/
async getPlaylist(playerId) {
this.playerLogger.log(`player "${playerId}" -> getPlaylist`);
return Promise.resolve({ result: { method: 'getPlaylist', value: this.players[playerId].getPlaylist() } });
}
async getPlaylistIndex(playerId) {
this.playerLogger.log(`player "${playerId}" -> getPlaylistIndex`);
return Promise.resolve({ result: { method: 'getPlaylistIndex', value: this.players[playerId].getPlaylistIndex() } });
}
/*********/
// Methods accessing and modifying DOM nodes.
/*********/
async getIframe(playerId) {
this.playerLogger.log(`player "${playerId}" -> getIframe`);
return Promise.resolve({ result: { method: 'getIframe', value: this.players[playerId].getIframe() } });
}
/*********/
// Player event listeners.
addEventListener(playerId, eventName, listener) {
this.playerLogger.log(`player "${playerId}" -> addEventListener "${eventName}"`);
this.players[playerId].addEventListener(eventName, listener);
}
removeEventListener(playerId, eventName, listener) {
this.playerLogger.log(`player "${playerId}" -> removeEventListener "${eventName}"`);
this.players[playerId].removeEventListener(eventName, listener);
}
}
var web = /*#__PURE__*/Object.freeze({
__proto__: null,
YT: YT,
Player: Player,
PlayerState: PlayerState,
YoutubePlayerPluginWeb: YoutubePlayerPluginWeb
});
exports.YoutubePlayer = YoutubePlayer;
//# sourceMappingURL=plugin.cjs.js.map