mirror of
https://github.com/iv-org/invidious.git
synced 2025-05-31 14:11:54 +05:30
Compare commits
22 Commits
limit-feed
...
b1a1e5230d
Author | SHA1 | Date | |
---|---|---|---|
|
b1a1e5230d | ||
|
ffb7b7446e | ||
|
74bf3bc8b2 | ||
|
96439bc15c | ||
|
bd35a5a149 | ||
|
cb27c6a33a | ||
|
1d67e13d9c | ||
|
6a1beeb789 | ||
|
2134dd89d8 | ||
|
8239d1da5d | ||
|
26f9e8bf0d | ||
|
37cd696a46 | ||
|
4bb9a618be | ||
|
024246d1b3 | ||
|
e9faeb793b | ||
|
bfba48af81 | ||
|
2ae3b3e2e4 | ||
|
fc49ab285e | ||
|
54c90bae48 | ||
|
a9820eee5e | ||
|
d6b34a4057 | ||
|
39147309da |
@@ -62,3 +62,127 @@ addEventListener('load', function (e) {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function return_message(message, target_window) {
|
||||
if (target_window === undefined) {
|
||||
target_window = window.parent;
|
||||
}
|
||||
let url_params = new URLSearchParams(location.search);
|
||||
let widgetid = url_params.get('widgetid');
|
||||
let additional_info = { from: 'invidious_control' };
|
||||
if (widgetid !== null) {
|
||||
additional_info.widgetid = widgetid;
|
||||
}
|
||||
if (message.message_kind === 'event') {
|
||||
if (message.eventname === 'timeupdate' || message.eventname === 'loadedmetadata') {
|
||||
additional_info['value'] = { getvolume: player.volume(), getduration: player.duration(), getcurrenttime: player.currentTime(), getplaystatus: player.paused(), getplaybackrate: player.playbackRate(), getloopstatus: player.loop(), getmutestatus: player.muted(), getfullscreenstatus: player.isFullscreen(), getavailableplaybackrates: options.playbackRates, gettitle: player_data.title, getplaylistindex: video_data.index, getplaylistid: video_data.plid };
|
||||
}
|
||||
}
|
||||
if (message.eventname === 'error') {
|
||||
additional_info['value'] = { geterrorcode: player.error().code };
|
||||
}
|
||||
message = Object.assign(additional_info, message);
|
||||
let target_origin = url_params.get('origin') || '*';
|
||||
target_window.postMessage(message, target_origin);
|
||||
}
|
||||
|
||||
function control_embed_iframe(message) {
|
||||
const url_params = new URLSearchParams(location.search);
|
||||
const origin = url_params.get('origin');
|
||||
const origin_equal = origin === null || origin === message.origin;
|
||||
if (origin_equal) {
|
||||
const widgetid = url_params.get('widgetid');
|
||||
const widgetid_equal = widgetid === message.data.widgetid;
|
||||
const target_name_equal = message.data.target === 'invidious_control';
|
||||
const eventname_string_check = typeof message.data.eventname === 'string';
|
||||
if (widgetid_equal && target_name_equal && eventname_string_check) {
|
||||
let message_return_value;
|
||||
switch (message.data.eventname) {
|
||||
case 'play':
|
||||
player.play();
|
||||
break;
|
||||
case 'pause':
|
||||
player.pause();
|
||||
break;
|
||||
|
||||
case 'setvolume':
|
||||
player.volume(message.data.value);
|
||||
break;
|
||||
case 'seek':
|
||||
const duration = player.duration();
|
||||
let newTime = helpers.clamp(message.data.value, 0, duration);
|
||||
if (player.paused() && player.currentTime() === 0) {
|
||||
player.play();
|
||||
}
|
||||
player.currentTime(newTime);
|
||||
break;
|
||||
case 'setplaybackrate':
|
||||
player.playbackRate(message.data.value);
|
||||
break;
|
||||
case 'setloopstatus':
|
||||
player.loop(message.data.value);
|
||||
break;
|
||||
case 'requestfullscreen':
|
||||
player.requestFullscreen();
|
||||
break;
|
||||
case 'exitfullscreen':
|
||||
player.exitFullscreen();
|
||||
break;
|
||||
|
||||
case 'getvolume':
|
||||
message_return_value = player.volume();
|
||||
break;
|
||||
case 'getduration':
|
||||
message_return_value = player.duration();
|
||||
break;
|
||||
case 'getcurrenttime':
|
||||
message_return_value = player.currentTime();
|
||||
break;
|
||||
case 'getplaystatus':
|
||||
message_return_value = player.paused();
|
||||
break;
|
||||
case 'getplaybackrate':
|
||||
message_return_value = player.playbackRate();
|
||||
break;
|
||||
case 'getavailableplaybackrates':
|
||||
message_return_value = options.playbackRates;
|
||||
break;
|
||||
case 'getloopstatus':
|
||||
message_return_value = player.loop();
|
||||
break;
|
||||
case 'getmutestatus':
|
||||
message_return_value = player.muted();
|
||||
break;
|
||||
case 'gettitle':
|
||||
message_return_value = player_data.title;
|
||||
break;
|
||||
case 'getfullscreenstatus':
|
||||
message_return_value = player.isFullscreen();
|
||||
break;
|
||||
case 'geterrorcode':
|
||||
message_return_value = player.error().code;
|
||||
break;
|
||||
case 'getplaylistindex':
|
||||
message_return_value = video_data.index;
|
||||
break;
|
||||
case 'getplaylistid':
|
||||
message_return_value = video_data.plid;
|
||||
break;
|
||||
default:
|
||||
console.info("Unhandled event name: " + message.data.eventname);
|
||||
break;
|
||||
}
|
||||
if (message_return_value !== undefined) {
|
||||
return_message({ command: message.data.eventname, value: message_return_value, message_kind: 'info_return' }, message.source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (new URLSearchParams(location.search).get('enablejsapi') === '1') {
|
||||
window.addEventListener('message', control_embed_iframe);
|
||||
const event_list = ['ended', 'error', 'ratechange', 'volumechange', 'waiting', 'timeupdate', 'loadedmetadata', 'play', 'seeking', 'seeked', 'playerresize', 'pause'];
|
||||
event_list.forEach(event_name => {
|
||||
player.on(event_name, function () { return_message({ message_kind: 'event', eventname: event_name }) });
|
||||
});
|
||||
}
|
||||
|
667
assets/js/invidious_iframe_api.js
Normal file
667
assets/js/invidious_iframe_api.js
Normal file
@@ -0,0 +1,667 @@
|
||||
class invidious_embed {
|
||||
static widgetid = 0;
|
||||
static eventname_table = { onPlaybackRateChange: 'ratechange', onStateChange: 'statechange', onError: 'error', onReady: 'ready' };
|
||||
static available_event_name = ['ready', 'ended', 'error', 'ratechange', 'volumechange', 'waiting', 'timeupdate', 'loadedmetadata', 'play', 'seeking', 'seeked', 'playerresize', 'pause'];
|
||||
static api_promise = false;
|
||||
static invidious_instance = '';
|
||||
static api_instance_list = [];
|
||||
static instance_status_list = {};
|
||||
static videodata_cahce = {};
|
||||
|
||||
addEventListener(eventname, func) {
|
||||
if (eventname in invidious_embed.eventname_table) {
|
||||
eventname = invidious_embed.eventname_table[eventname];
|
||||
}
|
||||
this.eventElement.addEventListener(eventname,func);
|
||||
}
|
||||
|
||||
removeEventListener(eventname, func) {
|
||||
if (eventname in invidious_embed.eventname_table) {
|
||||
eventname = invidious_embed.eventname_table[eventname];
|
||||
}
|
||||
this.eventElement.removeEventListener(eventname,func);
|
||||
}
|
||||
|
||||
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) {
|
||||
try {
|
||||
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;
|
||||
} else {
|
||||
return_status = false;
|
||||
}
|
||||
} else {
|
||||
return_status = false;
|
||||
}
|
||||
} catch {
|
||||
return_status = false;
|
||||
}
|
||||
invidious_embed.instance_status_list[instance_origin] = return_status;
|
||||
return return_status;
|
||||
} else {
|
||||
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']);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async auto_instance_select() {
|
||||
if (await this.instance_access_check(invidious_embed.invidious_instance)) {
|
||||
return;
|
||||
} else {
|
||||
if (invidious_embed.api_instance_list.length === 0) {
|
||||
await this.get_instance_list();
|
||||
}
|
||||
for (let x = 0; x < invidious_embed.api_instance_list.length; x++) {
|
||||
if (await this.instance_access_check(invidious_embed.api_instance_list[x])) {
|
||||
invidious_embed.invidious_instance = invidious_embed.api_instance_list[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async videodata_api(videoid) {
|
||||
const not_in_videodata_cahce = !(videoid in invidious_embed.videodata_cahce);
|
||||
if (not_in_videodata_cahce) {
|
||||
const video_api_response = await fetch(invidious_embed.invidious_instance + "/api/v1/videos/" + videoid + "?fields=title,videoId,paid,premium,isFamilyFriendly,isListed,liveNow");
|
||||
if (video_api_response.ok) {
|
||||
invidious_embed.videodata_cahce[videoid] = Object.assign({},{status:true},await video_api_response.json());
|
||||
} else {
|
||||
invidious_embed.videodata_cahce[videoid] = {status:false};
|
||||
}
|
||||
}
|
||||
return invidious_embed.videodata_cahce[videoid];
|
||||
}
|
||||
|
||||
async videoid_accessable_check(videoid) {
|
||||
return (await this.videodata_api(videoid)).status;
|
||||
}
|
||||
|
||||
async getPlaylistVideoids(playlistid) {
|
||||
const playlist_api_response = await fetch(invidious_embed.invidious_instance + "/api/v1/playlists/" + playlistid);
|
||||
if (playlist_api_response.ok) {
|
||||
const playlist_api_json = await playlist_api_response.json();
|
||||
let tmp_videoid_list = [];
|
||||
playlist_api_json.videos.forEach(videodata => tmp_videoid_list.push(videodata.videoId));
|
||||
return tmp_videoid_list;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async Player(element, options) {
|
||||
this.eventElement = document.createElement("span");
|
||||
this.player_status = -1;
|
||||
this.error_code = 0;
|
||||
this.volume = 100;
|
||||
this.loop = false;
|
||||
this.playlistVideoIds = [];
|
||||
this.eventobject = { ready: [], ended: [], error: [], ratechange: [], volumechange: [], waiting: [], timeupdate: [], loadedmetadata: [], play: [], seeking: [], seeked: [], playerresize: [], pause: [], statechange: [] };
|
||||
let replace_elemnt;
|
||||
if (element === undefined || element === null) {
|
||||
throw 'Please, pass element id or HTMLElement as first argument';
|
||||
} else if (typeof element === 'string') {
|
||||
replace_elemnt = document.getElementById(element);
|
||||
} else {
|
||||
replace_elemnt = element;
|
||||
}
|
||||
let iframe_src = '';
|
||||
if (options.host !== undefined && options.host !== "") {
|
||||
iframe_src = new URL(options.host).origin;
|
||||
} else if (invidious_embed.invidious_instance !== '') {
|
||||
iframe_src = invidious_embed.invidious_instance;
|
||||
}
|
||||
if (!await this.instance_access_check(iframe_src)) {
|
||||
await this.auto_instance_select();
|
||||
iframe_src = invidious_embed.invidious_instance;
|
||||
}
|
||||
invidious_embed.invidious_instance = iframe_src;
|
||||
this.target_origin = iframe_src;
|
||||
iframe_src += '/embed/';
|
||||
if (typeof options.videoId === 'string' && options.videoId.length === 11) {
|
||||
iframe_src += options.videoId;
|
||||
this.videoId = options.videoId;
|
||||
if (!await this.videoid_accessable_check(options.videoId)) {
|
||||
this.error_code = 100;
|
||||
this.event_executor('error');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
this.error_code = 2;
|
||||
this.event_executor('error');
|
||||
return;
|
||||
}
|
||||
let search_params = new URLSearchParams('');
|
||||
search_params.append('widgetid', invidious_embed.widgetid);
|
||||
this.widgetid = invidious_embed.widgetid;
|
||||
invidious_embed.widgetid++;
|
||||
search_params.append('origin', location.origin);
|
||||
search_params.append('enablejsapi', '1');
|
||||
let no_start_parameter = true;
|
||||
if (typeof options.playerVars === 'object') {
|
||||
this.option_playerVars = options.playerVars;
|
||||
Object.keys(options.playerVars).forEach(key=>{
|
||||
if (typeof key === 'string') {
|
||||
let keyValue = options.playerVars[key];
|
||||
switch (typeof keyValue) {
|
||||
case 'number':
|
||||
keyValue = keyValue.toString();
|
||||
break;
|
||||
case 'string':
|
||||
break;
|
||||
default :
|
||||
console.warn('player vars key value must be string or number');
|
||||
}
|
||||
search_params.append(key, keyValue);
|
||||
} else {
|
||||
console.warn('player vars key must be string');
|
||||
}
|
||||
})
|
||||
if (options.playerVars.start !== undefined) {
|
||||
no_start_parameter = false;
|
||||
}
|
||||
if (options.playerVars.autoplay === undefined) {
|
||||
search_params.append('autoplay', '0');
|
||||
}
|
||||
} else {
|
||||
search_params.append('autoplay', '0');
|
||||
}
|
||||
if (no_start_parameter) {
|
||||
search_params.append('start', '0');
|
||||
}
|
||||
iframe_src += "?" + search_params.toString();
|
||||
if (typeof options.events === 'object') {
|
||||
for (let x in options.events) {
|
||||
this.addEventListener(x, options.events[x]);
|
||||
}
|
||||
}
|
||||
this.player_iframe = document.createElement("iframe");
|
||||
this.loaded = false;
|
||||
this.addEventListener('loadedmetadata', () => { this.event_executor('ready'); this.loaded = true; });
|
||||
this.addEventListener('loadedmetadata', () => { this.setVolume(this.volume); });
|
||||
this.player_iframe.src = iframe_src;
|
||||
if (typeof options.width === 'number') {
|
||||
this.player_iframe.width = options.width;
|
||||
} else {
|
||||
this.player_iframe.width = 640;
|
||||
this.player_iframe.style.maxWidth = '100%';
|
||||
}
|
||||
if (typeof options.width === 'number') {
|
||||
this.player_iframe.width = options.width;
|
||||
} else {
|
||||
this.player_iframe.height = this.player_iframe.width * (9 / 16);
|
||||
}
|
||||
this.player_iframe.style.border = "none";
|
||||
replace_elemnt.replaceWith(this.player_iframe);
|
||||
this.eventdata = {};
|
||||
return this;
|
||||
}
|
||||
|
||||
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) {
|
||||
let event_parameter = {detail:undefined};
|
||||
if (eventname === 'statechange') {
|
||||
event_parameter.detail = this.getPlayerState();
|
||||
} else if (eventname === 'error'){
|
||||
event_parameter.detail = this.error_code;
|
||||
}
|
||||
this.eventElement.dispatchEvent(new Event(eventname,event_parameter));
|
||||
}
|
||||
|
||||
receiveMessage(message) {
|
||||
const onControlAndHasWidgetId = message.data.from==='invidious_control' && message.data.widgetid===this.widgetid.toString();
|
||||
if (onControlAndHasWidgetId) {
|
||||
switch (message.data.message_kind) {
|
||||
case 'info_return':
|
||||
const promise_array = this.message_wait[message.data.command];
|
||||
promise_array.forEach(element => {
|
||||
if (message.data.command === 'getvolume') {
|
||||
element(message.data.value * 100);
|
||||
} else {
|
||||
element(message.data.value);
|
||||
}
|
||||
});
|
||||
this.message_wait[message.data.command] = [];
|
||||
break;
|
||||
case 'event':
|
||||
if (typeof message.data.eventname === 'string') {
|
||||
this.event_executor(message.data.eventname);
|
||||
const previous_status = this.player_status;
|
||||
switch (message.data.eventname) {
|
||||
case 'ended':
|
||||
this.player_status = 0;
|
||||
break;
|
||||
case 'play':
|
||||
this.player_status = 1;
|
||||
break;
|
||||
case 'timeupdate':
|
||||
this.player_status = 1;
|
||||
this.eventdata = Object.assign({}, this.eventdata, message.data.value);
|
||||
break;
|
||||
case 'pause':
|
||||
this.player_status = 2;
|
||||
break;
|
||||
case 'waiting':
|
||||
this.player_status = 3;
|
||||
break;
|
||||
case 'loadedmetadata':
|
||||
this.eventdata = Object.assign({}, this.eventdata, message.data.value);
|
||||
break;
|
||||
}
|
||||
if (previous_status !== this.player_status) {
|
||||
this.event_executor('statechange');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
} else {
|
||||
return this.eventdata[event_name];
|
||||
}
|
||||
}
|
||||
|
||||
getPlayerState() {
|
||||
return this.player_status;
|
||||
}
|
||||
|
||||
playVideo() {
|
||||
this.postMessage({ eventname: 'play' });
|
||||
}
|
||||
|
||||
pauseVideo() {
|
||||
this.postMessage({ eventname: 'pause' });
|
||||
}
|
||||
|
||||
getVolume() {
|
||||
return this.promise_send_event('getvolume');
|
||||
}
|
||||
|
||||
setVolume(volume) {
|
||||
if (typeof volume === 'number') {
|
||||
this.volume = volume;
|
||||
if (volume !== NaN && volume >= 0 && volume <= 100) {
|
||||
this.postMessage({ eventname: 'setvolume', value: volume / 100 });
|
||||
}
|
||||
} else {
|
||||
console.warn("setVolume first argument must be number");
|
||||
}
|
||||
}
|
||||
|
||||
getIframe() {
|
||||
return this.player_iframe;
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.player_iframe.remove();
|
||||
}
|
||||
|
||||
mute() {
|
||||
this.postMessage({ eventname: 'setmutestatus', value: true });
|
||||
}
|
||||
|
||||
unMute() {
|
||||
this.postMessage({ eventname: 'setmutestatus', value: false });
|
||||
}
|
||||
|
||||
isMuted() {
|
||||
return this.promise_send_event('getmutestatus');
|
||||
}
|
||||
|
||||
async seekTo(seconds, allowSeekAhead) {//seconds must be a number and allowSeekAhead is ignore
|
||||
if (typeof seconds === 'number') {
|
||||
if (seconds !== NaN && seconds !== undefined) {
|
||||
this.postMessage({ eventname: 'seek', value: seconds });
|
||||
}
|
||||
} else {
|
||||
console.warn('seekTo first argument type must be number')
|
||||
}
|
||||
}
|
||||
|
||||
setSize(width, height) {//width and height must be Number
|
||||
if (typeof width === 'number' && typeof height === 'number') {
|
||||
this.player_iframe.width = width;
|
||||
this.player_iframe.height = height;
|
||||
} else {
|
||||
console.warn('setSize first and secound argument type must be number');
|
||||
}
|
||||
}
|
||||
|
||||
getPlaybackRate() {
|
||||
return this.promise_send_event('getplaybackrate');
|
||||
}
|
||||
|
||||
setPlaybackRate(suggestedRate) {//suggestedRate must be number.this player allow not available playback rate such as 1.4
|
||||
if (typeof suggestedRate === 'number') {
|
||||
if (suggestedRate !== NaN) {
|
||||
this.postMessage({ eventname: 'setplaybackrate', value: suggestedRate });
|
||||
} else {
|
||||
console.warn('setPlaybackRate first argument NaN is no valid');
|
||||
}
|
||||
} else {
|
||||
console.warn('setPlaybackRate first argument type must be number');
|
||||
}
|
||||
}
|
||||
|
||||
getAvailablePlaybackRates() {
|
||||
return this.promise_send_event('getavailableplaybackrates');
|
||||
}
|
||||
|
||||
async playOtherVideoById(option, autoplay, startSeconds_arg, additional_argument) {//internal fuction
|
||||
let videoId = '';
|
||||
let startSeconds = 0;
|
||||
let endSeconds = -1;
|
||||
let mediaContetUrl = '';
|
||||
if (typeof option === 'string') {
|
||||
if (option.length === 11) {
|
||||
videoId = option
|
||||
} else {
|
||||
mediaContetUrl = option;
|
||||
}
|
||||
if (typeof startSeconds_arg === 'number') {
|
||||
startSeconds = startSeconds_arg;
|
||||
}
|
||||
} else if (typeof option === 'object') {
|
||||
if (typeof option.videoId === 'string') {
|
||||
if (option.videoId.length == 11) {
|
||||
videoId = option.videoId;
|
||||
} else {
|
||||
this.error_code = 2;
|
||||
this.event_executor('error');
|
||||
return;
|
||||
}
|
||||
} else if (typeof option.mediaContentUrl === 'string') {
|
||||
mediaContetUrl = option.mediaContentUrl;
|
||||
} else {
|
||||
this.error_code = 2;
|
||||
this.event_executor('error');
|
||||
return;
|
||||
}
|
||||
if (typeof option.startSeconds === 'number' && option.startSeconds >= 0) {
|
||||
startSeconds = option.startSeconds;
|
||||
}
|
||||
if (typeof option.endSeconds === 'number' && option.endSeconds >= 0) {
|
||||
endSeconds = option.endSeconds;
|
||||
}
|
||||
}
|
||||
if (mediaContetUrl.length > 0) {
|
||||
const match_result = mediaContetUrl.match(/\/([A-Za-z0-9]{11})\//);
|
||||
if (match_result !== null && match_result.length === 2) {
|
||||
videoId = match_result[1];
|
||||
} else {
|
||||
this.error_code = 2;
|
||||
this.event_executor('error');
|
||||
return;
|
||||
}
|
||||
}
|
||||
let iframe_sorce = this.target_origin.slice();
|
||||
iframe_sorce += "/embed/" + videoId;
|
||||
this.videoId = videoId;
|
||||
if (!await this.videoid_accessable_check(videoId)) {
|
||||
this.error_code = 100;
|
||||
this.event_executor('error');
|
||||
return;
|
||||
}
|
||||
let search_params = new URLSearchParams('');
|
||||
search_params.append('origin', location.origin);
|
||||
search_params.append('enablejsapi', '1');
|
||||
search_params.append('widgetid', invidious_embed.widgetid);
|
||||
this.widgetid = invidious_embed.widgetid;
|
||||
invidious_embed.widgetid++;
|
||||
search_params.append('autoplay', Number(autoplay));
|
||||
if (this.option_playerVars !== undefined) {
|
||||
const ignore_keys = ['autoplay', 'start', 'end', 'index', 'list'];
|
||||
Object.keys(this.option_playerVars).forEach(key => {
|
||||
if (!ignore_keys.includes(key)) {
|
||||
search_params.append(key, this.option_playerVars[key]);
|
||||
}
|
||||
})
|
||||
}
|
||||
if (typeof additional_argument === 'object') {
|
||||
const ignore_keys = ['autoplay', 'start', 'end'];
|
||||
Object.keys(additional_argument).forEach(key => {
|
||||
if (!ignore_keys.includes(key)) {
|
||||
search_params.append(key, additional_argument[key]);
|
||||
}
|
||||
})
|
||||
}
|
||||
search_params.append('start', startSeconds);
|
||||
if (endSeconds !== -1 && endSeconds >= 0) {
|
||||
if (endSeconds > startSeconds) {
|
||||
search_params.append('end', endSeconds);
|
||||
} else {
|
||||
throw 'Invalid end seconds because end seconds before start seconds';
|
||||
}
|
||||
}
|
||||
iframe_sorce += "?" + search_params.toString();
|
||||
this.player_iframe.src = iframe_sorce;
|
||||
if (autoplay) {
|
||||
this.player_status = 5;
|
||||
}
|
||||
this.eventdata = {};
|
||||
}
|
||||
|
||||
loadVideoById(option, startSeconds) {
|
||||
this.playOtherVideoById(option, true, startSeconds, {});
|
||||
}
|
||||
|
||||
cueVideoById(option, startSeconds) {
|
||||
this.playOtherVideoById(option, false, startSeconds, {});
|
||||
}
|
||||
|
||||
cueVideoByUrl(option, startSeconds) {
|
||||
this.playOtherVideoById(option, false, startSeconds, {});
|
||||
}
|
||||
|
||||
loadVideoByUrl(option, startSeconds) {
|
||||
this.playOtherVideoById(option, true, startSeconds, {});
|
||||
}
|
||||
|
||||
async playPlaylist(playlistData,autoplay,index,startSeconds) {
|
||||
let playlistId;
|
||||
if (typeof playlistData === 'string') {
|
||||
this.playlistVideoIds = await this.getPlaylistVideoids(playlistData);
|
||||
playlistId = playlistData;
|
||||
} else if (typeof playlistData === 'object') {
|
||||
if (Array.isArray(playlistData)) {
|
||||
this.playlistVideoIds = playlistData;
|
||||
} else {
|
||||
index = playlistData['index'];
|
||||
let listType = 'playlist';
|
||||
if (typeof playlistData['listType'] === 'string'){
|
||||
listType = playlistData['listType'];
|
||||
}
|
||||
switch (listType) {
|
||||
case 'playlist':
|
||||
if (Array.isArray(playlistData['list'])) {
|
||||
this.playlistVideoIds = playlistData['list'];
|
||||
} else if(typeof playlistData['list'] === 'string') {
|
||||
this.playlistVideoIds = await this.getPlaylistVideoids(playlistData['list']);
|
||||
playlistId = playlistData['list'];
|
||||
} else {
|
||||
console.error('playlist data list must be string or array of strings');
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 'user_uploads':
|
||||
console.warn('sorry user_uploads not support');
|
||||
return;
|
||||
default:
|
||||
console.error('listType : ' + listType + ' is unknown');
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.error('playlist function first argument must be string or array of string');
|
||||
return;
|
||||
}
|
||||
if (this.playlistVideoIds.length === 0){
|
||||
console.error('playlist length 0 is invalid');
|
||||
return;
|
||||
}
|
||||
let parameter = {index:0};
|
||||
if (typeof index === 'undefined') {
|
||||
index = 0;
|
||||
} else if (typeof index === 'number'){
|
||||
parameter.index = index;
|
||||
} else{
|
||||
console.error('index must be number of undefined');
|
||||
}
|
||||
if (typeof playlistId === 'string') {
|
||||
parameter['list'] = playlistId;
|
||||
this.playlistId = playlistId;
|
||||
}
|
||||
this.playOtherVideoById(this.playlistVideoIds[index],autoplay,startSeconds,parameter);
|
||||
}
|
||||
|
||||
cuePlaylist(data,index,startSeconds) {
|
||||
this.playPlaylist(data,false,index,startSeconds);
|
||||
}
|
||||
|
||||
loadPlaylist(data,index,startSeconds) {
|
||||
this.playPlaylist(data,true,index,startSeconds);
|
||||
}
|
||||
|
||||
playVideoAt(index) {
|
||||
if (typeof index === 'number') {
|
||||
let parameter = {index:index};
|
||||
if (this.playlistId !== undefined) {
|
||||
parameter['list'] = this.playlistId;
|
||||
}
|
||||
this.playOtherVideoById(this.playlistVideoIds[index],true,0,parameter);
|
||||
} else {
|
||||
console.error('playVideoAt first argument must be number');
|
||||
}
|
||||
}
|
||||
|
||||
async nextVideo() {
|
||||
let now_index = this.promise_send_event('getplaylistindex');
|
||||
if (now_index === this.playlistVideoIds.length -1) {
|
||||
if (this.loop) {
|
||||
now_index = 0;
|
||||
} else {
|
||||
console.log('end of playlist');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
now_index++;
|
||||
}
|
||||
let parameter = {index:now_index};
|
||||
if (this.playlistId !== undefined) {
|
||||
parameter['list'] = this.playlistId;
|
||||
}
|
||||
this.playOtherVideoById(this.playlistVideoIds[now_index],true,0,parameter);
|
||||
}
|
||||
|
||||
async previousVideo() {
|
||||
let now_index = this.promise_send_event('getplaylistindex');
|
||||
if (now_index === 0) {
|
||||
if (this.loop) {
|
||||
now_index = this.playlistVideoIds.length -1;
|
||||
} else {
|
||||
console.log('back to start of playlist');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
now_index--;
|
||||
}
|
||||
let parameter = {index:now_index};
|
||||
if (this.playlistId !== undefined) {
|
||||
parameter['list'] = this.playlistId;
|
||||
}
|
||||
this.playOtherVideoById(this.playlistVideoIds[now_index],true,0,parameter);
|
||||
}
|
||||
|
||||
getDuration() {
|
||||
return this.promise_send_event('getduration');
|
||||
}
|
||||
|
||||
getVideoUrl() {
|
||||
return this.target_origin + "/watch?v=" + this.videoId;
|
||||
}
|
||||
|
||||
async getVideoEmbedCode() {
|
||||
const title = await this.getVideoTitle();
|
||||
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>';
|
||||
}
|
||||
|
||||
getCurrentTime() {
|
||||
return this.promise_send_event('getcurrenttime');
|
||||
}
|
||||
|
||||
async getVideoData() {
|
||||
const videoData = await this.videodata_api(this.videoId);
|
||||
return { video_id: this.videoId, title: await this.promise_send_event('gettitle'), list: await this.promise_send_event('getplaylistid'), isListed:videoData.isListed, isLive:videoData.liveNow, isPremiere:videoData.premium};
|
||||
}
|
||||
|
||||
getPlaylistIndex() {
|
||||
return this.promise_send_event('getplaylistindex');
|
||||
}
|
||||
|
||||
getPlaylist() {
|
||||
return this.playlistVideoIds !== undefined ? this.playlistVideoIds : [];
|
||||
}
|
||||
|
||||
setLoop(loopStatus) {
|
||||
if (typeof loopStatus === 'boolean') {
|
||||
this.loop = loopStatus;
|
||||
} else {
|
||||
console.error('setLoop first argument must be bool');
|
||||
}
|
||||
}
|
||||
|
||||
constructor(element, options) {
|
||||
this.Player(element, options);
|
||||
window.addEventListener('message', (ms) => { this.receiveMessage(ms) });
|
||||
this.message_wait = { getvolume: [], getmutestatus: [], getduration: [], getcurrenttime: [], getplaybackrate: [], getavailableplaybackrates: [], gettitle: [] };
|
||||
}
|
||||
}
|
||||
|
||||
function invidious_ready(func) {
|
||||
if (typeof func === 'function') {
|
||||
func();
|
||||
}
|
||||
else {
|
||||
console.warn('invidious.ready first argument must be function');
|
||||
}
|
||||
}
|
||||
|
||||
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 };
|
||||
if (typeof onInvidiousIframeAPIReady === 'function') {
|
||||
try{
|
||||
onInvidiousIframeAPIReady();
|
||||
} catch(e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user