2023-08-29 15:52:58 +00:00
|
|
|
class invidious_embed {
|
2023-08-18 02:40:50 +00:00
|
|
|
static widgetid = 0;
|
2023-09-02 17:27:05 +00:00
|
|
|
static eventname_table = { onPlaybackRateChange: 'ratechange', onStateChange: 'statechange', onError: 'error', onReady: 'ready' };
|
2023-09-02 17:17:14 +00:00
|
|
|
static available_event_name = ['ready', 'ended', 'error', 'ratechange', 'volumechange', 'waiting', 'timeupdate', 'loadedmetadata', 'play', 'seeking', 'seeked', 'playerresize', 'pause'];
|
2023-08-18 02:40:50 +00:00
|
|
|
static api_promise = false;
|
2023-08-29 15:52:58 +00:00
|
|
|
static invidious_instance = '';
|
2023-09-02 17:17:14 +00:00
|
|
|
static api_instance_list = [];
|
|
|
|
static instance_status_list = {};
|
|
|
|
|
2023-08-29 15:52:58 +00:00
|
|
|
addEventListener(eventname, func) {
|
2023-09-03 15:43:39 +00:00
|
|
|
if (eventname in invidious_embed.eventname_table) {
|
|
|
|
eventname = invidious_embed.eventname_table[eventname];
|
2023-09-02 17:17:14 +00:00
|
|
|
}
|
2023-09-03 15:43:39 +00:00
|
|
|
this.eventElement.addEventListener(eventname,func);
|
2023-09-02 17:17:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
removeEventListener(eventname, func) {
|
2023-09-03 15:43:39 +00:00
|
|
|
if (eventname in invidious_embed.eventname_table) {
|
|
|
|
eventname = invidious_embed.eventname_table[eventname];
|
2023-09-02 17:17:14 +00:00
|
|
|
}
|
2023-09-03 15:43:39 +00:00
|
|
|
this.eventElement.removeEventListener(eventname,func);
|
2023-09-02 17:17:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async instance_access_check(instance_origin) {
|
|
|
|
let return_status;
|
|
|
|
const status_cahce_exist = instance_origin in invidious_embed.instance_status_list;
|
|
|
|
if (!status_cahce_exist) {
|
2023-09-02 17:27:05 +00:00
|
|
|
try {
|
2023-09-02 17:17:14 +00:00
|
|
|
const instance_stats = await fetch(instance_origin + '/api/v1/stats');
|
|
|
|
if (instance_stats.ok) {
|
|
|
|
const instance_stats_json = await instance_stats.json();
|
|
|
|
if (instance_stats_json.software.name === 'invidious') {
|
|
|
|
return_status = true;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
return_status = false;
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
return_status = false;
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} catch {
|
2023-09-02 17:17:14 +00:00
|
|
|
return_status = false;
|
|
|
|
}
|
|
|
|
invidious_embed.instance_status_list[instance_origin] = return_status;
|
|
|
|
return return_status;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
return invidious_embed.instance_status_list[instance_origin];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async get_instance_list() {
|
|
|
|
invidious_embed.api_instance_list = [];
|
|
|
|
const instance_list_api = await (await fetch('https://api.invidious.io/instances.json?pretty=1&sort_by=type,users')).json();
|
|
|
|
instance_list_api.forEach(instance_data => {
|
|
|
|
const http_check = instance_data[1]['type'] === 'https';
|
|
|
|
let status_check_api_data;
|
|
|
|
if (instance_data[1]['monitor'] !== null) {
|
|
|
|
status_check_api_data = instance_data[1]['monitor']['statusClass'] === 'success';
|
|
|
|
}
|
|
|
|
const api_available = instance_data[1]['api'] && instance_data[1]['cors'];
|
|
|
|
if (http_check && status_check_api_data && api_available) {
|
|
|
|
invidious_embed.api_instance_list.push(instance_data[1]['uri']);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2023-09-02 17:27:05 +00:00
|
|
|
async auto_instance_select() {
|
|
|
|
if (await this.instance_access_check(invidious_embed.invidious_instance)) {
|
2023-09-02 17:17:14 +00:00
|
|
|
return;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
if (invidious_embed.api_instance_list.length === 0) {
|
|
|
|
await this.get_instance_list();
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
for (let x = 0; x < invidious_embed.api_instance_list.length; x++) {
|
|
|
|
if (await this.instance_access_check(invidious_embed.api_instance_list[x])) {
|
2023-09-02 17:17:14 +00:00
|
|
|
invidious_embed.invidious_instance = invidious_embed.api_instance_list[x];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
2023-09-02 17:27:05 +00:00
|
|
|
async videoid_accessable_check(videoid) {
|
2023-09-02 17:17:14 +00:00
|
|
|
const video_api_response = await fetch(invidious_embed.invidious_instance + "/api/v1/videos/" + videoid);
|
|
|
|
return video_api_response.ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
async getPlaylistVideoids(playlistid) {
|
|
|
|
const playlist_api_response = await fetch(invidious_embed.invidious_instance + "/api/v1/playlists/" + playlistid);
|
2023-09-02 17:27:05 +00:00
|
|
|
if (playlist_api_response.ok) {
|
2023-09-02 17:17:14 +00:00
|
|
|
const playlist_api_json = await playlist_api_response.json();
|
|
|
|
let tmp_videoid_list = [];
|
2023-09-02 17:27:05 +00:00
|
|
|
playlist_api_json.videos.forEach(videodata => tmp_videoid_list.push(videodata.videoId));
|
2023-09-02 17:17:14 +00:00
|
|
|
return tmp_videoid_list;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
return [];
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
2023-09-02 17:17:14 +00:00
|
|
|
async Player(element, options) {
|
2023-09-03 15:43:39 +00:00
|
|
|
this.eventElement = document.createElement("span");
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_status = -1;
|
|
|
|
this.error_code = 0;
|
2023-08-25 15:48:41 +00:00
|
|
|
this.volume = 100;
|
2023-08-29 15:52:58 +00:00
|
|
|
this.eventobject = { ready: [], ended: [], error: [], ratechange: [], volumechange: [], waiting: [], timeupdate: [], loadedmetadata: [], play: [], seeking: [], seeked: [], playerresize: [], pause: [], statechange: [] };
|
|
|
|
let replace_elemnt;
|
|
|
|
if (element === undefined || element === null) {
|
2023-08-28 22:56:52 +00:00
|
|
|
throw 'Please, pass element id or HTMLElement as first argument';
|
2023-09-02 17:27:05 +00:00
|
|
|
} else if (typeof element === 'string') {
|
2023-08-18 02:40:50 +00:00
|
|
|
replace_elemnt = document.getElementById(element);
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
replace_elemnt = element;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
let iframe_src = '';
|
|
|
|
if (options.host !== undefined && options.host !== "") {
|
2023-08-18 02:40:50 +00:00
|
|
|
iframe_src = new URL(options.host).origin;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else if (invidious_embed.invidious_instance !== '') {
|
2023-08-29 15:52:58 +00:00
|
|
|
iframe_src = invidious_embed.invidious_instance;
|
|
|
|
}
|
2023-09-02 17:17:14 +00:00
|
|
|
if (!await this.instance_access_check(iframe_src)) {
|
|
|
|
await this.auto_instance_select();
|
|
|
|
iframe_src = invidious_embed.invidious_instance;
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-09-02 17:17:14 +00:00
|
|
|
invidious_embed.invidious_instance = iframe_src;
|
|
|
|
this.target_origin = iframe_src;
|
2023-08-18 02:40:50 +00:00
|
|
|
iframe_src += '/embed/';
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof options.videoId === 'string' && options.videoId.length === 11) {
|
2023-08-18 02:40:50 +00:00
|
|
|
iframe_src += options.videoId;
|
|
|
|
this.videoId = options.videoId;
|
2023-09-02 17:17:14 +00:00
|
|
|
if (!await this.videoid_accessable_check(options.videoId)) {
|
|
|
|
this.error_code = 100;
|
|
|
|
this.event_executor('error');
|
|
|
|
return;
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.error_code = 2;
|
|
|
|
this.event_executor('error');
|
2023-08-29 15:27:32 +00:00
|
|
|
return;
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
let search_params = new URLSearchParams('');
|
|
|
|
search_params.append('widgetid', invidious_embed.widgetid);
|
2023-08-18 02:40:50 +00:00
|
|
|
this.widgetid = invidious_embed.widgetid;
|
|
|
|
invidious_embed.widgetid++;
|
2023-08-29 15:52:58 +00:00
|
|
|
search_params.append('origin', location.origin);
|
|
|
|
search_params.append('enablejsapi', '1');
|
|
|
|
if (typeof options.playerVars === 'object') {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.option_playerVars = options.playerVars;
|
2023-08-29 15:52:58 +00:00
|
|
|
for (let x in options.playerVars) {
|
|
|
|
if (typeof x === 'string' && typeof options.playerVars[x] === 'string') {
|
|
|
|
search_params.append(x, options.playerVars[x]);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (options.playerVars.autoplay === undefined) {
|
|
|
|
search_params.append('autoplay', '0');
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
iframe_src += "?" + search_params.toString();
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof options.events === 'object') {
|
|
|
|
for (let x in options.events) {
|
|
|
|
this.addEventListener(x, options.events[x]);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
this.player_iframe = document.createElement("iframe");
|
|
|
|
this.loaded = false;
|
2023-09-02 17:17:14 +00:00
|
|
|
this.addEventListener('loadedmetadata', () => { this.event_executor('ready'); this.loaded = true; });
|
|
|
|
this.addEventListener('loadedmetadata', () => { this.setVolume(this.volume); });
|
|
|
|
this.addEventListener('loadedmetadata', async () => { const plid = await this.promise_send_event('getplaylistid'); (plid === null || plid === undefined) ? this.playlistVideoIds = [] : this.playlistVideoIds = await this.getPlaylistVideoids(plid); })
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_iframe.src = iframe_src;
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof options.width === 'number') {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_iframe.width = options.width;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-29 15:52:58 +00:00
|
|
|
if (document.body.clientWidth < 640) {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_iframe.width = document.body.clientWidth;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_iframe.width = 640;
|
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof options.width === 'number') {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_iframe.width = options.width;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-29 15:52:58 +00:00
|
|
|
this.player_iframe.height = this.player_iframe.width * (9 / 16);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
this.player_iframe.style.border = "none";
|
|
|
|
replace_elemnt.replaceWith(this.player_iframe);
|
|
|
|
this.eventdata = {};
|
|
|
|
return this;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
postMessage(data) {
|
|
|
|
const additionalInfo = { 'origin': location.origin, 'widgetid': this.widgetid.toString(), 'target': 'invidious_control' };
|
|
|
|
data = Object.assign(additionalInfo, data);
|
|
|
|
this.player_iframe.contentWindow.postMessage(data, this.target_origin);
|
|
|
|
}
|
|
|
|
|
|
|
|
event_executor(eventname) {
|
2023-09-03 15:43:39 +00:00
|
|
|
this.eventElement.dispatchEvent(new Event(eventname));
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
receiveMessage(message) {
|
|
|
|
if (message.data.from === 'invidious_control' && message.data.widgetid === String(this.widgetid)) {
|
|
|
|
switch (message.data.message_kind) {
|
2023-08-18 02:40:50 +00:00
|
|
|
case 'info_return':
|
2023-08-29 15:52:58 +00:00
|
|
|
const promise_array = this.message_wait[message.data.command];
|
|
|
|
promise_array.forEach(element => {
|
|
|
|
if (message.data.command === 'getvolume') {
|
|
|
|
element(message.data.value * 100);
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-29 15:52:58 +00:00
|
|
|
element(message.data.value);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
});
|
2023-08-18 02:40:50 +00:00
|
|
|
this.message_wait[message.data.command] = [];
|
|
|
|
break;
|
|
|
|
case 'event':
|
2023-08-29 15:26:20 +00:00
|
|
|
if (typeof message.data.eventname === 'string') {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.event_executor(message.data.eventname);
|
2023-08-29 15:52:58 +00:00
|
|
|
const previous_status = this.player_status;
|
|
|
|
switch (message.data.eventname) {
|
2023-08-18 02:40:50 +00:00
|
|
|
case 'ended':
|
|
|
|
this.player_status = 0;
|
|
|
|
break;
|
|
|
|
case 'play':
|
|
|
|
this.player_status = 1;
|
|
|
|
break;
|
|
|
|
case 'timeupdate':
|
|
|
|
this.player_status = 1;
|
2023-08-29 15:52:58 +00:00
|
|
|
this.eventdata = Object.assign({}, this.eventdata, message.data.value);
|
2023-08-18 02:40:50 +00:00
|
|
|
break;
|
|
|
|
case 'pause':
|
|
|
|
this.player_status = 2;
|
|
|
|
break;
|
|
|
|
case 'waiting':
|
|
|
|
this.player_status = 3;
|
|
|
|
break;
|
|
|
|
case 'loadedmetadata':
|
2023-08-29 15:52:58 +00:00
|
|
|
this.eventdata = Object.assign({}, this.eventdata, message.data.value);
|
2023-08-18 02:40:50 +00:00
|
|
|
break;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (previous_status !== this.player_status) {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.event_executor('statechange');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
promise_send_event(event_name) {
|
|
|
|
if (invidious_embed.api_promise) {
|
|
|
|
const promise_object = new Promise((resolve, reject) => { this.message_wait[event_name].push(resolve) });
|
|
|
|
this.postMessage({ eventname: event_name });
|
|
|
|
return promise_object;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.eventdata[event_name];
|
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getPlayerState() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.player_status;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
playVideo() {
|
|
|
|
this.postMessage({ eventname: 'play' });
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
pauseVideo() {
|
|
|
|
this.postMessage({ eventname: 'pause' });
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getVolume() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.promise_send_event('getvolume');
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
setVolume(volume) {
|
|
|
|
if (typeof volume === 'number') {
|
|
|
|
this.volume = volume;
|
2023-09-03 00:04:04 +00:00
|
|
|
if (volume !== NaN && volume >= 0 && volume <= 100) {
|
2023-08-29 15:52:58 +00:00
|
|
|
this.postMessage({ eventname: 'setvolume', value: volume / 100 });
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-29 15:52:58 +00:00
|
|
|
console.warn("setVolume first argument must be number");
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getIframe() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.player_iframe;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
destroy() {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_iframe.remove();
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
mute() {
|
|
|
|
this.postMessage({ eventname: 'setmutestatus', value: true });
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
unMute() {
|
|
|
|
this.postMessage({ eventname: 'setmutestatus', value: false });
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
isMuted() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.promise_send_event('getmutestatus');
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
seekTo(seconds, allowSeekAhead) {//seconds must be a number and allowSeekAhead is ignore
|
2023-09-02 17:17:14 +00:00
|
|
|
if (typeof seconds === 'number') {
|
|
|
|
if (seconds !== NaN && seconds !== undefined) {
|
|
|
|
this.postMessage({ eventname: 'seek', value: seconds });
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
console.warn('seekTo first argument type must be number')
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
setSize(width, height) {//width and height must be Number
|
2023-09-02 17:27:05 +00:00
|
|
|
if (typeof width === 'number' && typeof height === 'number') {
|
2023-09-02 17:17:14 +00:00
|
|
|
this.player_iframe.width = width;
|
|
|
|
this.player_iframe.height = height;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
console.warn('setSize first and secound argument type must be number');
|
|
|
|
}
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getPlaybackRate() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.promise_send_event('getplaybackrate');
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
setPlaybackRate(suggestedRate) {//suggestedRate must be number.this player allow not available playback rate such as 1.4
|
2023-09-02 17:27:05 +00:00
|
|
|
if (typeof suggestedRate === 'number') {
|
2023-09-02 17:17:14 +00:00
|
|
|
if (suggestedRate !== NaN) {
|
|
|
|
this.postMessage({ eventname: 'setplaybackrate', value: suggestedRate });
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
console.warn('setPlaybackRate first argument NaN is no valid');
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-09-02 17:17:14 +00:00
|
|
|
console.warn('setPlaybackRate first argument type must be number');
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getAvailablePlaybackRates() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.promise_send_event('getavailableplaybackrates');
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
2023-09-02 17:17:14 +00:00
|
|
|
async playOtherVideoById(option, autoplay, startSeconds_arg) {//internal fuction
|
2023-08-18 02:40:50 +00:00
|
|
|
let videoId = '';
|
2023-08-29 15:52:58 +00:00
|
|
|
let startSeconds = 0;
|
2023-08-18 02:40:50 +00:00
|
|
|
let endSeconds = -1;
|
|
|
|
let mediaContetUrl = '';
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof option === 'string') {
|
|
|
|
if (option.length === 11) {
|
2023-08-18 02:40:50 +00:00
|
|
|
videoId = option
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
mediaContetUrl = option;
|
|
|
|
}
|
2023-08-29 15:26:20 +00:00
|
|
|
if (typeof startSeconds_arg === 'number') {
|
2023-08-18 02:40:50 +00:00
|
|
|
startSeconds = startSeconds_arg;
|
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else if (typeof option === 'object') {
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof option.videoId === 'string') {
|
|
|
|
if (option.videoId.length == 11) {
|
2023-08-18 02:40:50 +00:00
|
|
|
videoId = option.videoId;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.error_code = 2;
|
|
|
|
this.event_executor('error');
|
2023-08-29 15:52:58 +00:00
|
|
|
return;
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-09-02 17:27:05 +00:00
|
|
|
} else if (typeof option.mediaContentUrl === 'string') {
|
2023-08-18 02:40:50 +00:00
|
|
|
mediaContetUrl = option.mediaContentUrl;
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.error_code = 2;
|
|
|
|
this.event_executor('error');
|
2023-08-29 15:52:58 +00:00
|
|
|
return;
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof option.startSeconds === 'number' && option.startSeconds >= 0) {
|
2023-08-18 02:40:50 +00:00
|
|
|
startSeconds = option.startSeconds;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (typeof option.endSeconds === 'number' && option.endSeconds >= 0) {
|
2023-08-25 15:48:41 +00:00
|
|
|
endSeconds = option.endSeconds;
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (mediaContetUrl.length > 0) {
|
2023-09-02 17:17:14 +00:00
|
|
|
const match_result = mediaContetUrl.match(/\/([A-Za-z0-9]{11})\//);
|
2023-09-02 17:27:05 +00:00
|
|
|
if (match_result !== null && match_result.length === 2) {
|
2023-09-02 17:17:14 +00:00
|
|
|
videoId = match_result[1];
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.error_code = 2;
|
|
|
|
this.event_executor('error');
|
2023-08-29 15:52:58 +00:00
|
|
|
return;
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
let iframe_sorce = this.target_origin.slice();
|
2023-08-18 02:40:50 +00:00
|
|
|
iframe_sorce += "/embed/" + videoId;
|
|
|
|
this.videoId = videoId;
|
2023-09-02 17:17:14 +00:00
|
|
|
if (!await this.videoid_accessable_check(videoId)) {
|
|
|
|
this.error_code = 100;
|
|
|
|
this.event_executor('error');
|
|
|
|
return;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
let search_params = new URLSearchParams('');
|
|
|
|
search_params.append('origin', location.origin);
|
|
|
|
search_params.append('enablejsapi', '1');
|
|
|
|
search_params.append('widgetid', invidious_embed.widgetid);
|
2023-08-18 02:40:50 +00:00
|
|
|
this.widgetid = invidious_embed.widgetid;
|
|
|
|
invidious_embed.widgetid++;
|
2023-08-29 15:40:03 +00:00
|
|
|
search_params.append('autoplay', Number(autoplay));
|
2023-08-29 15:52:58 +00:00
|
|
|
if (this.option_playerVars !== undefined) {
|
|
|
|
Object.keys(this.option_playerVars).forEach(key => {
|
|
|
|
if (key !== 'autoplay' && key !== 'start' && key !== 'end') {
|
|
|
|
search_params.append(key, this.option_playerVars[key]);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
})
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (startSeconds > 0) {
|
|
|
|
search_params.append('start', startSeconds);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
if (endSeconds !== -1 && endSeconds >= 0) {
|
|
|
|
if (endSeconds > startSeconds) {
|
|
|
|
search_params.append('end', endSeconds);
|
2023-09-02 17:27:05 +00:00
|
|
|
} else {
|
2023-08-29 15:52:58 +00:00
|
|
|
throw 'Invalid end seconds because end seconds before start seconds';
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
iframe_sorce += "?" + search_params.toString();
|
|
|
|
this.player_iframe.src = iframe_sorce;
|
2023-08-29 15:52:58 +00:00
|
|
|
if (autoplay) {
|
2023-08-18 02:40:50 +00:00
|
|
|
this.player_status = 5;
|
|
|
|
}
|
|
|
|
this.eventdata = {};
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
loadVideoById(option, startSeconds) {
|
|
|
|
this.playOtherVideoById(option, true, startSeconds);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
cueVideoById(option, startSeconds) {
|
|
|
|
this.playOtherVideoById(option, false, startSeconds);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
cueVideoByUrl(option, startSeconds) {
|
|
|
|
this.playOtherVideoById(option, false, startSeconds);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
loadVideoByUrl(option, startSeconds) {
|
|
|
|
this.playOtherVideoById(option, true, startSeconds);
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getDuration() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.promise_send_event('getduration');
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getVideoUrl() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.target_origin + "/watch?v=" + this.videoId;
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
async getVideoEmbedCode() {
|
2023-09-02 17:17:14 +00:00
|
|
|
const title = await this.getVideoTitle();
|
2023-08-29 15:52:58 +00:00
|
|
|
return '<iframe width="560" height="315" src="' + this.target_origin + '/embed/' + this.videoId + '" title="' + title.replace('"', "'") + '" frameborder="0" allow="autoplay;encrypted-media;picture-in-picture;web-share" allowfullscreen></iframe>';
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
|
|
|
getCurrentTime() {
|
2023-08-18 02:40:50 +00:00
|
|
|
return this.promise_send_event('getcurrenttime');
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
|
2023-09-02 17:17:14 +00:00
|
|
|
async getVideoData() {
|
2023-09-02 17:27:05 +00:00
|
|
|
return { video_id: this.videoId, title: await this.promise_send_event('gettitle'), list: this.promise_send_event('getplaylistid') };
|
2023-09-02 17:17:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getPlaylistIndex() {
|
|
|
|
return this.promise_send_event('getplaylistindex');
|
|
|
|
}
|
|
|
|
|
|
|
|
getPlaylist() {
|
|
|
|
return this.playlistVideoIds !== undefined ? this.playlistVideoIds : [];
|
|
|
|
}
|
|
|
|
|
2023-08-29 15:52:58 +00:00
|
|
|
constructor(element, options) {
|
|
|
|
this.Player(element, options);
|
|
|
|
window.addEventListener('message', (ms) => { this.receiveMessage(ms) });
|
|
|
|
this.message_wait = { getvolume: [], getmutestatus: [], getduration: [], getcurrenttime: [], getplaybackrate: [], getavailableplaybackrates: [], gettitle: [] };
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
function invidious_ready(func) {
|
|
|
|
if (typeof func === 'function') {
|
2023-08-18 02:40:50 +00:00
|
|
|
func();
|
|
|
|
}
|
2023-09-02 17:17:14 +00:00
|
|
|
else {
|
|
|
|
console.warn('invidious.ready first argument must be function');
|
|
|
|
}
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-08-29 15:52:58 +00:00
|
|
|
invidious_embed.invidious_instance = new URL(document.currentScript.src).origin;
|
|
|
|
const invidious = { Player: invidious_embed, PlayerState: { ENDED: 0, PLAYING: 1, PAUSED: 2, BUFFERING: 3, CUED: 5 }, ready: invidious_ready };
|
2023-09-02 17:27:05 +00:00
|
|
|
if (typeof onInvidiousIframeAPIReady === 'function') {
|
2023-09-03 00:04:04 +00:00
|
|
|
try{
|
|
|
|
onInvidiousIframeAPIReady();
|
|
|
|
} catch(e) {
|
|
|
|
console.error(e);
|
|
|
|
}
|
2023-08-18 02:40:50 +00:00
|
|
|
}
|
2023-09-03 15:43:39 +00:00
|
|
|
|
|
|
|
const YT = invidious;
|