multi_embed_player 3.0.1 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +92 -0
- package/README.md +0 -24
- package/add_types.sh +61 -0
- package/dist/iframe_api/bilibili.d.ts +180 -61
- package/dist/iframe_api/bilibili.d.ts.map +1 -1
- package/dist/iframe_api/bilibili.js +938 -354
- package/dist/iframe_api/bilibili.js.map +1 -1
- package/dist/iframe_api/niconico.d.ts +177 -28
- package/dist/iframe_api/niconico.d.ts.map +1 -1
- package/dist/iframe_api/niconico.js +290 -146
- package/dist/iframe_api/niconico.js.map +1 -1
- package/dist/iframe_api/soundcloud.d.ts +132 -60
- package/dist/iframe_api/soundcloud.d.ts.map +1 -1
- package/dist/iframe_api/soundcloud.js +318 -146
- package/dist/iframe_api/soundcloud.js.map +1 -1
- package/dist/iframe_api/youtube.d.ts +32 -69
- package/dist/iframe_api/youtube.d.ts.map +1 -1
- package/dist/iframe_api/youtube.js +130 -139
- package/dist/iframe_api/youtube.js.map +1 -1
- package/dist/multi_embed_player.d.ts +193 -26
- package/dist/multi_embed_player.d.ts.map +1 -1
- package/dist/multi_embed_player.js +726 -123
- package/dist/multi_embed_player.js.map +1 -1
- package/package.json +10 -41
- package/dist/iframe_api/index.d.ts +0 -6
- package/dist/iframe_api/index.d.ts.map +0 -1
- package/dist/iframe_api/index.js +0 -8
- package/dist/iframe_api/index.js.map +0 -1
- package/dist/types.d.ts +0 -126
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -22
- package/dist/types.js.map +0 -1
|
@@ -1,6 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
4
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
5
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
6
|
+
};
|
|
7
|
+
var _multi_embed_player_instances, _multi_embed_player_check_image_status, _multi_embed_player_add_iframe, _multi_embed_player_mep_imageurl, _multi_embed_player_GDPR_accept, _multi_embed_player_error_event_handler, _multi_embed_player_setEvent, _multi_embed_player_deleteEvent, _multi_embed_player_PlayOnPlayer, _multi_embed_player_addPlaylist;
|
|
2
8
|
/**
|
|
3
9
|
* Fetches the iframe API for a given service and video ID.
|
|
10
|
+
* @param {string} service - The name of the service.
|
|
11
|
+
* @param {string} videoid - The ID of the video.
|
|
12
|
+
* @param {boolean} use_cors - Whether to use CORS.
|
|
13
|
+
* @param {boolean} image_proxy - The image proxy.
|
|
14
|
+
* @param {boolean} GDPR_access_accept - Whether GDPR access is accepted.
|
|
15
|
+
* @param {boolean} failed_send_error - Whether to send an error if the request fails.
|
|
16
|
+
* @param {HTMLElement} failed_send_error_target - The target to send the error to.
|
|
17
|
+
* @returns {Promise}
|
|
4
18
|
*/
|
|
5
19
|
const multi_embed_player_fetch_iframe_api = async (service, videoid, use_cors, image_proxy, GDPR_access_accept, failed_send_error = false, failed_send_error_target = null) => {
|
|
6
20
|
const xml_first_search = (data, search_string, start = 0) => {
|
|
@@ -19,19 +33,16 @@ const multi_embed_player_fetch_iframe_api = async (service, videoid, use_cors, i
|
|
|
19
33
|
url = `${multi_embed_player.iframe_api_endpoint}?route=url_proxy&url=`;
|
|
20
34
|
}
|
|
21
35
|
let first_access = false;
|
|
22
|
-
if (!multi_embed_player.api_promise[service]) {
|
|
23
|
-
multi_embed_player.api_promise[service] = {};
|
|
24
|
-
}
|
|
25
36
|
if (multi_embed_player.api_promise[service][videoid] === undefined) {
|
|
26
37
|
multi_embed_player.api_promise[service][videoid] = { res: [], rej: [] };
|
|
27
38
|
first_access = true;
|
|
28
39
|
}
|
|
29
40
|
else {
|
|
30
41
|
await new Promise((resolve, reject) => {
|
|
31
|
-
const
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
const promiseData = multi_embed_player.api_promise[service][videoid];
|
|
43
|
+
if (promiseData) {
|
|
44
|
+
promiseData.res.push(resolve);
|
|
45
|
+
promiseData.rej.push(reject);
|
|
35
46
|
}
|
|
36
47
|
});
|
|
37
48
|
}
|
|
@@ -48,43 +59,37 @@ const multi_embed_player_fetch_iframe_api = async (service, videoid, use_cors, i
|
|
|
48
59
|
url_oembed = `https://soundcloud.com/oembed?url=https://soundcloud.com/${videoid}&format=json`;
|
|
49
60
|
}
|
|
50
61
|
const oembed_response_fetch = await fetch(url + encodeURI(url_oembed));
|
|
51
|
-
|
|
62
|
+
let oembed_response = await oembed_response_fetch.json();
|
|
52
63
|
oembed_response["image_base64"] = url + oembed_response["thumbnail_url"];
|
|
53
64
|
multi_embed_player.api_cache[service][videoid] = oembed_response;
|
|
54
65
|
break;
|
|
55
66
|
case 'niconico':
|
|
56
67
|
const xml_response = await (await fetch(url + `https://ext.nicovideo.jp/api/getthumbinfo/${videoid}`)).text();
|
|
57
68
|
let image_url = xml_first_search(xml_response, "thumbnail_url");
|
|
58
|
-
|
|
59
|
-
|
|
69
|
+
let predict_long = 43 + 2 * (videoid.length - 2);
|
|
70
|
+
let return_data = {};
|
|
60
71
|
if (image_url.length > predict_long) {
|
|
61
72
|
image_url += ".L";
|
|
62
73
|
}
|
|
63
|
-
if (image_url
|
|
74
|
+
if (image_url == "<?xml version=") {
|
|
64
75
|
return_data["status"] = "invalid videoid";
|
|
65
76
|
return_data["thumbnail_url"] = "";
|
|
66
77
|
}
|
|
67
78
|
else {
|
|
68
79
|
return_data["status"] = "success";
|
|
69
80
|
return_data["thumbnail_url"] = image_url;
|
|
70
|
-
const search_element_names = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
mylist_counter: "mylist_count",
|
|
78
|
-
first_retrieve: "publish_time",
|
|
79
|
-
embeddable: "embedable",
|
|
80
|
-
genre: "genre"
|
|
81
|
-
};
|
|
82
|
-
Object.keys(search_element_names).forEach(key_name => return_data[search_element_names[key_name]] = xml_first_search(xml_response, key_name));
|
|
81
|
+
const search_element_names = { video_id: "video_id", title: "title", description: "description", length: "length", view_counter: "view_count", comment_num: "comment_count", mylist_counter: "mylist_count", first_retrieve: "publish_time", embeddable: "embedable", genre: "genre" };
|
|
82
|
+
Object.keys(search_element_names).forEach(key_name => {
|
|
83
|
+
const mappedKey = search_element_names[key_name];
|
|
84
|
+
if (mappedKey) {
|
|
85
|
+
return_data[mappedKey] = xml_first_search(xml_response, key_name);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
83
88
|
}
|
|
84
89
|
multi_embed_player.api_cache[service][videoid] = return_data;
|
|
85
90
|
break;
|
|
86
91
|
case 'bilibili':
|
|
87
|
-
|
|
92
|
+
let json_response_bilibili = await (await fetch(url + `https://api.bilibili.com/x/web-interface/view?bvid=${videoid}`)).json();
|
|
88
93
|
if (json_response_bilibili?.data?.pic === undefined) {
|
|
89
94
|
json_response_bilibili["image_base64"] = null;
|
|
90
95
|
}
|
|
@@ -95,7 +100,7 @@ const multi_embed_player_fetch_iframe_api = async (service, videoid, use_cors, i
|
|
|
95
100
|
break;
|
|
96
101
|
case "youtube":
|
|
97
102
|
try {
|
|
98
|
-
|
|
103
|
+
let json_response_youtube = await (await fetch(url + `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${videoid}&format=json`)).json();
|
|
99
104
|
json_response_youtube["image_base64"] = url + json_response_youtube["thumbnail_url"];
|
|
100
105
|
multi_embed_player.api_cache[service][videoid] = json_response_youtube;
|
|
101
106
|
}
|
|
@@ -104,19 +109,16 @@ const multi_embed_player_fetch_iframe_api = async (service, videoid, use_cors, i
|
|
|
104
109
|
}
|
|
105
110
|
break;
|
|
106
111
|
}
|
|
107
|
-
|
|
108
|
-
if (promise_data) {
|
|
109
|
-
promise_data.res.forEach(resolve => resolve());
|
|
110
|
-
}
|
|
112
|
+
multi_embed_player.api_promise[service][videoid].res.forEach((resolve) => resolve(undefined));
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
115
|
catch {
|
|
114
|
-
const
|
|
115
|
-
if (
|
|
116
|
-
|
|
116
|
+
const promiseData = multi_embed_player.api_promise[service][videoid];
|
|
117
|
+
if (promiseData && Object.keys(promiseData).includes("rej")) {
|
|
118
|
+
promiseData.rej.forEach((reject) => reject());
|
|
117
119
|
}
|
|
118
|
-
if (failed_send_error && failed_send_error_target
|
|
119
|
-
failed_send_error_target.dispatchEvent(new CustomEvent("onError", { detail: { code:
|
|
120
|
+
if (failed_send_error && failed_send_error_target != null) {
|
|
121
|
+
failed_send_error_target.dispatchEvent(new CustomEvent("onError", { detail: { code: 1100 } }));
|
|
120
122
|
}
|
|
121
123
|
multi_embed_player.api_cache[service][videoid] = {};
|
|
122
124
|
}
|
|
@@ -125,29 +127,29 @@ const multi_embed_player_fetch_iframe_api = async (service, videoid, use_cors, i
|
|
|
125
127
|
let fetch_response;
|
|
126
128
|
try {
|
|
127
129
|
const url = `${multi_embed_player.iframe_api_endpoint}?route=${service}&videoid=${videoid}` + (image_proxy ? "&image_base64=1" : "");
|
|
128
|
-
if (multi_embed_player.api_promise[service]
|
|
129
|
-
if (!multi_embed_player.api_promise[service]) {
|
|
130
|
-
multi_embed_player.api_promise[service] = {};
|
|
131
|
-
}
|
|
130
|
+
if (multi_embed_player.api_promise[service][videoid] === undefined) {
|
|
132
131
|
multi_embed_player.api_promise[service][videoid] = { res: [], rej: [] };
|
|
133
132
|
fetch_response = await fetch(url);
|
|
134
133
|
multi_embed_player.api_cache[service][videoid] = await fetch_response.json();
|
|
135
|
-
multi_embed_player.api_promise[service][videoid].res.forEach(resolve => resolve());
|
|
134
|
+
multi_embed_player.api_promise[service][videoid].res.forEach((resolve) => resolve(undefined));
|
|
136
135
|
}
|
|
137
136
|
else {
|
|
138
137
|
await new Promise((resolve, reject) => {
|
|
139
|
-
multi_embed_player.api_promise[service][videoid]
|
|
140
|
-
|
|
138
|
+
const promiseData = multi_embed_player.api_promise[service][videoid];
|
|
139
|
+
if (promiseData) {
|
|
140
|
+
promiseData.res.push(resolve);
|
|
141
|
+
promiseData.rej.push(reject);
|
|
142
|
+
}
|
|
141
143
|
});
|
|
142
144
|
}
|
|
143
145
|
}
|
|
144
146
|
catch (e) {
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
147
|
-
|
|
147
|
+
const promiseData = multi_embed_player.api_promise[service][videoid];
|
|
148
|
+
if (promiseData && Object.keys(promiseData).includes("rej")) {
|
|
149
|
+
promiseData.rej.forEach((reject) => reject());
|
|
148
150
|
}
|
|
149
|
-
if (failed_send_error && failed_send_error_target
|
|
150
|
-
failed_send_error_target.dispatchEvent(new CustomEvent("onError", { detail: { code:
|
|
151
|
+
if (failed_send_error && failed_send_error_target != null) {
|
|
152
|
+
failed_send_error_target.dispatchEvent(new CustomEvent("onError", { detail: { code: 1100 } }));
|
|
151
153
|
}
|
|
152
154
|
else {
|
|
153
155
|
multi_embed_player.api_cache[service][videoid] = {};
|
|
@@ -166,9 +168,20 @@ const multi_embed_player_GDPR_accepted_all_back_down = () => {
|
|
|
166
168
|
* A custom HTML element for embedding multiple video services in a single player.
|
|
167
169
|
* @extends HTMLElement
|
|
168
170
|
*/
|
|
169
|
-
|
|
171
|
+
class multi_embed_player extends HTMLElement {
|
|
170
172
|
constructor() {
|
|
171
173
|
super();
|
|
174
|
+
_multi_embed_player_instances.add(this);
|
|
175
|
+
this.service = null;
|
|
176
|
+
this.image_url = null;
|
|
177
|
+
this.picture_tag = null;
|
|
178
|
+
this.player = null;
|
|
179
|
+
this.playlist = [];
|
|
180
|
+
this.autoplay = false;
|
|
181
|
+
this.error_not_declare = false;
|
|
182
|
+
this.previousData = null;
|
|
183
|
+
this.startSeconds = 0;
|
|
184
|
+
this.endSeconds = -1;
|
|
172
185
|
this.videoid = null;
|
|
173
186
|
this.follow_GDPR = multi_embed_player.follow_GDPR;
|
|
174
187
|
}
|
|
@@ -185,14 +198,26 @@ export class multi_embed_player extends HTMLElement {
|
|
|
185
198
|
else if (this.getAttribute("picture_tag") != null) {
|
|
186
199
|
this.picture_tag = document.createElement("picture");
|
|
187
200
|
this.appendChild(this.picture_tag);
|
|
188
|
-
this.picture_tag.innerHTML = this.getAttribute("picture_tag");
|
|
201
|
+
this.picture_tag.innerHTML = this.getAttribute("picture_tag") || "";
|
|
189
202
|
}
|
|
190
203
|
else {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
204
|
+
if (this.videoid && this.service) {
|
|
205
|
+
this.image_url = await __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_mep_imageurl).call(this, this.videoid, this.service);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.image_url = null;
|
|
209
|
+
}
|
|
210
|
+
if (this.image_url && !await __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_check_image_status).call(this, this.image_url)) {
|
|
211
|
+
const subVideoid = this.getAttribute("subVideoid");
|
|
212
|
+
const subService = this.getAttribute("subService");
|
|
213
|
+
if (subVideoid && subService) {
|
|
214
|
+
this.image_url = await __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_mep_imageurl).call(this, subVideoid, subService);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
this.image_url = null;
|
|
218
|
+
}
|
|
219
|
+
if (this.image_url && !await __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_check_image_status).call(this, this.image_url)) {
|
|
220
|
+
this.style.backgroundImage = `${window.multi_embed_player.script_origin}icon/video_not_found.svgz`;
|
|
196
221
|
}
|
|
197
222
|
}
|
|
198
223
|
}
|
|
@@ -200,104 +225,595 @@ export class multi_embed_player extends HTMLElement {
|
|
|
200
225
|
this.style.backgroundImage = `url(${this.image_url})`;
|
|
201
226
|
}
|
|
202
227
|
else {
|
|
203
|
-
this.style.backgroundImage = `url(${multi_embed_player.script_origin}icon/video_not_found.svgz)`;
|
|
228
|
+
this.style.backgroundImage = `url(${window.multi_embed_player.script_origin}icon/video_not_found.svgz)`;
|
|
204
229
|
}
|
|
205
230
|
//status setting
|
|
206
231
|
if (this.getAttribute("type") === null || this.getAttribute("type") === "embed") {
|
|
207
|
-
this.addEventListener('click', this
|
|
232
|
+
this.addEventListener('click', __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_add_iframe), { once: true });
|
|
208
233
|
}
|
|
209
234
|
if (this.getAttribute("type") === "thumbnail-click") {
|
|
210
|
-
this.addEventListener('click', () => { this.
|
|
211
|
-
this.addEventListener('contextmenu', (e) => { e.preventDefault(); this.
|
|
235
|
+
this.addEventListener('click', () => { __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_PlayOnPlayer).call(this, this.getAttribute("for") || "", this.getAttribute("service") || "", this.getAttribute("videoid") || "", this.getAttribute("start"), this.getAttribute("end"), this.getAttribute("subService"), this.getAttribute("subVideoid")); });
|
|
236
|
+
this.addEventListener('contextmenu', (e) => { e.preventDefault(); __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_addPlaylist).call(this); });
|
|
212
237
|
}
|
|
213
238
|
}
|
|
214
239
|
else if (this.getAttribute("type") === "player") {
|
|
215
|
-
|
|
240
|
+
this.player = {};
|
|
241
|
+
this.player.service = "before embed";
|
|
242
|
+
this.playlist = [];
|
|
243
|
+
this.addEventListener("onEndVideo", () => { if (this.playlist.length > 0) {
|
|
244
|
+
this.loadVideoById(this.playlist.shift());
|
|
245
|
+
} }); //終わりが来たとき次のやつを再生
|
|
246
|
+
this.addEventListener("addPlaylist", () => { if (this.getPlayerState() === -1 || this.getPlayerState() === 4) {
|
|
247
|
+
if (this.playlist.length > 0) {
|
|
248
|
+
this.loadVideoById(this.playlist.shift());
|
|
249
|
+
}
|
|
250
|
+
} });
|
|
216
251
|
}
|
|
217
252
|
}
|
|
218
253
|
/**
|
|
219
|
-
*
|
|
254
|
+
* Loads a video by its ID and sets the autoplay and subtitle options.
|
|
255
|
+
* @async
|
|
256
|
+
* @param {Object} data - The data object containing the video ID, service, start time, and end time.
|
|
257
|
+
* @param {boolean} [autoplay=true] - Whether or not to autoplay the video.
|
|
258
|
+
* @param {boolean} [sub=false] - Whether or not to load a subtitle. deprecated
|
|
259
|
+
* @returns {Promise<void>}
|
|
220
260
|
*/
|
|
221
|
-
async
|
|
222
|
-
|
|
223
|
-
if (
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
261
|
+
async loadVideoById(data, autoplay = true, sub = false) {
|
|
262
|
+
this.autoplay = autoplay;
|
|
263
|
+
if (this.player != undefined) {
|
|
264
|
+
let service_changed = false;
|
|
265
|
+
this.error_not_declare = false;
|
|
266
|
+
if (data === null || (Array.isArray(data.call_array) && typeof data.call_index === "number")) {
|
|
267
|
+
if (data !== null) {
|
|
268
|
+
this.previousData = data;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
data = this.previousData;
|
|
272
|
+
}
|
|
273
|
+
data = Object.assign({}, data, data.call_array[data.call_index]);
|
|
274
|
+
this.videoid = data.videoId;
|
|
275
|
+
this.service = data.service;
|
|
276
|
+
if (data.call_array.length - 1 < data.call_index) {
|
|
277
|
+
console.error("too large call_index");
|
|
278
|
+
}
|
|
279
|
+
else if (data.call_array.length - 1 === data.call_index) {
|
|
280
|
+
this.error_not_declare = false;
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
this.error_not_declare = true;
|
|
284
|
+
this.addEventListener("executeSecound", () => { this.loadVideoById(null, autoplay, false); }, { once: true });
|
|
285
|
+
}
|
|
286
|
+
if (this.service !== this.player.service) {
|
|
287
|
+
__classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_deleteEvent).call(this);
|
|
288
|
+
service_changed = true;
|
|
289
|
+
}
|
|
290
|
+
if (this.previousData) {
|
|
291
|
+
this.previousData.call_index++;
|
|
292
|
+
}
|
|
238
293
|
}
|
|
239
294
|
else {
|
|
240
|
-
|
|
295
|
+
if (sub == false) { //1回目
|
|
296
|
+
this.previousData = data;
|
|
297
|
+
if (typeof data.subVideoId === "string" && typeof data.subService === "string") {
|
|
298
|
+
this.error_not_declare = true;
|
|
299
|
+
this.addEventListener("executeSecound", () => { this.loadVideoById(null, autoplay, false); }, { once: true });
|
|
300
|
+
}
|
|
301
|
+
if (data.service != this.player.service) {
|
|
302
|
+
__classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_deleteEvent).call(this);
|
|
303
|
+
service_changed = true;
|
|
304
|
+
this.service = data.service;
|
|
305
|
+
}
|
|
306
|
+
this.videoid = data.videoId;
|
|
307
|
+
}
|
|
308
|
+
else if (sub == true) {
|
|
309
|
+
data = this.previousData;
|
|
310
|
+
__classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_deleteEvent).call(this);
|
|
311
|
+
service_changed = true;
|
|
312
|
+
this.videoid = data.subVideoId;
|
|
313
|
+
this.service = data.subService;
|
|
314
|
+
}
|
|
241
315
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (!GDPR_accepted || service === "bilibili") {
|
|
247
|
-
if (!(videoid in multi_embed_player.api_cache[service])) {
|
|
248
|
-
await multi_embed_player_fetch_iframe_api(service, videoid, use_cors, true, false);
|
|
316
|
+
await __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_GDPR_accept).call(this, data.service);
|
|
317
|
+
this.startSeconds = 0;
|
|
318
|
+
if (data.startSeconds != undefined) {
|
|
319
|
+
this.startSeconds = Number(data.startSeconds);
|
|
249
320
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
if (!(videoid in multi_embed_player.api_cache[service])) {
|
|
254
|
-
await multi_embed_player_fetch_iframe_api(service, videoid, use_cors, !GDPR_accepted, GDPR_accepted);
|
|
321
|
+
this.endSeconds = -1;
|
|
322
|
+
if (data.endSeconds != undefined) {
|
|
323
|
+
this.endSeconds = Number(data.endSeconds);
|
|
255
324
|
}
|
|
256
|
-
|
|
257
|
-
|
|
325
|
+
this.setAttribute("videoid", data.videoId); //いらないけど勘違い防止用に
|
|
326
|
+
this.setAttribute("service", data.service);
|
|
327
|
+
if (this.service && Object.keys(window.multi_embed_player.mep_load_api_promise).includes(this.service)) {
|
|
328
|
+
await this.iframe_api_loader(this.service);
|
|
329
|
+
if (service_changed == false) {
|
|
330
|
+
//動画idを変えてiframeを再読み込み
|
|
331
|
+
if (autoplay) {
|
|
332
|
+
this.player.loadVideoById(data);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.player.cueVideoById(data);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
this.innerHTML = "";
|
|
340
|
+
let divdoc = document.createElement("div");
|
|
341
|
+
divdoc.classList.add(`mep_${this.service}`);
|
|
342
|
+
this.appendChild(divdoc);
|
|
343
|
+
let playerVars = {};
|
|
344
|
+
if (autoplay) {
|
|
345
|
+
playerVars.autoplay = 1;
|
|
346
|
+
}
|
|
347
|
+
if (data["startSeconds"] != undefined) {
|
|
348
|
+
playerVars.startSeconds = data["startSeconds"];
|
|
349
|
+
}
|
|
350
|
+
if (data["endSeconds"] != undefined) {
|
|
351
|
+
playerVars.endSeconds = data["endSeconds"];
|
|
352
|
+
}
|
|
353
|
+
let player_argument = {
|
|
354
|
+
"videoId": this.videoid,
|
|
355
|
+
"width": "560",
|
|
356
|
+
"height": "315",
|
|
357
|
+
"playerVars": playerVars
|
|
358
|
+
};
|
|
359
|
+
if (this.service == "bilibili" && this.getAttribute("play_control_wrap") === "false") {
|
|
360
|
+
player_argument["play_control_wrap"] = false;
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
player_argument["play_control_wrap"] = true;
|
|
364
|
+
}
|
|
365
|
+
if (this.service) {
|
|
366
|
+
this.player = new window.multi_embed_player.iframe_api_class[this.service](divdoc, player_argument, __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_setEvent).bind(this));
|
|
367
|
+
this.player.service = this.service;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
258
370
|
}
|
|
259
371
|
else {
|
|
260
|
-
|
|
372
|
+
console.error(`service name not defined ${this.service}`);
|
|
261
373
|
}
|
|
262
374
|
}
|
|
263
375
|
else {
|
|
264
|
-
|
|
376
|
+
console.log("player not found.");
|
|
265
377
|
}
|
|
266
378
|
}
|
|
267
379
|
/**
|
|
268
|
-
*
|
|
380
|
+
* Plays the video.
|
|
269
381
|
*/
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
382
|
+
playVideo() {
|
|
383
|
+
this.player.playVideo();
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Pauses the video.
|
|
387
|
+
*/
|
|
388
|
+
pauseVideo() {
|
|
389
|
+
this.player.pauseVideo();
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Stops the video.
|
|
393
|
+
* @deprecated
|
|
394
|
+
*/
|
|
395
|
+
stopVideo() {
|
|
396
|
+
this.player.pauseVideo();
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Returns the current time of the video.
|
|
400
|
+
* @returns {Promise<number>} - A promise that resolves with the current time of the video. promise only bilibili
|
|
401
|
+
*/
|
|
402
|
+
async getCurrentTime() {
|
|
403
|
+
if (this.service == "bilibili") {
|
|
404
|
+
return await this.player.getCurrentTime();
|
|
405
|
+
}
|
|
406
|
+
else {
|
|
407
|
+
return this.player.getCurrentTime();
|
|
408
|
+
}
|
|
280
409
|
}
|
|
281
410
|
/**
|
|
282
|
-
*
|
|
411
|
+
* Seeks to a given time in the video.
|
|
412
|
+
* @param {number} seconds - if service is bilibili, return promise
|
|
283
413
|
*/
|
|
284
|
-
async
|
|
285
|
-
|
|
414
|
+
async seekTo(seconds) {
|
|
415
|
+
await this.player.seekTo(seconds);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Mutes the video.
|
|
419
|
+
*/
|
|
420
|
+
mute() {
|
|
421
|
+
this.player.mute();
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Unmutes the video.
|
|
425
|
+
*/
|
|
426
|
+
unMute() {
|
|
427
|
+
this.player.unMute();
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Returns whether the video is muted.
|
|
431
|
+
* @returns {boolean} - Whether the video is muted.if service is bilibili, return promise
|
|
432
|
+
*/
|
|
433
|
+
isMuted() {
|
|
434
|
+
return this.player.isMuted();
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Set the volume of the player.
|
|
438
|
+
* @param {number} volume - The volume level to set.
|
|
439
|
+
*/
|
|
440
|
+
setVolume(volume) {
|
|
441
|
+
this.player.setVolume(Number(volume));
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Returns the current volume of the player.
|
|
445
|
+
* @returns {number} The current volume of the player.
|
|
446
|
+
*/
|
|
447
|
+
getVolume() {
|
|
448
|
+
return this.player.getVolume();
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Returns the duration of the current video.
|
|
452
|
+
* @returns {number} The duration of the current video in seconds.
|
|
453
|
+
*/
|
|
454
|
+
getDuration() {
|
|
455
|
+
return this.player.getDuration();
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Returns the real duration of the video based on the start and end seconds.
|
|
459
|
+
* @returns {number} The real duration of the video.
|
|
460
|
+
*/
|
|
461
|
+
getRealDulation() {
|
|
462
|
+
if (this.service && Object.keys(window.multi_embed_player.mep_load_api_promise).includes(this.service)) {
|
|
463
|
+
return this.player.getRealDulation();
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
return 0;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Returns the relative current time by subtracting the start time from the current time.
|
|
471
|
+
* @returns {Promise<number>} The relative current time.
|
|
472
|
+
*/
|
|
473
|
+
async getRelativeCurrentTime() {
|
|
474
|
+
return await this.getCurrentTime() - this.startSeconds;
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Calculates the percentage of the current time relative to the total duration of the media.
|
|
478
|
+
* @returns {number} The percentage of the current time.
|
|
479
|
+
*/
|
|
480
|
+
async getPercentOfCurremtTime() {
|
|
481
|
+
return ((await this.getRelativeCurrentTime()) / this.getRealDulation()) * 100;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Seeks to a relative position in the video based on the current time.
|
|
485
|
+
* @param {number} seconds - The number of seconds to seek relative to the current time.
|
|
486
|
+
*/
|
|
487
|
+
async relativeSeekTo_ct(seconds) {
|
|
488
|
+
this.seekTo(seconds + await this.getCurrentTime());
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Start seeking from the given seconds plus the startSeconds.
|
|
492
|
+
* @param {number} seconds - The seconds to seek from.
|
|
493
|
+
*/
|
|
494
|
+
relativeSeekTo_ss(seconds) {
|
|
495
|
+
this.seekTo(seconds + this.startSeconds);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Returns the current state of the player.
|
|
499
|
+
* @returns {number} The player state:
|
|
500
|
+
* -1 -> not set video mainly before embed
|
|
501
|
+
* 0 -> not played only thumnail
|
|
502
|
+
* 1 -> onload
|
|
503
|
+
* 2 -> playing
|
|
504
|
+
* 3 -> pause
|
|
505
|
+
* 4 -> video ended
|
|
506
|
+
*/
|
|
507
|
+
getPlayerState() {
|
|
508
|
+
if (this.service && Object.keys(window.multi_embed_player.mep_load_api_promise).includes(this.service)) {
|
|
509
|
+
return this.player.getPlayerState();
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
return -1;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Loads the YouTube API asynchronously and returns a Promise that resolves when the API is ready.
|
|
517
|
+
* If the API is already loaded, the Promise resolves immediately.
|
|
518
|
+
* If the API is currently being loaded, the Promise will resolve when the API is ready.
|
|
519
|
+
* @returns {Promise<void>} A Promise that resolves when the YouTube API is ready.
|
|
520
|
+
*/
|
|
521
|
+
async youtube_api_loader() {
|
|
522
|
+
return new Promise(async (resolve, reject) => {
|
|
523
|
+
if (window.multi_embed_player.mep_status_load_api.youtube === 0) {
|
|
524
|
+
let script_url = "https://www.youtube.com/iframe_api";
|
|
525
|
+
window.multi_embed_player.mep_status_load_api.youtube = 1;
|
|
526
|
+
await this.mep_promise_script_loader(script_url);
|
|
527
|
+
YT.ready(() => { window.multi_embed_player.mep_load_api_promise.youtube.forEach((func) => func()); window.multi_embed_player.mep_status_load_api.youtube = 2; resolve(); });
|
|
528
|
+
}
|
|
529
|
+
else if (window.multi_embed_player.mep_status_load_api.youtube == 1) {
|
|
530
|
+
window.multi_embed_player.mep_load_api_promise.youtube.push(resolve);
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
resolve();
|
|
534
|
+
}
|
|
535
|
+
});
|
|
286
536
|
}
|
|
287
537
|
/**
|
|
288
|
-
*
|
|
538
|
+
* Loads the API for the specified service and returns a promise that resolves when the API is loaded.
|
|
539
|
+
* @async
|
|
540
|
+
* @param {string} service - The name of the service whose API needs to be loaded.
|
|
541
|
+
* @returns {Promise<void>} A promise that resolves when the API is loaded.
|
|
289
542
|
*/
|
|
290
|
-
|
|
291
|
-
|
|
543
|
+
async iframe_api_loader(service) {
|
|
544
|
+
return new Promise(async (resolve, reject) => {
|
|
545
|
+
if (window.multi_embed_player.mep_status_load_api[service] === 0) {
|
|
546
|
+
window.multi_embed_player.mep_status_load_api[service] = 1;
|
|
547
|
+
await this.mep_promise_script_loader(`${window.multi_embed_player.script_origin}iframe_api/${service}.js`);
|
|
548
|
+
window.multi_embed_player.mep_status_load_api[service] = 2;
|
|
549
|
+
switch (service) {
|
|
550
|
+
case "youtube":
|
|
551
|
+
window.multi_embed_player.iframe_api_class["youtube"] = mep_youtube;
|
|
552
|
+
break;
|
|
553
|
+
case "niconico":
|
|
554
|
+
window.multi_embed_player.iframe_api_class["niconico"] = mep_niconico;
|
|
555
|
+
break;
|
|
556
|
+
case "bilibili":
|
|
557
|
+
window.multi_embed_player.iframe_api_class["bilibili"] = mep_bilibili;
|
|
558
|
+
break;
|
|
559
|
+
case "soundcloud":
|
|
560
|
+
window.multi_embed_player.iframe_api_class["soundcloud"] = mep_soundcloud;
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
window.multi_embed_player.mep_load_api_promise[service].forEach((func) => func());
|
|
564
|
+
resolve();
|
|
565
|
+
}
|
|
566
|
+
else if (window.multi_embed_player.mep_status_load_api[service] === 1) {
|
|
567
|
+
window.multi_embed_player.mep_load_api_promise[service].push(resolve);
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
resolve();
|
|
571
|
+
}
|
|
572
|
+
});
|
|
292
573
|
}
|
|
293
574
|
/**
|
|
294
|
-
*
|
|
575
|
+
* Loads a script asynchronously and returns a promise that resolves when the script is loaded successfully or rejects when there is an error.
|
|
576
|
+
* @param {string} src - The URL of the script to be loaded.
|
|
577
|
+
* @returns {Promise<void>} - A promise that resolves when the script is loaded successfully or rejects when there is an error.
|
|
295
578
|
*/
|
|
296
|
-
|
|
297
|
-
|
|
579
|
+
async mep_promise_script_loader(src) {
|
|
580
|
+
return new Promise((resolve, reject) => {
|
|
581
|
+
let script_document = document.createElement("script");
|
|
582
|
+
script_document.src = src;
|
|
583
|
+
script_document.async = true;
|
|
584
|
+
document.body.appendChild(script_document);
|
|
585
|
+
script_document.addEventListener("load", () => {
|
|
586
|
+
resolve();
|
|
587
|
+
}, { once: true });
|
|
588
|
+
script_document.addEventListener("error", () => {
|
|
589
|
+
reject();
|
|
590
|
+
}, { once: true });
|
|
591
|
+
});
|
|
298
592
|
}
|
|
299
593
|
}
|
|
300
|
-
|
|
594
|
+
_multi_embed_player_instances = new WeakSet(), _multi_embed_player_check_image_status =
|
|
595
|
+
/**
|
|
596
|
+
* Checks the status of an image URL.
|
|
597
|
+
* @async
|
|
598
|
+
* @param {string} img_url - The URL of the image to check.
|
|
599
|
+
* @returns {Promise<boolean>} - A promise that resolves to true if the image loads successfully, false otherwise.
|
|
600
|
+
*/
|
|
601
|
+
async function _multi_embed_player_check_image_status(img_url) {
|
|
602
|
+
if (typeof img_url !== "string") {
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
const img = new Image();
|
|
606
|
+
img.src = img_url;
|
|
607
|
+
return new Promise((resolve, reject) => { img.onload = () => { img.remove(); resolve(true); }; img.onerror = () => { img.remove(); resolve(false); }; });
|
|
608
|
+
}, _multi_embed_player_add_iframe =
|
|
609
|
+
/**
|
|
610
|
+
* This function adds an iframe to the current element.
|
|
611
|
+
* @param {Event} e - The event that triggered the function. Default is null.
|
|
612
|
+
* @param {boolean} sub - A flag to indicate whether the iframe is a subframe. Default is false.
|
|
613
|
+
*/
|
|
614
|
+
async function _multi_embed_player_add_iframe(e = null, sub = false) {
|
|
615
|
+
let content = new mep_playitem(this.getAttribute("service"), this.getAttribute("videoid"));
|
|
616
|
+
if (this.getAttribute("start") != null) {
|
|
617
|
+
content.startSeconds = Number(this.getAttribute("start"));
|
|
618
|
+
}
|
|
619
|
+
if (this.getAttribute("end") != null) {
|
|
620
|
+
content.endSeconds = Number(this.getAttribute("end"));
|
|
621
|
+
}
|
|
622
|
+
if (this.getAttribute("subvideoid") != null && this.getAttribute("subservice") != null) {
|
|
623
|
+
content.subVideoid = this.getAttribute("subvideoid") || undefined;
|
|
624
|
+
content.subService = this.getAttribute("subservice");
|
|
625
|
+
}
|
|
626
|
+
this.player = {};
|
|
627
|
+
this.loadVideoById(content.toData());
|
|
628
|
+
}, _multi_embed_player_mep_imageurl =
|
|
629
|
+
/**
|
|
630
|
+
* Asynchronously fetches the image URL for a given video ID and service.
|
|
631
|
+
* @param {string} videoid - The ID of the video to fetch the image for.
|
|
632
|
+
* @param {string} service - The service to fetch the image from.
|
|
633
|
+
* @param {string} [filetype=null] - The type of file to fetch.
|
|
634
|
+
* @returns {Promise<string>} - A promise that resolves with the image URL.
|
|
635
|
+
*/
|
|
636
|
+
async function _multi_embed_player_mep_imageurl(videoid, service, filetype = null) {
|
|
637
|
+
let GDPR_accepted = false;
|
|
638
|
+
if (!this.follow_GDPR) {
|
|
639
|
+
GDPR_accepted = true;
|
|
640
|
+
}
|
|
641
|
+
else if (this.follow_GDPR && !window.multi_embed_player.GDPR_accepted[service]) {
|
|
642
|
+
GDPR_accepted = false;
|
|
643
|
+
}
|
|
644
|
+
else if (this.follow_GDPR && window.multi_embed_player.GDPR_accepted[service]) {
|
|
645
|
+
GDPR_accepted = true;
|
|
646
|
+
}
|
|
647
|
+
let image_url = "";
|
|
648
|
+
let use_cors = false;
|
|
649
|
+
if (GDPR_accepted) {
|
|
650
|
+
if (window.multi_embed_player.cors_proxy !== "") {
|
|
651
|
+
image_url = window.multi_embed_player.cors_proxy;
|
|
652
|
+
use_cors = true;
|
|
653
|
+
}
|
|
654
|
+
else {
|
|
655
|
+
image_url = `${window.multi_embed_player.iframe_api_endpoint}?route=url_proxy&url=`;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
if (window.multi_embed_player.cors_proxy !== "") {
|
|
659
|
+
use_cors = true;
|
|
660
|
+
}
|
|
661
|
+
if (!GDPR_accepted || service === "bilibili") { //if follow gdpr or bilibili(bilibili don't allow to fetch thumbnail from crossorigin)
|
|
662
|
+
if (!(videoid in window.multi_embed_player.api_cache[service])) {
|
|
663
|
+
await multi_embed_player_fetch_iframe_api(service, videoid, use_cors, true, false);
|
|
664
|
+
}
|
|
665
|
+
return window.multi_embed_player.api_cache[service][videoid]["image_base64"];
|
|
666
|
+
}
|
|
667
|
+
/*else if(service==="niconico"){
|
|
668
|
+
if(!(videoid in (window as any).multi_embed_player.api_cache[service])){
|
|
669
|
+
await this.fetch_iframe_api(service,videoid,use_cors,false,GDPR_accepted);
|
|
670
|
+
}
|
|
671
|
+
return image_url + (window as any).multi_embed_player.api_cache[service][videoid]["image"];
|
|
672
|
+
}*/
|
|
673
|
+
else if (service === "soundcloud" || service === "youtube" || service === "niconico") {
|
|
674
|
+
if (!(videoid in window.multi_embed_player.api_cache[service])) {
|
|
675
|
+
await multi_embed_player_fetch_iframe_api(service, videoid, use_cors, !GDPR_accepted, GDPR_accepted);
|
|
676
|
+
}
|
|
677
|
+
if (!GDPR_accepted) {
|
|
678
|
+
return window.multi_embed_player.api_cache[service][videoid]["image_base64"];
|
|
679
|
+
}
|
|
680
|
+
else {
|
|
681
|
+
return window.multi_embed_player.api_cache[service][videoid]["thumbnail_url"];
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
image_url = "invalid_url";
|
|
686
|
+
return image_url;
|
|
687
|
+
}
|
|
688
|
+
}, _multi_embed_player_GDPR_accept =
|
|
689
|
+
/**
|
|
690
|
+
* Asynchronously accepts GDPR for a given service.
|
|
691
|
+
* @param {string} service - The name of the service to accept GDPR for.
|
|
692
|
+
* @returns {Promise<void>} - A promise that resolves when GDPR is accepted.
|
|
693
|
+
*/
|
|
694
|
+
async function _multi_embed_player_GDPR_accept(service) {
|
|
695
|
+
return new Promise(async (resolve, reject) => {
|
|
696
|
+
if (this.follow_GDPR) {
|
|
697
|
+
if (window.multi_embed_player.GDPR_accepted[service]) {
|
|
698
|
+
resolve();
|
|
699
|
+
}
|
|
700
|
+
else {
|
|
701
|
+
window.multi_embed_player.GDPR_accept_promise[service].push(resolve);
|
|
702
|
+
const GDPR_check_div = document.createElement("div");
|
|
703
|
+
const firest_p_element = document.createElement("p");
|
|
704
|
+
firest_p_element.innerText = "This content is hosted by a third party.\nBy showing the external content you accept the terms and conditions";
|
|
705
|
+
GDPR_check_div.appendChild(firest_p_element);
|
|
706
|
+
const tearms_link = document.createElement("a");
|
|
707
|
+
tearms_link.href = window.multi_embed_player.tearms_policy_service[service];
|
|
708
|
+
tearms_link.target = "_blank";
|
|
709
|
+
tearms_link.innerText = `${service} terms and conditions`;
|
|
710
|
+
GDPR_check_div.appendChild(tearms_link);
|
|
711
|
+
const second_p_element = document.createElement("p");
|
|
712
|
+
second_p_element.innerText = `service hosted by ${service} is not under our control and can change without notice.\nIf you notice any change, please let us know.\nAlso this accept status save for this domain localstorage if you accept and can access for this.`;
|
|
713
|
+
GDPR_check_div.appendChild(second_p_element);
|
|
714
|
+
const button_agree = document.createElement("button");
|
|
715
|
+
button_agree.innerText = "I accept";
|
|
716
|
+
button_agree.addEventListener("click", () => { multi_embed_player_GDPR_reviever(service); });
|
|
717
|
+
GDPR_check_div.appendChild(button_agree);
|
|
718
|
+
//remove all children of this
|
|
719
|
+
while (this.firstChild) {
|
|
720
|
+
this.removeChild(this.firstChild);
|
|
721
|
+
}
|
|
722
|
+
this.appendChild(GDPR_check_div);
|
|
723
|
+
this.style.backgroundImage = "";
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
resolve();
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
}, _multi_embed_player_error_event_handler = function _multi_embed_player_error_event_handler(e) {
|
|
731
|
+
console.error("error occured");
|
|
732
|
+
if (!this.error_not_declare) {
|
|
733
|
+
this.dispatchEvent(new CustomEvent("onError", { detail: { code: e.detail.code } }));
|
|
734
|
+
}
|
|
735
|
+
else {
|
|
736
|
+
this.dispatchEvent(new Event("executeSecound"));
|
|
737
|
+
}
|
|
738
|
+
}, _multi_embed_player_setEvent = function _multi_embed_player_setEvent(element) {
|
|
739
|
+
try {
|
|
740
|
+
if (typeof element === "undefined") {
|
|
741
|
+
if (this.service && Object.keys(window.multi_embed_player.mep_load_api_promise).includes(this.service)) {
|
|
742
|
+
this.player.player.addEventListener("onReady", () => { this.dispatchEvent(new Event("onReady")); }); //need bind
|
|
743
|
+
this.player.player.addEventListener("onError", (e) => { __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_error_event_handler).call(this, e); });
|
|
744
|
+
this.player.player.addEventListener("onStateChange", (e) => { this.dispatchEvent(new CustomEvent("onStateChange", { detail: e.detail })); });
|
|
745
|
+
this.player.player.addEventListener("onEndVideo", () => { this.dispatchEvent(new Event("onEndVideo")); });
|
|
746
|
+
}
|
|
747
|
+
else {
|
|
748
|
+
console.error(`service ${this.service} not found at multi_embed_player class setEvent()`);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
else {
|
|
752
|
+
if (this.service && Object.keys(window.multi_embed_player.mep_load_api_promise).includes(this.service)) {
|
|
753
|
+
element.addEventListener("onReady", () => { this.dispatchEvent(new Event("onReady")); });
|
|
754
|
+
element.addEventListener("onError", (e) => { __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_error_event_handler).call(this, e); });
|
|
755
|
+
element.addEventListener("onStateChange", (e) => { this.dispatchEvent(new CustomEvent("onStateChange", { detail: e.detail })); });
|
|
756
|
+
element.addEventListener("onEndVideo", () => { this.dispatchEvent(new Event("onEndVideo")); });
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
console.error(`service ${this.service} not found at multi_embed_player class setEvent(element)`);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
catch (e) {
|
|
764
|
+
console.log("failed to set event. under log is error message.");
|
|
765
|
+
console.log(e);
|
|
766
|
+
}
|
|
767
|
+
}, _multi_embed_player_deleteEvent = function _multi_embed_player_deleteEvent() {
|
|
768
|
+
try {
|
|
769
|
+
if (this.service && Object.keys(window.multi_embed_player.mep_load_api_promise).includes(this.service)) {
|
|
770
|
+
this.player.player.removeEventListener("onReady", () => { this.dispatchEvent(new Event("onReady")); }); //need bind
|
|
771
|
+
this.player.player.removeEventListener("onError", (e) => { __classPrivateFieldGet(this, _multi_embed_player_instances, "m", _multi_embed_player_error_event_handler).call(this, e); });
|
|
772
|
+
this.player.player.removeEventListener("onStateChange", (e) => { this.dispatchEvent(new CustomEvent("onStateChange", { detail: e.detail })); });
|
|
773
|
+
this.player.player.removeEventListener("onEndVideo", () => { this.dispatchEvent(new Event("onEndVideo")); });
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
console.error(`service ${this.service} not found at multi_embed_player class deleteEvent()`);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
catch { }
|
|
780
|
+
}, _multi_embed_player_PlayOnPlayer = function _multi_embed_player_PlayOnPlayer(playerid, service, videoid, start, end, subService, subVideoid) {
|
|
781
|
+
let playdoc = document.getElementById(playerid);
|
|
782
|
+
let content = new mep_playitem(service, videoid);
|
|
783
|
+
if (start != null) {
|
|
784
|
+
content.startSeconds = typeof start === 'string' ? Number(start) : start;
|
|
785
|
+
}
|
|
786
|
+
if (end != null) {
|
|
787
|
+
content.endSeconds = typeof end === 'string' ? Number(end) : end;
|
|
788
|
+
}
|
|
789
|
+
if (subService != null && subVideoid != null) {
|
|
790
|
+
content.subVideoid = subVideoid;
|
|
791
|
+
content.subService = subService;
|
|
792
|
+
}
|
|
793
|
+
playdoc.loadVideoById(content.toData());
|
|
794
|
+
}, _multi_embed_player_addPlaylist = function _multi_embed_player_addPlaylist() {
|
|
795
|
+
let k_data = new mep_playitem(this.getAttribute("service"), this.getAttribute("videoid"));
|
|
796
|
+
if (this.getAttribute("start") != null) {
|
|
797
|
+
k_data.startSeconds = Number(this.getAttribute("start"));
|
|
798
|
+
}
|
|
799
|
+
if (this.getAttribute("end") != null) {
|
|
800
|
+
k_data.endSeconds = Number(this.getAttribute("end"));
|
|
801
|
+
}
|
|
802
|
+
if (this.getAttribute("subService") != null && this.getAttribute("subVideoid") != null) {
|
|
803
|
+
k_data.subService = this.getAttribute("subService");
|
|
804
|
+
k_data.subVideoid = this.getAttribute("subVideoid") || undefined;
|
|
805
|
+
}
|
|
806
|
+
const forElement = this.getAttribute("for");
|
|
807
|
+
if (forElement) {
|
|
808
|
+
const targetElement = document.getElementById(forElement);
|
|
809
|
+
if (targetElement) {
|
|
810
|
+
targetElement.playlist.push(k_data.toData());
|
|
811
|
+
targetElement.dispatchEvent(new Event("addPlaylist"));
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
// static script_origin = "https://cdn.jsdelivr.net/gh/bonjinnorenka/multi_embed_player@v2/";
|
|
816
|
+
multi_embed_player.script_origin = "http://localhost:5500/dist/";
|
|
301
817
|
multi_embed_player.iframe_api_endpoint = "https://iframe_api.ryokuryu.workers.dev";
|
|
302
818
|
multi_embed_player.mep_status_load_api = { youtube: 0, niconico: 0, bilibili: 0, soundcloud: 0 };
|
|
303
819
|
multi_embed_player.mep_load_api_promise = { youtube: [], niconico: [], bilibili: [], soundcloud: [] };
|
|
@@ -307,12 +823,99 @@ multi_embed_player.GDPR_accept_promise = { youtube: [], niconico: [], bilibili:
|
|
|
307
823
|
multi_embed_player.iframe_api_class = {};
|
|
308
824
|
multi_embed_player.GDPR_accepted = { youtube: false, niconico: false, bilibili: false, soundcloud: false };
|
|
309
825
|
multi_embed_player.possible_direct_access_services = ["youtube", "soundcloud"];
|
|
310
|
-
multi_embed_player.cors_proxy = ""; //
|
|
311
|
-
multi_embed_player.tearms_policy_service = {
|
|
312
|
-
"youtube": "https://www.youtube.com/t/terms",
|
|
313
|
-
"niconico": "https://account.nicovideo.jp/rules/account?language=en-us",
|
|
314
|
-
"bilibili": "https://www.bilibili.com/blackboard/protocal/activity-lc1L-pIoh.html",
|
|
315
|
-
"soundcloud": "https://soundcloud.com/pages/privacy"
|
|
316
|
-
};
|
|
826
|
+
multi_embed_player.cors_proxy = ""; //if cors_proxy is not empty string,it use instead of iframe_api_endpoint and follow gdpr
|
|
827
|
+
multi_embed_player.tearms_policy_service = { "youtube": "https://www.youtube.com/t/terms", "niconico": "https://account.nicovideo.jp/rules/account?language=en-us", "bilibili": "https://www.bilibili.com/blackboard/protocal/activity-lc1L-pIoh.html", "soundcloud": "https://soundcloud.com/pages/privacy" };
|
|
317
828
|
multi_embed_player.follow_GDPR = false;
|
|
829
|
+
class mep_playitem {
|
|
830
|
+
constructor(service, videoid) {
|
|
831
|
+
this.service = service;
|
|
832
|
+
this.videoid = videoid;
|
|
833
|
+
this.call_array = [];
|
|
834
|
+
}
|
|
835
|
+
toData() {
|
|
836
|
+
let content = { "service": this?.service, "videoId": this?.videoid, call_array: this.call_array, call_index: 0 };
|
|
837
|
+
if (this.service !== undefined && this.videoid !== undefined) {
|
|
838
|
+
content.call_array.push({ videoId: this.videoid, service: this.service });
|
|
839
|
+
}
|
|
840
|
+
if (this.startSeconds != undefined) {
|
|
841
|
+
content.startSeconds = this.startSeconds;
|
|
842
|
+
}
|
|
843
|
+
if (this.endSeconds != undefined) {
|
|
844
|
+
content.endSeconds = this.endSeconds;
|
|
845
|
+
}
|
|
846
|
+
if (this.subService != undefined && this.subVideoid != undefined) {
|
|
847
|
+
content.subService = this.subService;
|
|
848
|
+
content.subVideoId = this.subVideoid;
|
|
849
|
+
content.call_array.push({ videoId: this.subVideoid, service: this.subService });
|
|
850
|
+
}
|
|
851
|
+
return content;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
class mep_parallel {
|
|
855
|
+
constructor() {
|
|
856
|
+
this.data = []; //class mep_parallel_inner
|
|
857
|
+
}
|
|
858
|
+
parse() {
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
class mep_parallel_inner {
|
|
862
|
+
constructor(service, videoid) {
|
|
863
|
+
this.service = service;
|
|
864
|
+
this.videoid = videoid;
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
if (typeof multi_embed_player_set_variable === "function") {
|
|
868
|
+
multi_embed_player_set_variable(multi_embed_player);
|
|
869
|
+
}
|
|
870
|
+
//load GDPR status
|
|
871
|
+
try {
|
|
872
|
+
if (localStorage.getItem("multi_embed_player_GDPR_accepted") !== null) {
|
|
873
|
+
const gdprData = localStorage.getItem("multi_embed_player_GDPR_accepted");
|
|
874
|
+
if (gdprData) {
|
|
875
|
+
window.multi_embed_player.GDPR_accepted = JSON.parse(gdprData);
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
catch {
|
|
880
|
+
console.log("failed to load GDPR status may be not supported browser or not accept to access localstorage");
|
|
881
|
+
}
|
|
882
|
+
const multi_embed_player_save_GDPR_status = () => {
|
|
883
|
+
try {
|
|
884
|
+
localStorage.setItem("multi_embed_player_GDPR_accepted", JSON.stringify(multi_embed_player.GDPR_accepted));
|
|
885
|
+
}
|
|
886
|
+
catch {
|
|
887
|
+
console.log("failed to save GDPR status may be not supported browser or not accept to access localstorage");
|
|
888
|
+
}
|
|
889
|
+
};
|
|
890
|
+
//recieve GDPR accept by service
|
|
891
|
+
const multi_embed_player_GDPR_reviever = (service) => {
|
|
892
|
+
multi_embed_player.GDPR_accepted[service] = true;
|
|
893
|
+
multi_embed_player_save_GDPR_status();
|
|
894
|
+
multi_embed_player.GDPR_accept_promise[service].forEach((func) => func());
|
|
895
|
+
};
|
|
896
|
+
//Add multi embed player CSS
|
|
897
|
+
const multi_embed_player_css = document.createElement("style");
|
|
898
|
+
multi_embed_player_css.innerHTML = `
|
|
899
|
+
multi-embed-player{
|
|
900
|
+
display: block;
|
|
901
|
+
position: relative;
|
|
902
|
+
background-repeat: no-repeat;
|
|
903
|
+
background-position: center center;
|
|
904
|
+
background-size: cover;
|
|
905
|
+
}
|
|
906
|
+
multi-embed-player>iframe{
|
|
907
|
+
width: 100%;
|
|
908
|
+
height: 100%;
|
|
909
|
+
}
|
|
910
|
+
multi-embed-player>picture{
|
|
911
|
+
position: absolute;
|
|
912
|
+
width: 100%;
|
|
913
|
+
height: 100%;
|
|
914
|
+
z-index: -1;
|
|
915
|
+
}`;
|
|
916
|
+
multi_embed_player_css.classList.add("multi-embed-player-CSS");
|
|
917
|
+
document.head.appendChild(multi_embed_player_css);
|
|
918
|
+
// Preserve class name for compilation
|
|
919
|
+
window.multi_embed_player = multi_embed_player;
|
|
920
|
+
customElements.define('multi-embed-player', multi_embed_player); //define custom element
|
|
318
921
|
//# sourceMappingURL=multi_embed_player.js.map
|