multi_embed_player 3.0.1 → 3.1.0

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.
Files changed (128) hide show
  1. package/.github/workflows/build-and-deploy.yml +44 -0
  2. package/.gitmodules +3 -0
  3. package/CLAUDE.md +92 -0
  4. package/README.md +0 -24
  5. package/add_types.sh +61 -0
  6. package/browserExtention/chrome/background.js +55 -0
  7. package/browserExtention/chrome/extention.json +1 -0
  8. package/browserExtention/chrome/liteplayer.js +26439 -0
  9. package/browserExtention/chrome/manifest.json +31 -0
  10. package/browserExtention/chrome/player-selector.js +1854 -0
  11. package/browserExtention/firefox/background.js +27 -0
  12. package/browserExtention/firefox/extention.json +1 -0
  13. package/browserExtention/firefox/liteplayer.js +26439 -0
  14. package/browserExtention/firefox/manifest.json +19 -0
  15. package/browserExtention/firefox/player-selector.js +1854 -0
  16. package/documents/.hugo_build.lock +0 -0
  17. package/documents/archetypes/default.md +5 -0
  18. package/documents/assets/jsconfig.json +11 -0
  19. package/documents/content/docs/install.md +103 -0
  20. package/documents/content/docs/quickstart.md +51 -0
  21. package/documents/content/docs/reference/HTML.md +31 -0
  22. package/documents/content/docs/reference/_index.md +10 -0
  23. package/documents/content/docs/reference/error_code.md +23 -0
  24. package/documents/content/docs/reference/iframe_api.md +737 -0
  25. package/documents/content/docs/reference/iframe_class.md +230 -0
  26. package/documents/content/docs/reference/multi_embed_player_class.md +113 -0
  27. package/documents/content/docs/reference/reserved_words.md +71 -0
  28. package/documents/content/docs/usage/GDPR_mode.md +77 -0
  29. package/documents/content/docs/usage/_index.md +10 -0
  30. package/documents/content/docs/usage/custom_playlist.md +239 -0
  31. package/documents/content/docs/usage/embed_api.md +163 -0
  32. package/documents/content/docs/usage/embed_various_service.md +81 -0
  33. package/documents/content/docs/usage/thumbnail_click.md +57 -0
  34. package/documents/go.mod +8 -0
  35. package/documents/go.sum +14 -0
  36. package/documents/hugo.toml +18 -0
  37. package/documents/layouts/partials/docs/sidebar.html +117 -0
  38. package/documents/layouts/partials/landing/features.html +47 -0
  39. package/documents/layouts/robots.txt +4 -0
  40. package/documents/static/_headers +7 -0
  41. package/documents/static/localStorageCheck.html +27 -0
  42. package/documents/static/no_extention.json +1 -0
  43. package/example.html +27 -0
  44. package/extention.json +1 -0
  45. package/icon/video_not_found.odg +0 -0
  46. package/icon/video_not_found.svgz +0 -0
  47. package/iframe_api/bilibili.ts +1095 -0
  48. package/iframe_api/niconico.ts +429 -0
  49. package/iframe_api/soundcloud.ts +450 -0
  50. package/iframe_api/youtube.ts +311 -0
  51. package/multi_embed_player.ts +989 -0
  52. package/package.json +10 -41
  53. package/player_api_gate/bilibili-api-gate/cgi/cpp/bilibili-api-gate-cgi.cpp +281 -0
  54. package/player_api_gate/bilibili-api-gate/cgi/go/src.go +46 -0
  55. package/player_api_gate/bilibili-api-gate/cloudflare_workers/package-lock.json +1356 -0
  56. package/player_api_gate/bilibili-api-gate/cloudflare_workers/package.json +12 -0
  57. package/player_api_gate/bilibili-api-gate/cloudflare_workers/src/index.js +50 -0
  58. package/player_api_gate/bilibili-api-gate/cloudflare_workers/wrangler.toml +3 -0
  59. package/player_api_gate/iframe-api-ts/.editorconfig +12 -0
  60. package/player_api_gate/iframe-api-ts/.prettierrc +6 -0
  61. package/player_api_gate/iframe-api-ts/package-lock.json +3054 -0
  62. package/player_api_gate/iframe-api-ts/package.json +18 -0
  63. package/player_api_gate/iframe-api-ts/src/bilibili.ts +49 -0
  64. package/player_api_gate/iframe-api-ts/src/index.ts +35 -0
  65. package/player_api_gate/iframe-api-ts/src/niconico.ts +95 -0
  66. package/player_api_gate/iframe-api-ts/src/soundcloud.ts +38 -0
  67. package/player_api_gate/iframe-api-ts/src/types.ts +115 -0
  68. package/player_api_gate/iframe-api-ts/src/url-proxy.ts +29 -0
  69. package/player_api_gate/iframe-api-ts/src/utils.ts +82 -0
  70. package/player_api_gate/iframe-api-ts/src/youtube.ts +41 -0
  71. package/player_api_gate/iframe-api-ts/test/bilibili.spec.ts +47 -0
  72. package/player_api_gate/iframe-api-ts/test/env.d.ts +3 -0
  73. package/player_api_gate/iframe-api-ts/test/index.spec.ts +59 -0
  74. package/player_api_gate/iframe-api-ts/test/niconico.spec.ts +55 -0
  75. package/player_api_gate/iframe-api-ts/test/soundcloud.spec.ts +55 -0
  76. package/player_api_gate/iframe-api-ts/test/tsconfig.json +8 -0
  77. package/player_api_gate/iframe-api-ts/test/url-proxy.spec.ts +46 -0
  78. package/player_api_gate/iframe-api-ts/test/youtube.spec.ts +45 -0
  79. package/player_api_gate/iframe-api-ts/tsconfig.json +45 -0
  80. package/player_api_gate/iframe-api-ts/vitest.config.mts +11 -0
  81. package/player_api_gate/iframe-api-ts/worker-configuration.d.ts +5768 -0
  82. package/player_api_gate/iframe-api-ts/wrangler.jsonc +47 -0
  83. package/player_api_gate/iframe_api/.editorconfig +13 -0
  84. package/player_api_gate/iframe_api/.prettierrc +6 -0
  85. package/player_api_gate/iframe_api/package-lock.json +1307 -0
  86. package/player_api_gate/iframe_api/package.json +12 -0
  87. package/player_api_gate/iframe_api/src/bilibili_api.js +60 -0
  88. package/player_api_gate/iframe_api/src/index.js +47 -0
  89. package/player_api_gate/iframe_api/src/niconico_api.js +112 -0
  90. package/player_api_gate/iframe_api/src/soundcloud_api.js +57 -0
  91. package/player_api_gate/iframe_api/src/url_proxy.js +28 -0
  92. package/player_api_gate/iframe_api/src/youtube_api.js +44 -0
  93. package/player_api_gate/iframe_api/wrangler.toml +51 -0
  94. package/player_api_gate/niconico-imager/cgi/go/src.go +74 -0
  95. package/player_api_gate/niconico-imager/cloudflare_workers/package-lock.json +2175 -0
  96. package/player_api_gate/niconico-imager/cloudflare_workers/package.json +12 -0
  97. package/player_api_gate/niconico-imager/cloudflare_workers/src/index.js +78 -0
  98. package/player_api_gate/niconico-imager/cloudflare_workers/wrangler.toml +3 -0
  99. package/test_script.html +172 -0
  100. package/tsconfig.json +36 -0
  101. package/dist/iframe_api/bilibili.d.ts +0 -91
  102. package/dist/iframe_api/bilibili.d.ts.map +0 -1
  103. package/dist/iframe_api/bilibili.js +0 -451
  104. package/dist/iframe_api/bilibili.js.map +0 -1
  105. package/dist/iframe_api/index.d.ts +0 -6
  106. package/dist/iframe_api/index.d.ts.map +0 -1
  107. package/dist/iframe_api/index.js +0 -8
  108. package/dist/iframe_api/index.js.map +0 -1
  109. package/dist/iframe_api/niconico.d.ts +0 -42
  110. package/dist/iframe_api/niconico.d.ts.map +0 -1
  111. package/dist/iframe_api/niconico.js +0 -181
  112. package/dist/iframe_api/niconico.js.map +0 -1
  113. package/dist/iframe_api/soundcloud.d.ts +0 -80
  114. package/dist/iframe_api/soundcloud.d.ts.map +0 -1
  115. package/dist/iframe_api/soundcloud.js +0 -188
  116. package/dist/iframe_api/soundcloud.js.map +0 -1
  117. package/dist/iframe_api/youtube.d.ts +0 -133
  118. package/dist/iframe_api/youtube.d.ts.map +0 -1
  119. package/dist/iframe_api/youtube.js +0 -278
  120. package/dist/iframe_api/youtube.js.map +0 -1
  121. package/dist/multi_embed_player.d.ts +0 -48
  122. package/dist/multi_embed_player.d.ts.map +0 -1
  123. package/dist/multi_embed_player.js +0 -318
  124. package/dist/multi_embed_player.js.map +0 -1
  125. package/dist/types.d.ts +0 -126
  126. package/dist/types.d.ts.map +0 -1
  127. package/dist/types.js +0 -22
  128. package/dist/types.js.map +0 -1
@@ -0,0 +1,429 @@
1
+ // Notice! This file JSDOC is generated by gitHub copilot.
2
+ // So some of this JSDOC is not correct.
3
+ // Please refer to documents https://multi-embed-player.pages.dev/docs/reference/iframe_class/#mep_niconico-class
4
+
5
+ /**
6
+ * @typedef {Object} mep_niconico_load_object
7
+ * @property {string} videoId - The ID of the video.
8
+ * @property {number} [startSeconds] - The start time of the video.
9
+ * @property {number} [endSeconds] - The end time of the video.
10
+ */
11
+ interface mep_niconico_load_object {
12
+ videoId: string;
13
+ startSeconds?: number;
14
+ endSeconds?: number;
15
+ }
16
+
17
+ /**
18
+ * @typedef {Object} mep_niconico_playerVars
19
+ * @property {number} [startSeconds] - The start time of the video.
20
+ * @property {number} [endSeconds] - The end time of the video.
21
+ * @property {number} [autoplay] - Whether the video is on autoplay.
22
+ * @property {number} [displayComment] - Whether the video is on display comment mode.
23
+ */
24
+ interface mep_niconico_playerVars {
25
+ startSeconds?: number;
26
+ endSeconds?: number;
27
+ autoplay?: number;
28
+ displayComment?: number;
29
+ }
30
+
31
+ /**
32
+ * @typedef {Object} mep_niconico_content
33
+ * @property {string} videoId - The ID of the video.
34
+ * @property {number} width - The width of the player.
35
+ * @property {number} height - The height of the player.
36
+ * @property {mep_niconico_playerVars} playerVars - The player variables.
37
+ */
38
+ interface NiconicoPlayerState {
39
+ isRepeat: boolean;
40
+ playerStatus: number;
41
+ currentTime?: number; // ミリ秒単位
42
+ duration?: number; // ミリ秒単位
43
+ muted?: boolean; // ミュート状態
44
+ volume?: number; // 0-1の範囲
45
+ videoInfo?: {
46
+ title?: string; // 動画タイトル
47
+ };
48
+ }
49
+
50
+ interface mep_niconico_content {
51
+ videoId: string;
52
+ width: number;
53
+ height: number;
54
+ playerVars?: mep_niconico_playerVars;
55
+ }
56
+
57
+ interface NiconicoPlayMessage {
58
+ eventName: 'play';
59
+ }
60
+
61
+ interface NiconicoPauseMessage {
62
+ eventName: 'pause';
63
+ }
64
+
65
+ interface NiconicoSeekMessage {
66
+ eventName: 'seek';
67
+ data: {
68
+ time: number; // ミリ秒
69
+ };
70
+ }
71
+
72
+ interface NiconicoCommentVisibilityMessage {
73
+ eventName: 'commentVisibilityChange';
74
+ data: {
75
+ commentVisibility: boolean;
76
+ };
77
+ }
78
+
79
+ interface NiconicoMuteMessage {
80
+ eventName: 'mute';
81
+ data: {
82
+ mute: boolean;
83
+ };
84
+ }
85
+
86
+ interface NiconicoVolumeMessage {
87
+ eventName: 'volumeChange';
88
+ data: {
89
+ volume: number; // 0-1の範囲
90
+ };
91
+ }
92
+
93
+ type NiconicoPostMessage =
94
+ | NiconicoPlayMessage
95
+ | NiconicoPauseMessage
96
+ | NiconicoSeekMessage
97
+ | NiconicoCommentVisibilityMessage
98
+ | NiconicoMuteMessage
99
+ | NiconicoVolumeMessage;
100
+
101
+ /**
102
+ * Class representing a Niconico player.
103
+ */
104
+ class mep_niconico{
105
+ state: NiconicoPlayerState;
106
+ startSeconds: number;
107
+ player: HTMLIFrameElement;
108
+ playerId: string;
109
+ autoplay_flag: boolean;
110
+ endSeconds: number;
111
+ displayCommentMode: boolean | undefined;
112
+
113
+ /**
114
+ * The ID of the player.
115
+ * @type {number}
116
+ */
117
+ static playerId = 0;
118
+ /**
119
+ * The origin of the Niconico player.
120
+ * @type {string}
121
+ */
122
+ static origin = 'https://embed.nicovideo.jp';
123
+ /**
124
+ * The result of checking local storage.
125
+ * @type {boolean}
126
+ */
127
+ static localStorageCheck: boolean | null = null;
128
+ /**
129
+ * Create a Niconico player.
130
+ * @param {string|HTMLElement} replacing_element - The element to replace with the player.
131
+ * @param {Object} content - The content of the player.
132
+ * @param {Function} player_set_event_function - The function to set player events.
133
+ */
134
+ constructor(replacing_element: string | HTMLElement, content: mep_niconico_content, player_set_event_function?: (player: HTMLIFrameElement) => void){
135
+ /**
136
+ * The state of the player.
137
+ * @type {Object}
138
+ * @property {boolean} isRepeat - Whether the player is on repeat.
139
+ * @property {number} playerStatus - The status of the player.
140
+ */
141
+ let element: HTMLElement;
142
+ if(typeof replacing_element === "string"){
143
+ const found_element = document.getElementById(replacing_element);
144
+ if (!found_element) {
145
+ throw new Error(`Element with id "${replacing_element}" not found`);
146
+ }
147
+ element = found_element;
148
+ } else {
149
+ element = replacing_element;
150
+ }
151
+ this.state = {
152
+ isRepeat: false,
153
+ playerStatus: 0
154
+ };
155
+ this.#messageListener();
156
+ /**
157
+ * The start time of the player.
158
+ * @type {number}
159
+ */
160
+ this.startSeconds = 0;
161
+ if(content?.playerVars?.startSeconds!=undefined){
162
+ this.startSeconds = content?.playerVars?.startSeconds;
163
+ }
164
+ let niconico_doc = document.createElement("iframe");
165
+ niconico_doc.src = "https://embed.nicovideo.jp/watch/" + content["videoId"] + "?jsapi=1&playerId=" + String(mep_niconico.playerId) + "&from=" + String(this.startSeconds);
166
+ this.playerId = String(mep_niconico.playerId);
167
+ mep_niconico.playerId++;
168
+ niconico_doc.width = String(content["width"]);
169
+ niconico_doc.height = String(content["height"]);
170
+ niconico_doc.allow = "autoplay";//fix bug not autoplay on chrome
171
+ niconico_doc.allowFullscreen = true;//fix bug can't watch on full screen(all browser)
172
+ niconico_doc.style.border = "none";//fix bug display border on outer frame
173
+ element.replaceWith(niconico_doc);
174
+ /**
175
+ * The player element.
176
+ * @type {HTMLIFrameElement}
177
+ */
178
+ this.player = niconico_doc;
179
+ if(typeof player_set_event_function === "function"){
180
+ player_set_event_function(this.player);
181
+ }
182
+ /**
183
+ * Whether the player is on autoplay.
184
+ * @type {boolean}
185
+ */
186
+ this.autoplay_flag = false;
187
+ if(content?.playerVars?.autoplay==1){//終わり次第再生
188
+ this.autoplay_flag = true;
189
+ }
190
+ /**
191
+ * The end time of the player.
192
+ * @type {number}
193
+ */
194
+ this.endSeconds = -1;
195
+ if(content?.playerVars?.endSeconds!==undefined){
196
+ this.endSeconds = content?.playerVars?.endSeconds;
197
+ }
198
+ if(content?.playerVars?.displayComment!==undefined){
199
+ if(content?.playerVars?.displayComment==0){
200
+ this.displayCommentMode = false;
201
+ }
202
+ else if(content?.playerVars?.displayComment==1){
203
+ this.displayCommentMode = true;
204
+ }
205
+ }
206
+ }
207
+ /**
208
+ * Cue a video by ID.
209
+ * @param {mep_niconico_load_object} content - The content of the video.
210
+ */
211
+ cueVideoById(content: mep_niconico_load_object){
212
+ this.startSeconds = 0;
213
+ if(content["startSeconds"]!=undefined){
214
+ this.startSeconds = content["startSeconds"];
215
+ }
216
+ this.endSeconds = -1;
217
+ if(content["endSeconds"]!=undefined){
218
+ this.endSeconds = content["endSeconds"];
219
+ }
220
+ this.player.src = "https://embed.nicovideo.jp/watch/" + content["videoId"] + "?jsapi=1&playerId=" + String(this.playerId) + "&from=" + String(this.startSeconds);
221
+ this.autoplay_flag = false;
222
+ }
223
+ /**
224
+ * Load a video by ID.
225
+ * @param {mep_niconico_load_object} content - The content of the video.
226
+ */
227
+ loadVideoById(content: mep_niconico_load_object){
228
+ this.startSeconds = 0;
229
+ if(content["startSeconds"]!=undefined){
230
+ this.startSeconds = content["startSeconds"];
231
+ }
232
+ this.endSeconds = -1;
233
+ if(content["endSeconds"]!=undefined){
234
+ this.endSeconds = content["endSeconds"];
235
+ }
236
+ this.player.src = "https://embed.nicovideo.jp/watch/" + content["videoId"] + "?jsapi=1&playerId=" + String(this.playerId) + "&from=" + String(this.startSeconds);
237
+ this.autoplay_flag = true;
238
+ }
239
+ /**
240
+ * Get the real duration of the video.
241
+ * @returns {number} The duration of the video.
242
+ */
243
+ getRealDulation(): number{//original function
244
+ if(this.endSeconds==-1){
245
+ return this.getDuration() - this.startSeconds;
246
+ }
247
+ else{
248
+ return this.endSeconds - this.startSeconds;
249
+ }
250
+ }
251
+ /**
252
+ * Play the video.
253
+ */
254
+ playVideo(): void{
255
+ this.#postMessage({
256
+ eventName: 'play'
257
+ })
258
+ }
259
+ /**
260
+ * Pause the video.
261
+ */
262
+ pauseVideo(): void{
263
+ this.#postMessage({
264
+ eventName: 'pause'
265
+ })
266
+ }
267
+ /**
268
+ * Get the current time of the video.
269
+ * @returns {number} The current time of the video.
270
+ */
271
+ getCurrentTime(): number{
272
+ return (this.state.currentTime ?? 0)/1000;//msec->sec
273
+ }
274
+ /**
275
+ * Get the duration of the video.
276
+ * @returns {number} The duration of the video.
277
+ */
278
+ getDuration(): number{
279
+ return (this.state.duration ?? 0)/1000;//msec->sec
280
+ }
281
+ /**
282
+ * Get the title of the video.
283
+ * @returns {string} The title of the video.
284
+ */
285
+ getTitle(): string{
286
+ return this.state.videoInfo?.title ?? '';
287
+ }
288
+ /**
289
+ * Check if the video is muted.
290
+ * @returns {boolean} Whether the video is muted.
291
+ */
292
+ isMuted(): boolean{
293
+ return this.state.muted ?? false;
294
+ }
295
+ /**
296
+ * Get the volume of the video.
297
+ * @returns {number} The volume of the video.
298
+ */
299
+ getVolume(): number{
300
+ return Number(this.state.volume)*100;
301
+ }
302
+ /**
303
+ * Seek to a specific time in the video.
304
+ * @param {number} seconds - The time to seek to.
305
+ */
306
+ seekTo(seconds: number): void{
307
+ this.#postMessage({
308
+ eventName: 'seek',
309
+ data: {
310
+ time: seconds*1000//secounds->msec
311
+ }
312
+ })
313
+ }
314
+ /**
315
+ * Change the display comment mode of the video.
316
+ * @param {boolean} mode - The display comment mode to set.
317
+ */
318
+ displayComment(mode: boolean): void{
319
+ this.#postMessage({
320
+ eventName: "commentVisibilityChange",
321
+ data:{
322
+ commentVisibility: mode
323
+ }
324
+ })
325
+ }
326
+ /**
327
+ * Mute the video.
328
+ */
329
+ mute(): void{
330
+ this.#postMessage({
331
+ eventName: "mute",
332
+ data:{
333
+ mute:true
334
+ }
335
+ })
336
+ }
337
+ /**
338
+ * Unmute the video.
339
+ */
340
+ unMute(): void{
341
+ this.#postMessage({
342
+ eventName: "mute",
343
+ data:{
344
+ mute:false
345
+ }
346
+ })
347
+ }
348
+ /**
349
+ * Set the volume of the video.
350
+ * @param {number} volume - The volume to set.
351
+ */
352
+ setVolume(volume: number): void{
353
+ this.#postMessage({
354
+ eventName: "volumeChange",
355
+ data:{
356
+ volume: volume/100
357
+ }
358
+ })
359
+ }
360
+ /**
361
+ * Get the state of the player.
362
+ * @returns {number} The state of the player.
363
+ */
364
+ getPlayerState(): number{
365
+ if(this.getCurrentTime()>=this.getDuration()-0.5||(this.endSeconds!=-1&&this.getCurrentTime()>=(this.endSeconds-0.5))){//最後まで行った
366
+ return 4
367
+ }
368
+ else{
369
+ return this.state.playerStatus;
370
+ }
371
+ }
372
+ /**
373
+ * Post a message to the player.
374
+ * @param {Object} request - The request to post.
375
+ */
376
+ #postMessage(request: NiconicoPostMessage): void {
377
+ const message = Object.assign({
378
+ sourceConnectorType: 1,
379
+ playerId: this.playerId
380
+ }, request);
381
+ if (this.player.contentWindow) {
382
+ this.player.contentWindow.postMessage(message, (window as any).mep_niconico.origin);
383
+ }
384
+ }
385
+ /**
386
+ * Listen for messages from the player.
387
+ */
388
+ #messageListener(): void {
389
+ window.addEventListener('message', (e) => {
390
+ if (e.origin === (window as any).mep_niconico.origin && e.data.playerId === this.playerId) {
391
+ const { data } = e.data;
392
+ switch (e.data.eventName) {
393
+ case 'statusChange': {
394
+ break;
395
+ }
396
+ case 'error':{
397
+ this.player.dispatchEvent(new CustomEvent("onError", {detail:{code:500}}));
398
+ break;
399
+ }
400
+ case 'playerMetadataChange':{
401
+ break;
402
+ }
403
+ case 'loadComplete':{
404
+ if(this.autoplay_flag){
405
+ this.playVideo();
406
+ }
407
+ this.player.dispatchEvent(new Event("onReady"));
408
+ break;
409
+ }
410
+ case 'playerStatusChange':{
411
+ this.player.dispatchEvent(new CustomEvent("onStateChange", {detail: this.getPlayerState()}));
412
+ if(this.getCurrentTime()>=this.getDuration()-0.5||(this.endSeconds!=-1&&this.getCurrentTime()>=(this.endSeconds-0.5))){//最後まで行った
413
+ this.player.dispatchEvent(new Event("onEndVideo"));
414
+ }
415
+ break;
416
+ }
417
+ default:
418
+ console.log(e.data);
419
+ }
420
+
421
+ this.state = Object.assign({}, this.state, data);
422
+ if(this.endSeconds!=-1&&(this.state.currentTime ?? 0)>=this.endSeconds*1000){//終了時間の時自動で停止
423
+ this.pauseVideo();
424
+ }
425
+ }
426
+ });
427
+ }
428
+ }
429
+ (window as any).mep_niconico = mep_niconico;