@aigamo/nostalgic-diva 1.3.0 → 1.4.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.
- package/README.md +1 -1
- package/dist/components/NostalgicDivaProvider.d.ts +4 -1
- package/dist/components/PlayerContainer.d.ts +5 -3
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +431 -361
- package/dist/index.es.js.map +1 -1
- package/dist/players/AudioPlayerApi.d.ts +3 -2
- package/dist/players/ILogger.d.ts +39 -0
- package/dist/players/NiconicoPlayerApi.d.ts +3 -2
- package/dist/players/PlayerApi.d.ts +5 -7
- package/dist/players/PlayerApiImpl.d.ts +4 -3
- package/dist/players/SoundCloudPlayerApi.d.ts +3 -2
- package/dist/players/VimeoPlayerApi.d.ts +3 -2
- package/dist/players/YouTubePlayerApi.d.ts +3 -2
- package/dist/players/ensureScriptLoaded.d.ts +2 -1
- package/package.json +9 -9
- package/dist/global.d.ts +0 -757
- package/dist/players/PlayerConsole.d.ts +0 -8
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ React function components for imperatively controlling embedded players (audio,
|
|
|
4
4
|
|
|
5
5
|
This was originally developed in [VocaDB/vocadb#1101](https://github.com/VocaDB/vocadb/pull/1101) as a part of VocaDB.
|
|
6
6
|
|
|
7
|
-
NOTE: This is an independent fork of VocaDB/
|
|
7
|
+
NOTE: This is an independent fork of VocaDB/nostalgic-diva.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { IPlayerApi } from '../players';
|
|
3
|
+
import { ILogger } from '../players/ILogger';
|
|
3
4
|
interface NostalgicDivaContextProps extends IPlayerApi {
|
|
5
|
+
logger: ILogger;
|
|
4
6
|
playerApiRef: React.MutableRefObject<IPlayerApi | undefined>;
|
|
5
7
|
}
|
|
6
8
|
interface NostalgicDivaProviderProps {
|
|
9
|
+
logger?: ILogger;
|
|
7
10
|
children?: React.ReactNode;
|
|
8
11
|
}
|
|
9
|
-
export declare const NostalgicDivaProvider: ({ children, }: NostalgicDivaProviderProps) => React.ReactElement;
|
|
12
|
+
export declare const NostalgicDivaProvider: ({ logger, children, }: NostalgicDivaProviderProps) => React.ReactElement;
|
|
10
13
|
export declare const useNostalgicDiva: () => NostalgicDivaContextProps;
|
|
11
14
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { ILogger } from '../players/ILogger';
|
|
3
|
+
import { IPlayerApi, PlayerOptions, PlayerType } from '../players/PlayerApi';
|
|
3
4
|
import { PlayerApiImpl } from '../players/PlayerApiImpl';
|
|
4
5
|
export interface PlayerProps {
|
|
6
|
+
logger: ILogger;
|
|
5
7
|
type: PlayerType;
|
|
6
8
|
playerApiRef: React.MutableRefObject<IPlayerApi | undefined> | undefined;
|
|
7
9
|
videoId: string;
|
|
@@ -9,8 +11,8 @@ export interface PlayerProps {
|
|
|
9
11
|
}
|
|
10
12
|
interface PlayerContainerProps<TElement extends HTMLElement, TPlayer extends PlayerApiImpl<TElement>> extends PlayerProps {
|
|
11
13
|
loadScript: (() => Promise<void>) | undefined;
|
|
12
|
-
playerApiFactory: new (logger:
|
|
14
|
+
playerApiFactory: new (logger: ILogger, playerElementRef: React.MutableRefObject<TElement>, options: PlayerOptions | undefined) => TPlayer;
|
|
13
15
|
children: (playerElementRef: React.MutableRefObject<TElement>, videoId: string) => React.ReactNode;
|
|
14
16
|
}
|
|
15
|
-
export declare const PlayerContainer: <TElement extends HTMLElement, TPlayer extends PlayerApiImpl<TElement>>({ type, playerApiRef, videoId, options, loadScript, playerApiFactory, children, }: PlayerContainerProps<TElement, TPlayer>) => React.ReactElement<PlayerContainerProps<TElement, TPlayer>, string | React.JSXElementConstructor<any>>;
|
|
17
|
+
export declare const PlayerContainer: <TElement extends HTMLElement, TPlayer extends PlayerApiImpl<TElement>>({ logger, type, playerApiRef, videoId, options, loadScript, playerApiFactory, children, }: PlayerContainerProps<TElement, TPlayer>) => React.ReactElement<PlayerContainerProps<TElement, TPlayer>, string | React.JSXElementConstructor<any>>;
|
|
16
18
|
export {};
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var z=Object.defineProperty;var J=(s,a,e)=>a in s?z(s,a,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[a]=e;var m=(s,a,e)=>(J(s,typeof a!="symbol"?a+"":a,e),e);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const D=require("react"),K=s=>s&&typeof s=="object"&&"default"in s?s:{default:s},i=K(D);class T{constructor(a,e,t){this.logger=a,this.playerElementRef=e,this.options=t,this.logger.debug("ctor")}}class Y extends T{constructor(e,t,r){super(e,t,r);m(this,"player");this.player=t.current}async attach(){this.player.onerror=e=>{var t,r;return(r=(t=this.options)==null?void 0:t.onError)==null?void 0:r.call(t,e)},this.player.onloadeddata=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onLoaded)==null?void 0:t.call(e,{id:this.player.src})},this.player.onplay=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPlay)==null?void 0:t.call(e)},this.player.onpause=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPause)==null?void 0:t.call(e)},this.player.onended=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onEnded)==null?void 0:t.call(e)},this.player.ontimeupdate=()=>{var e,t;(t=(e=this.options)==null?void 0:e.onTimeUpdate)==null||t.call(e,{duration:this.player.duration,percent:this.player.currentTime/this.player.duration,seconds:this.player.currentTime})}}async detach(){this.player.onerror=null,this.player.onloadeddata=null,this.player.onplay=null,this.player.onpause=null,this.player.onended=null,this.player.ontimeupdate=null}async loadVideo(e){this.player.src=e}async play(){this.player.play()}async pause(){this.player.pause()}async setCurrentTime(e){this.player.currentTime=e}async setVolume(e){this.player.volume=e}async setMuted(e){this.player.muted=e}async getDuration(){return this.player.duration}async getCurrentTime(){return this.player.currentTime}}const g=class{static createMessage(a){return`[${g.title}] ${a}`}static assert(a,e,...t){console.assert(a,g.createMessage(e),...t)}static debug(a,...e){console.debug(g.createMessage(a),...e)}static error(a,...e){console.error(g.createMessage(a),...e)}static warn(a,...e){console.warn(g.createMessage(a),...e)}};let h=g;m(h,"title","nostalgic-diva");const k=class{constructor(a,e,t,r,u){m(this,"id");m(this,"impl");this.type=a,this.playerElementRef=e,this.options=t,this.loadScript=r,this.playerApiFactory=u,this.id=k.nextId++}createMessage(a){return`${this.type}#${this.id} ${a}`}debug(a,...e){h.debug(this.createMessage(a),...e)}error(a,...e){h.error(this.createMessage(a),...e)}async attach(a){var e;if(this.debug("attach",a),this.impl){this.debug("player is already attached");return}await((e=this.loadScript)==null?void 0:e.call(this)),this.debug("Attaching player..."),this.impl=new this.playerApiFactory(this,this.playerElementRef,this.options),await this.impl.attach(a),this.debug("player attached")}assertPlayerAttached(){h.assert(!!this.impl,"player is not attached")}async detach(){var a;this.debug("detach"),this.assertPlayerAttached(),await((a=this.impl)==null?void 0:a.detach()),this.impl=void 0}async loadVideo(a){var e;this.debug("loadVideo",a),this.assertPlayerAttached(),this.debug("Loading video..."),await((e=this.impl)==null?void 0:e.loadVideo(a)),this.debug("video loaded",a)}async play(){var a;this.debug("play"),this.assertPlayerAttached(),await((a=this.impl)==null?void 0:a.play())}async pause(){var a;this.debug("pause"),this.assertPlayerAttached(),await((a=this.impl)==null?void 0:a.pause())}async setCurrentTime(a){var e;this.debug("setCurrentTime",a),this.assertPlayerAttached(),await((e=this.impl)==null?void 0:e.setCurrentTime(a))}async setVolume(a){var e;this.debug("setVolume",a),this.assertPlayerAttached(),await((e=this.impl)==null?void 0:e.setVolume(a))}async setMuted(a){var e;this.debug("setMuted",a),this.assertPlayerAttached(),await((e=this.impl)==null?void 0:e.setMuted(a))}async getDuration(){var a;return this.debug("getDuration"),this.assertPlayerAttached(),await((a=this.impl)==null?void 0:a.getDuration())}async getCurrentTime(){var a;return this.debug("getCurrentTime"),this.assertPlayerAttached(),await((a=this.impl)==null?void 0:a.getCurrentTime())}};let b=k;m(b,"nextId",1);function Q(){const s=D.useRef(!0);return s.current?(s.current=!1,!0):s.current}const X=(s,a)=>s===a;function Z(s,a=X){const e=D.useRef(),t=D.useRef(s);return!Q()&&!a(t.current,s)&&(e.current=t.current,t.current=s),e.current}const P=({type:s,playerApiRef:a,videoId:e,options:t,loadScript:r,playerApiFactory:u,children:c})=>{h.debug("PlayerContainer");const n=i.default.useRef(e),o=i.default.useRef(void 0),[p,y]=i.default.useState();i.default.useEffect(()=>{const l=new b(s,o,t,r,u);return a&&(a.current=l),l.attach(n.current).then(()=>y(l)),()=>{a&&h.assert(l===a.current,"playerApi differs",l,a.current),l.detach().then(()=>y(void 0))}},[s,t,r,u,a]);const d=Z(e);return i.default.useEffect(()=>{d!==void 0&&(p==null||p.loadVideo(e))},[d,e,p]),i.default.createElement(i.default.Fragment,null,c(o,n.current))},j=i.default.memo(({...s})=>(h.debug("AudioPlayer"),i.default.createElement(P,{...s,loadScript:void 0,playerApiFactory:Y},(a,e)=>i.default.createElement("audio",{ref:a,src:e,style:{width:"100%",height:"100%"},preload:"auto",autoPlay:!0,controls:!0}))));var M=(s=>(s[s.Play=2]="Play",s[s.Pause=3]="Pause",s[s.End=4]="End",s))(M||{});const S=class extends T{constructor(e,t,r){super(e,t,r);m(this,"player");m(this,"duration");m(this,"currentTime");this.player=t.current}handleMessage(e){var r,u,c,n,o,p,y,d,l,v,C,N,A,L,I,F;if(e.origin!==S.origin)return;const t=e.data;switch(t.eventName){case"playerStatusChange":this.logger.debug(`player status changed: ${(r=M[t.data.playerStatus])!=null?r:t.data.playerStatus}`);break;case"statusChange":switch(this.logger.debug(`status changed: ${(u=M[t.data.playerStatus])!=null?u:t.data.playerStatus}`),t.data.playerStatus){case 2:(n=(c=this.options)==null?void 0:c.onPlay)==null||n.call(c);break;case 3:(p=(o=this.options)==null?void 0:o.onPause)==null||p.call(o);break;case 4:(d=(y=this.options)==null?void 0:y.onEnded)==null||d.call(y);break}break;case"playerMetadataChange":t.data.duration!==void 0&&(this.duration=t.data.duration/1e3),this.currentTime=t.data.currentTime===void 0?void 0:t.data.currentTime/1e3,(v=(l=this.options)==null?void 0:l.onTimeUpdate)==null||v.call(l,{duration:this.duration,percent:this.currentTime!==void 0&&this.duration!==void 0?this.currentTime/this.duration:void 0,seconds:this.currentTime});break;case"loadComplete":this.logger.debug("load completed"),this.duration=t.data.videoInfo.lengthInSeconds,(N=(C=this.options)==null?void 0:C.onLoaded)==null||N.call(C,{id:t.data.videoInfo.watchId});break;case"error":(L=(A=this.options)==null?void 0:A.onError)==null||L.call(A,t);break;case"player-error:video:play":case"player-error:video:seek":(F=(I=this.options)==null?void 0:I.onError)==null||F.call(I,t);break;default:this.logger.debug("message",t.eventName,t.data);break}}async attach(){window.addEventListener("message",this.handleMessage)}async detach(){window.removeEventListener("message",this.handleMessage)}async loadVideo(e){return new Promise((t,r)=>{this.duration=void 0,this.currentTime=void 0,this.player.onload=()=>{this.player.onload=null,t()},this.player.src=`https://embed.nicovideo.jp/watch/${e}?jsapi=1&playerId=1`})}postMessage(e){var t;(t=this.player.contentWindow)==null||t.postMessage({...e,playerId:"1",sourceConnectorType:1},S.origin)}async play(){this.postMessage({eventName:"play"})}async pause(){this.postMessage({eventName:"pause"})}async setCurrentTime(e){this.postMessage({eventName:"seek",data:{time:e*1e3}})}async setVolume(e){this.postMessage({eventName:"volumeChange",data:{volume:e}})}async setMuted(e){this.postMessage({eventName:"mute",data:{mute:e}})}async getDuration(){return this.duration}async getCurrentTime(){return this.currentTime}};let w=S;m(w,"origin","https://embed.nicovideo.jp");const W=i.default.memo(({...s})=>(h.debug("NiconicoPlayer"),i.default.createElement(P,{...s,loadScript:void 0,playerApiFactory:w},(a,e)=>i.default.createElement("div",{style:{width:"100%",height:"100%"}},i.default.createElement("iframe",{ref:a,src:`https://embed.nicovideo.jp/watch/${e}?jsapi=1&playerId=1`,width:"100%",height:"100%",allowFullScreen:!0,style:{border:"none"},allow:"autoplay; fullscreen"}))))),G=i.default.createContext(void 0),_=({children:s})=>{const a=i.default.useRef(),e=i.default.useCallback(async d=>{var l;await((l=a.current)==null?void 0:l.loadVideo(d))},[]),t=i.default.useCallback(async()=>{var d;await((d=a.current)==null?void 0:d.play())},[]),r=i.default.useCallback(async()=>{var d;await((d=a.current)==null?void 0:d.pause())},[]),u=i.default.useCallback(async d=>{const l=a.current;!l||(await l.setCurrentTime(d),await l.play())},[]),c=i.default.useCallback(async d=>{var l;await((l=a.current)==null?void 0:l.setVolume(d))},[]),n=i.default.useCallback(async d=>{var l;await((l=a.current)==null?void 0:l.setMuted(d))},[]),o=i.default.useCallback(async()=>{var d;return await((d=a.current)==null?void 0:d.getDuration())},[]),p=i.default.useCallback(async()=>{var d;return await((d=a.current)==null?void 0:d.getCurrentTime())},[]),y=i.default.useMemo(()=>({playerApiRef:a,loadVideo:e,play:t,pause:r,setCurrentTime:u,setVolume:c,setMuted:n,getDuration:o,getCurrentTime:p}),[e,t,r,u,c,n,o,p]);return i.default.createElement(G.Provider,{value:y},s)},$=()=>i.default.useContext(G);class f extends T{constructor(e,t,r){super(e,t,r);m(this,"player");this.player=SC.Widget(this.playerElementRef.current)}static playerGetDurationAsync(e){return new Promise((t,r)=>{e.getDuration(t)})}attach(e){return new Promise((t,r)=>{this.player.bind(SC.Widget.Events.READY,()=>{var u,c;this.player.bind(SC.Widget.Events.PLAY_PROGRESS,async n=>{var p,y;const o=await f.playerGetDurationAsync(this.player);(y=(p=this.options)==null?void 0:p.onTimeUpdate)==null||y.call(p,{duration:o/1e3,percent:n.currentPosition/o,seconds:n.currentPosition/1e3})}),this.player.bind(SC.Widget.Events.ERROR,n=>{var o,p;return(p=(o=this.options)==null?void 0:o.onError)==null?void 0:p.call(o,n)}),this.player.bind(SC.Widget.Events.PLAY,()=>{var n,o;return(o=(n=this.options)==null?void 0:n.onPlay)==null?void 0:o.call(n)}),this.player.bind(SC.Widget.Events.PAUSE,()=>{var n,o;return(o=(n=this.options)==null?void 0:n.onPause)==null?void 0:o.call(n)}),this.player.bind(SC.Widget.Events.FINISH,()=>{var n,o;return(o=(n=this.options)==null?void 0:n.onEnded)==null?void 0:o.call(n)}),(c=(u=this.options)==null?void 0:u.onLoaded)==null||c.call(u,{id:e}),t()})})}async detach(){this.player.unbind(SC.Widget.Events.READY),this.player.unbind(SC.Widget.Events.PLAY_PROGRESS),this.player.unbind(SC.Widget.Events.ERROR),this.player.unbind(SC.Widget.Events.PLAY),this.player.unbind(SC.Widget.Events.PAUSE),this.player.unbind(SC.Widget.Events.FINISH)}static playerLoadAsync(e,t,r){return new Promise((u,c)=>{e.load(t,{...r,callback:u})})}async loadVideo(e){var t,r;await f.playerLoadAsync(this.player,e,{auto_play:!0}),(r=(t=this.options)==null?void 0:t.onLoaded)==null||r.call(t,{id:e})}async play(){this.player.play()}async pause(){this.player.pause()}async setCurrentTime(e){this.player.seekTo(e*1e3)}async setVolume(e){this.player.setVolume(e*100)}async setMuted(e){this.setVolume(e?0:1)}async getDuration(){return await f.playerGetDurationAsync(this.player)/1e3}static playerGetPositionAsync(e){return new Promise((t,r)=>{e.getPosition(t)})}async getCurrentTime(){return await f.playerGetPositionAsync(this.player)/1e3}}function ee(s){return new Promise((a,e)=>{const t=document.createElement("script");t.src=s,t.async=!0,t.onerror=e,t.onload=t.onreadystatechange=function(){const r=this.readyState;r&&r!=="loaded"&&r!=="complete"||(t.onload=t.onreadystatechange=null,a())},document.head.appendChild(t)})}const V=[];async function U(s){if(V.includes(s))return h.debug(s,"script is already loaded"),!1;try{return h.debug(s,"Loading script..."),await ee(s),V.includes(s)?(h.debug(s,"script is already loaded"),!1):(V.push(s),h.debug(s,"script loaded"),!0)}catch(a){throw h.error(s,"Failed to load script"),a}}const x=i.default.memo(({...s})=>{h.debug("SoundCloudPlayer");const a=i.default.useCallback(async()=>{await U("https://w.soundcloud.com/player/api.js")},[]);return i.default.createElement(P,{...s,loadScript:a,playerApiFactory:f},(e,t)=>i.default.createElement("iframe",{ref:e,src:`https://w.soundcloud.com/player/?url=${t}`,frameBorder:0,allow:"autoplay",style:{width:"100%",height:"100%"}}))});class B extends T{constructor(e,t,r){super(e,t,r);m(this,"player");this.player=new Vimeo.Player(this.playerElementRef.current)}async attach(){await this.player.ready(),this.player.on("error",e=>{var t,r;return(r=(t=this.options)==null?void 0:t.onError)==null?void 0:r.call(t,e)}),this.player.on("loaded",e=>{var t,r;return(r=(t=this.options)==null?void 0:t.onLoaded)==null?void 0:r.call(t,{id:e.id.toString()})}),this.player.on("play",()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPlay)==null?void 0:t.call(e)}),this.player.on("pause",()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPause)==null?void 0:t.call(e)}),this.player.on("ended",()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onEnded)==null?void 0:t.call(e)}),this.player.on("timeupdate",e=>{var t,r;(r=(t=this.options)==null?void 0:t.onTimeUpdate)==null||r.call(t,{duration:e.duration,percent:e.percent,seconds:e.seconds})})}async detach(){this.player.off("error"),this.player.off("loaded"),this.player.off("play"),this.player.off("pause"),this.player.off("ended"),this.player.off("timeupdate")}async loadVideo(e){await this.player.loadVideo(e)}async play(){await this.player.play()}async pause(){await this.player.pause()}async setCurrentTime(e){await this.player.setCurrentTime(e)}async setVolume(e){await this.player.setVolume(e)}async setMuted(e){await this.player.setMuted(e)}async getDuration(){return await this.player.getDuration()}async getCurrentTime(){return await this.player.getCurrentTime()}}const O=i.default.memo(({...s})=>{h.debug("VimeoPlayer");const a=i.default.useCallback(async()=>{await U("https://player.vimeo.com/api/player.js")},[]);return i.default.createElement(P,{...s,loadScript:a,playerApiFactory:B},(e,t)=>i.default.createElement("iframe",{ref:e,src:`https://player.vimeo.com/video/${t}`,frameBorder:0,allow:"autoplay",style:{width:"100%",height:"100%"}}))});var q=(s=>(s[s.UNSTARTED=-1]="UNSTARTED",s[s.ENDED=0]="ENDED",s[s.PLAYING=1]="PLAYING",s[s.PAUSED=2]="PAUSED",s[s.BUFFERING=3]="BUFFERING",s[s.CUED=5]="CUED",s))(q||{});const R=class extends T{constructor(e,t,r){super(e,t,r);m(this,"player");m(this,"previousTime");m(this,"timeUpdateIntervalId");this.player=new YT.Player(this.playerElementRef.current,{host:R.origin,width:"100%",height:"100%"})}clearTimeUpdateInterval(){this.logger.debug("clearTimeUpdateInterval",this.timeUpdateIntervalId),window.clearInterval(this.timeUpdateIntervalId),this.timeUpdateIntervalId=void 0}invokeTimeUpdate(e){var u,c;const t=e.getCurrentTime();if(t===this.previousTime)return;const r=e.getDuration();(c=(u=this.options)==null?void 0:u.onTimeUpdate)==null||c.call(u,{duration:r,percent:t/r,seconds:t}),this.previousTime=t}setTimeUpdateInterval(){this.logger.debug("setTimeUpdateInterval"),this.clearTimeUpdateInterval(),this.timeUpdateIntervalId=window.setInterval(()=>this.invokeTimeUpdate(this.player),250),this.logger.debug("timeUpdateIntervalId",this.timeUpdateIntervalId),this.invokeTimeUpdate(this.player)}attach(e){return new Promise((t,r)=>{this.player.addEventListener("onReady",async()=>{this.player.addEventListener("onError",u=>{var c,n;return(n=(c=this.options)==null?void 0:c.onError)==null?void 0:n.call(c,u.data)}),this.player.addEventListener("onStateChange",u=>{var c,n,o,p,y,d,l,v;switch(this.logger.debug(`state changed: ${q[u.data]}`),u.data){case YT.PlayerState.CUED:(n=(c=this.options)==null?void 0:c.onLoaded)==null||n.call(c,{id:e});break;case YT.PlayerState.PLAYING:(p=(o=this.options)==null?void 0:o.onPlay)==null||p.call(o),this.setTimeUpdateInterval();break;case YT.PlayerState.PAUSED:(d=(y=this.options)==null?void 0:y.onPause)==null||d.call(y),this.clearTimeUpdateInterval();break;case YT.PlayerState.ENDED:(v=(l=this.options)==null?void 0:l.onEnded)==null||v.call(l),this.clearTimeUpdateInterval();break}}),await this.loadVideo(e),t()})})}async detach(){this.clearTimeUpdateInterval()}async loadVideo(e){this.previousTime=void 0,this.player.cueVideoById(e)}async play(){this.player.playVideo()}async pause(){this.player.pauseVideo()}async setCurrentTime(e){this.player.seekTo(e),this.invokeTimeUpdate(this.player)}async setVolume(e){this.player.setVolume(e*100)}async setMuted(e){e?this.player.mute():this.player.unMute()}async getDuration(){return this.player.getDuration()}async getCurrentTime(){return this.player.getCurrentTime()}};let E=R;m(E,"origin","https://www.youtube-nocookie.com");const H=i.default.memo(({...s})=>{h.debug("YouTubePlayer");const a=i.default.useCallback(()=>new Promise(async(e,t)=>{await U("https://www.youtube.com/iframe_api")?window.onYouTubeIframeAPIReady=()=>{h.debug("YouTube iframe API ready"),e()}:e()}),[]);return i.default.createElement(P,{...s,loadScript:a,playerApiFactory:E},e=>i.default.createElement("div",{style:{width:"100%",height:"100%"}},i.default.createElement("div",{ref:e})))}),te={Audio:j,Niconico:W,SoundCloud:x,Vimeo:O,YouTube:H},ae=i.default.memo(({type:s,videoId:a,options:e})=>{h.debug("NostalgicDiva");const t=$(),r=te[s];return i.default.createElement(r,{type:s,playerApiRef:t.playerApiRef,videoId:a,options:e})});exports.AudioPlayer=j;exports.AudioPlayerApi=Y;exports.NiconicoPlayer=W;exports.NiconicoPlayerApi=w;exports.NostalgicDiva=ae;exports.NostalgicDivaProvider=_;exports.PlayerApi=b;exports.SoundCloudPlayer=x;exports.SoundCloudPlayerApi=f;exports.VimeoPlayer=O;exports.VimeoPlayerApi=B;exports.YouTubePlayer=H;exports.YouTubePlayerApi=E;exports.useNostalgicDiva=$;
|
|
1
|
+
"use strict";var O=Object.defineProperty;var q=(a,r,e)=>r in a?O(a,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[r]=e;var m=(a,r,e)=>(q(a,typeof r!="symbol"?r+"":r,e),e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react");var u=(a=>(a[a.Trace=0]="Trace",a[a.Debug=1]="Debug",a[a.Information=2]="Information",a[a.Warning=3]="Warning",a[a.Error=4]="Error",a[a.Critical=5]="Critical",a[a.None=6]="None",a))(u||{});class f{constructor(r,e,t){this.logger=r,this.playerElementRef=e,this.options=t,this.logger.log(u.Debug,"ctor")}}class M extends f{constructor(e,t,i){super(e,t,i);m(this,"player");this.player=t.current}async attach(){this.player.onerror=e=>{var t,i;return(i=(t=this.options)==null?void 0:t.onError)==null?void 0:i.call(t,e)},this.player.onloadeddata=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onLoaded)==null?void 0:t.call(e,{id:this.player.src})},this.player.onplay=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPlay)==null?void 0:t.call(e)},this.player.onpause=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPause)==null?void 0:t.call(e)},this.player.onended=()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onEnded)==null?void 0:t.call(e)},this.player.ontimeupdate=()=>{var e,t;(t=(e=this.options)==null?void 0:e.onTimeUpdate)==null||t.call(e,{duration:this.player.duration,percent:this.player.currentTime/this.player.duration,seconds:this.player.currentTime})}}async detach(){this.player.onerror=null,this.player.onloadeddata=null,this.player.onplay=null,this.player.onpause=null,this.player.onended=null,this.player.ontimeupdate=null}async loadVideo(e){this.player.src=e}async play(){this.player.play()}async pause(){this.player.pause()}async setCurrentTime(e){this.player.currentTime=e}async setVolume(e){this.player.volume=e}async setMuted(e){this.player.muted=e}async getDuration(){return this.player.duration}async getCurrentTime(){return this.player.currentTime}}const S=class{constructor(r,e,t,i,c,d){m(this,"id");m(this,"impl");this.logger=r,this.type=e,this.playerElementRef=t,this.options=i,this.loadScript=c,this.playerApiFactory=d,this.id=S.nextId++}createMessage(r){return`${this.type}#${this.id} ${r}`}debug(r,...e){this.logger.log(u.Debug,this.createMessage(r),...e)}error(r,...e){this.logger.log(u.Error,this.createMessage(r),...e)}async attach(r){var e;if(this.debug("attach",r),this.impl){this.debug("player is already attached");return}await((e=this.loadScript)==null?void 0:e.call(this)),this.debug("Attaching player..."),this.impl=new this.playerApiFactory(this.logger,this.playerElementRef,this.options),await this.impl.attach(r),this.debug("player attached")}createPlayerNotAttachedError(){return new Error("player is not attached")}async detach(){if(this.debug("detach"),this.impl===void 0)throw this.createPlayerNotAttachedError();await this.impl.detach(),this.impl=void 0}async loadVideo(r){if(this.debug("loadVideo",r),this.impl===void 0)throw this.createPlayerNotAttachedError();this.debug("Loading video..."),await this.impl.loadVideo(r),this.debug("video loaded",r)}play(){if(this.debug("play"),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.play()}pause(){if(this.debug("pause"),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.pause()}setCurrentTime(r){if(this.debug("setCurrentTime",r),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.setCurrentTime(r)}setVolume(r){if(this.debug("setVolume",r),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.setVolume(r)}setMuted(r){if(this.debug("setMuted",r),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.setMuted(r)}getDuration(){if(this.debug("getDuration"),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.getDuration()}getCurrentTime(){if(this.debug("getCurrentTime"),this.impl===void 0)throw this.createPlayerNotAttachedError();return this.impl.getCurrentTime()}};let w=S;m(w,"nextId",1);function H(){const a=s.useRef(!0);return a.current?(a.current=!1,!0):a.current}const z=(a,r)=>a===r;function J(a,r=z){const e=s.useRef(),t=s.useRef(a);return!H()&&!r(t.current,a)&&(e.current=t.current,t.current=a),e.current}const T=({logger:a,type:r,playerApiRef:e,videoId:t,options:i,loadScript:c,playerApiFactory:d,children:n})=>{a.log(u.Debug,"PlayerContainer");const o=s.useRef(t),y=s.useRef(void 0),[p,g]=s.useState();s.useEffect(()=>{const h=new w(a,r,y,i,c,d);return e&&(e.current=h),h.attach(o.current).then(()=>g(h)),()=>{if(e&&h!==e.current)throw new Error("playerApi differs");h.detach().then(()=>g(void 0))}},[a,r,i,c,d,e]);const l=J(t);return s.useEffect(()=>{l!==void 0&&(p==null||p.loadVideo(t))},[l,t,p]),s.createElement(s.Fragment,null,n(y,o.current))},R=s.memo(({...a})=>{const{logger:r}=a;return r.log(u.Debug,"AudioPlayer"),s.createElement(T,{...a,loadScript:void 0,playerApiFactory:M},(e,t)=>s.createElement("audio",{ref:e,src:t,style:{width:"100%",height:"100%"},preload:"auto",autoPlay:!0,controls:!0}))});var I=(a=>(a[a.Play=2]="Play",a[a.Pause=3]="Pause",a[a.End=4]="End",a))(I||{});const P=class extends f{constructor(e,t,i){super(e,t,i);m(this,"player");m(this,"duration");m(this,"currentTime");this.player=t.current}handleMessage(e){var i,c,d,n,o,y,p,g,l,h,C,V,D,U;if(e.origin!==P.origin)return;const t=e.data;switch(t.eventName){case"playerStatusChange":this.logger.log(u.Debug,`player status changed: ${I[t.data.playerStatus]??t.data.playerStatus}`);break;case"statusChange":switch(this.logger.log(u.Debug,`status changed: ${I[t.data.playerStatus]??t.data.playerStatus}`),t.data.playerStatus){case 2:(c=(i=this.options)==null?void 0:i.onPlay)==null||c.call(i);break;case 3:(n=(d=this.options)==null?void 0:d.onPause)==null||n.call(d);break;case 4:(y=(o=this.options)==null?void 0:o.onEnded)==null||y.call(o);break}break;case"playerMetadataChange":t.data.duration!==void 0&&(this.duration=t.data.duration/1e3),this.currentTime=t.data.currentTime===void 0?void 0:t.data.currentTime/1e3,(g=(p=this.options)==null?void 0:p.onTimeUpdate)==null||g.call(p,{duration:this.duration,percent:this.currentTime!==void 0&&this.duration!==void 0?this.currentTime/this.duration:void 0,seconds:this.currentTime});break;case"loadComplete":this.logger.log(u.Debug,"load completed"),this.duration=t.data.videoInfo.lengthInSeconds,(h=(l=this.options)==null?void 0:l.onLoaded)==null||h.call(l,{id:t.data.videoInfo.watchId});break;case"error":(V=(C=this.options)==null?void 0:C.onError)==null||V.call(C,t);break;case"player-error:video:play":case"player-error:video:seek":(U=(D=this.options)==null?void 0:D.onError)==null||U.call(D,t);break;default:this.logger.log(u.Debug,"message",t.eventName,t.data);break}}async attach(){window.addEventListener("message",this.handleMessage)}async detach(){window.removeEventListener("message",this.handleMessage)}async loadVideo(e){return new Promise((t,i)=>{this.duration=void 0,this.currentTime=void 0,this.player.onload=()=>{this.player.onload=null,t()},this.player.src=`https://embed.nicovideo.jp/watch/${e}?jsapi=1&playerId=1`})}postMessage(e){var t;(t=this.player.contentWindow)==null||t.postMessage({...e,playerId:"1",sourceConnectorType:1},P.origin)}async play(){this.postMessage({eventName:"play"})}async pause(){this.postMessage({eventName:"pause"})}async setCurrentTime(e){this.postMessage({eventName:"seek",data:{time:e*1e3}})}async setVolume(e){this.postMessage({eventName:"volumeChange",data:{volume:e}})}async setMuted(e){this.postMessage({eventName:"mute",data:{mute:e}})}async getDuration(){return this.duration}async getCurrentTime(){return this.currentTime}};let E=P;m(E,"origin","https://embed.nicovideo.jp");const F=s.memo(({...a})=>{const{logger:r}=a;return r.log(u.Debug,"NiconicoPlayer"),s.createElement(T,{...a,loadScript:void 0,playerApiFactory:E},(e,t)=>s.createElement("div",{style:{width:"100%",height:"100%"}},s.createElement("iframe",{ref:e,src:`https://embed.nicovideo.jp/watch/${t}?jsapi=1&playerId=1`,width:"100%",height:"100%",allowFullScreen:!0,style:{border:"none"},allow:"autoplay; fullscreen"})))}),Y=s.createContext(void 0),K=new class{constructor(){m(this,"title","nostalgic-diva")}createMessage(a){return`[${this.title}] ${a}`}debug(a,...r){console.debug(this.createMessage(a),...r)}error(a,...r){console.error(this.createMessage(a),...r)}warn(a,...r){console.warn(this.createMessage(a),...r)}isEnabled(){return!0}log(a,r,...e){switch(a){case u.Debug:this.debug(r,...e);break;case u.Warning:this.warn(r,...e);break;case u.Error:this.error(r,...e);break}}},Q=({logger:a=K,children:r})=>{const e=s.useRef(),t=s.useCallback(async l=>{var h;await((h=e.current)==null?void 0:h.loadVideo(l))},[]),i=s.useCallback(async()=>{var l;await((l=e.current)==null?void 0:l.play())},[]),c=s.useCallback(async()=>{var l;await((l=e.current)==null?void 0:l.pause())},[]),d=s.useCallback(async l=>{const h=e.current;h&&(await h.setCurrentTime(l),await h.play())},[]),n=s.useCallback(async l=>{var h;await((h=e.current)==null?void 0:h.setVolume(l))},[]),o=s.useCallback(async l=>{var h;await((h=e.current)==null?void 0:h.setMuted(l))},[]),y=s.useCallback(async()=>{var l;return await((l=e.current)==null?void 0:l.getDuration())},[]),p=s.useCallback(async()=>{var l;return await((l=e.current)==null?void 0:l.getCurrentTime())},[]),g=s.useMemo(()=>({logger:a,playerApiRef:e,loadVideo:t,play:i,pause:c,setCurrentTime:d,setVolume:n,setMuted:o,getDuration:y,getCurrentTime:p}),[a,t,i,c,d,n,o,y,p]);return s.createElement(Y.Provider,{value:g},r)},W=()=>s.useContext(Y);class b extends f{constructor(e,t,i){super(e,t,i);m(this,"player");this.player=SC.Widget(this.playerElementRef.current)}static playerGetDurationAsync(e){return new Promise((t,i)=>{e.getDuration(t)})}attach(e){return new Promise((t,i)=>{this.player.bind(SC.Widget.Events.READY,()=>{var c,d;this.player.bind(SC.Widget.Events.PLAY_PROGRESS,async n=>{var y,p;const o=await b.playerGetDurationAsync(this.player);(p=(y=this.options)==null?void 0:y.onTimeUpdate)==null||p.call(y,{duration:o/1e3,percent:n.currentPosition/o,seconds:n.currentPosition/1e3})}),this.player.bind(SC.Widget.Events.ERROR,n=>{var o,y;return(y=(o=this.options)==null?void 0:o.onError)==null?void 0:y.call(o,n)}),this.player.bind(SC.Widget.Events.PLAY,()=>{var n,o;return(o=(n=this.options)==null?void 0:n.onPlay)==null?void 0:o.call(n)}),this.player.bind(SC.Widget.Events.PAUSE,()=>{var n,o;return(o=(n=this.options)==null?void 0:n.onPause)==null?void 0:o.call(n)}),this.player.bind(SC.Widget.Events.FINISH,()=>{var n,o;return(o=(n=this.options)==null?void 0:n.onEnded)==null?void 0:o.call(n)}),(d=(c=this.options)==null?void 0:c.onLoaded)==null||d.call(c,{id:e}),t()})})}async detach(){this.player.unbind(SC.Widget.Events.READY),this.player.unbind(SC.Widget.Events.PLAY_PROGRESS),this.player.unbind(SC.Widget.Events.ERROR),this.player.unbind(SC.Widget.Events.PLAY),this.player.unbind(SC.Widget.Events.PAUSE),this.player.unbind(SC.Widget.Events.FINISH)}static playerLoadAsync(e,t,i){return new Promise((c,d)=>{e.load(t,{...i,callback:c})})}async loadVideo(e){var t,i;await b.playerLoadAsync(this.player,e,{auto_play:!0}),(i=(t=this.options)==null?void 0:t.onLoaded)==null||i.call(t,{id:e})}async play(){this.player.play()}async pause(){this.player.pause()}async setCurrentTime(e){this.player.seekTo(e*1e3)}async setVolume(e){this.player.setVolume(e*100)}async setMuted(e){this.setVolume(e?0:1)}async getDuration(){return await b.playerGetDurationAsync(this.player)/1e3}static playerGetPositionAsync(e){return new Promise((t,i)=>{e.getPosition(t)})}async getCurrentTime(){return await b.playerGetPositionAsync(this.player)/1e3}}function X(a){return new Promise((r,e)=>{const t=document.createElement("script");t.src=a,t.async=!0,t.onerror=e,t.onload=t.onreadystatechange=function(){const i=this.readyState;i&&i!=="loaded"&&i!=="complete"||(t.onload=t.onreadystatechange=null,r())},document.head.appendChild(t)})}const A=[];async function N(a,r){if(A.includes(a))return r.log(u.Debug,a,"script is already loaded"),!1;try{return r.log(u.Debug,a,"Loading script..."),await X(a),A.includes(a)?(r.log(u.Debug,a,"script is already loaded"),!1):(A.push(a),r.log(u.Debug,a,"script loaded"),!0)}catch(e){throw r.log(u.Error,a,"Failed to load script"),e}}const j=s.memo(({...a})=>{const{logger:r}=a;r.log(u.Debug,"SoundCloudPlayer");const e=s.useCallback(async()=>{await N("https://w.soundcloud.com/player/api.js",r)},[r]);return s.createElement(T,{...a,loadScript:e,playerApiFactory:b},(t,i)=>s.createElement("iframe",{ref:t,src:`https://w.soundcloud.com/player/?url=${i}`,frameBorder:0,allow:"autoplay",style:{width:"100%",height:"100%"}}))});class G extends f{constructor(e,t,i){super(e,t,i);m(this,"player");this.player=new Vimeo.Player(this.playerElementRef.current)}async attach(){await this.player.ready(),this.player.on("error",e=>{var t,i;return(i=(t=this.options)==null?void 0:t.onError)==null?void 0:i.call(t,e)}),this.player.on("loaded",e=>{var t,i;return(i=(t=this.options)==null?void 0:t.onLoaded)==null?void 0:i.call(t,{id:e.id.toString()})}),this.player.on("play",()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPlay)==null?void 0:t.call(e)}),this.player.on("pause",()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onPause)==null?void 0:t.call(e)}),this.player.on("ended",()=>{var e,t;return(t=(e=this.options)==null?void 0:e.onEnded)==null?void 0:t.call(e)}),this.player.on("timeupdate",e=>{var t,i;(i=(t=this.options)==null?void 0:t.onTimeUpdate)==null||i.call(t,{duration:e.duration,percent:e.percent,seconds:e.seconds})})}async detach(){this.player.off("error"),this.player.off("loaded"),this.player.off("play"),this.player.off("pause"),this.player.off("ended"),this.player.off("timeupdate")}async loadVideo(e){await this.player.loadVideo(e)}async play(){await this.player.play()}async pause(){await this.player.pause()}async setCurrentTime(e){await this.player.setCurrentTime(e)}async setVolume(e){await this.player.setVolume(e)}async setMuted(e){await this.player.setMuted(e)}async getDuration(){return await this.player.getDuration()}async getCurrentTime(){return await this.player.getCurrentTime()}}const $=s.memo(({...a})=>{const{logger:r}=a;r.log(u.Debug,"VimeoPlayer");const e=s.useCallback(async()=>{await N("https://player.vimeo.com/api/player.js",r)},[r]);return s.createElement(T,{...a,loadScript:e,playerApiFactory:G},(t,i)=>s.createElement("iframe",{ref:t,src:`https://player.vimeo.com/video/${i}`,frameBorder:0,allow:"autoplay",style:{width:"100%",height:"100%"}}))});var x=(a=>(a[a.UNSTARTED=-1]="UNSTARTED",a[a.ENDED=0]="ENDED",a[a.PLAYING=1]="PLAYING",a[a.PAUSED=2]="PAUSED",a[a.BUFFERING=3]="BUFFERING",a[a.CUED=5]="CUED",a))(x||{});const k=class extends f{constructor(e,t,i){super(e,t,i);m(this,"player");m(this,"previousTime");m(this,"timeUpdateIntervalId");this.player=new YT.Player(this.playerElementRef.current,{host:k.origin,width:"100%",height:"100%"})}clearTimeUpdateInterval(){this.logger.log(u.Debug,"clearTimeUpdateInterval",this.timeUpdateIntervalId),window.clearInterval(this.timeUpdateIntervalId),this.timeUpdateIntervalId=void 0}invokeTimeUpdate(e){var c,d;const t=e.getCurrentTime();if(t===this.previousTime)return;const i=e.getDuration();(d=(c=this.options)==null?void 0:c.onTimeUpdate)==null||d.call(c,{duration:i,percent:t/i,seconds:t}),this.previousTime=t}setTimeUpdateInterval(){this.logger.log(u.Debug,"setTimeUpdateInterval"),this.clearTimeUpdateInterval(),this.timeUpdateIntervalId=window.setInterval(()=>this.invokeTimeUpdate(this.player),250),this.logger.log(u.Debug,"timeUpdateIntervalId",this.timeUpdateIntervalId),this.invokeTimeUpdate(this.player)}attach(e){return new Promise((t,i)=>{this.player.addEventListener("onReady",async()=>{this.player.addEventListener("onError",c=>{var d,n;return(n=(d=this.options)==null?void 0:d.onError)==null?void 0:n.call(d,c.data)}),this.player.addEventListener("onStateChange",c=>{var d,n,o,y,p,g,l,h;switch(this.logger.log(u.Debug,`state changed: ${x[c.data]}`),c.data){case YT.PlayerState.CUED:(n=(d=this.options)==null?void 0:d.onLoaded)==null||n.call(d,{id:e});break;case YT.PlayerState.PLAYING:(y=(o=this.options)==null?void 0:o.onPlay)==null||y.call(o),this.setTimeUpdateInterval();break;case YT.PlayerState.PAUSED:(g=(p=this.options)==null?void 0:p.onPause)==null||g.call(p),this.clearTimeUpdateInterval();break;case YT.PlayerState.ENDED:(h=(l=this.options)==null?void 0:l.onEnded)==null||h.call(l),this.clearTimeUpdateInterval();break}}),await this.loadVideo(e),t()})})}async detach(){this.clearTimeUpdateInterval()}async loadVideo(e){this.previousTime=void 0,this.player.cueVideoById(e)}async play(){this.player.playVideo()}async pause(){this.player.pauseVideo()}async setCurrentTime(e){this.player.seekTo(e),this.invokeTimeUpdate(this.player)}async setVolume(e){this.player.setVolume(e*100)}async setMuted(e){e?this.player.mute():this.player.unMute()}async getDuration(){return this.player.getDuration()}async getCurrentTime(){return this.player.getCurrentTime()}};let v=k;m(v,"origin","https://www.youtube-nocookie.com");const B=s.memo(({...a})=>{const{logger:r}=a;r.log(u.Debug,"YouTubePlayer");const e=s.useCallback(()=>new Promise(async(t,i)=>{await N("https://www.youtube.com/iframe_api",r)?window.onYouTubeIframeAPIReady=()=>{r.log(u.Debug,"YouTube iframe API ready"),t()}:t()}),[r]);return s.createElement(T,{...a,loadScript:e,playerApiFactory:v},t=>s.createElement("div",{style:{width:"100%",height:"100%"}},s.createElement("div",{ref:t})))}),Z={Audio:R,Niconico:F,SoundCloud:j,Vimeo:$,YouTube:B},L=s.memo(({type:a,videoId:r,options:e})=>{const{logger:t,playerApiRef:i}=W();t.log(u.Debug,"NostalgicDiva");const c=Z[a];return s.createElement(c,{logger:t,type:a,playerApiRef:i,videoId:r,options:e})});exports.AudioPlayer=R;exports.AudioPlayerApi=M;exports.NiconicoPlayer=F;exports.NiconicoPlayerApi=E;exports.NostalgicDiva=L;exports.NostalgicDivaProvider=Q;exports.PlayerApi=w;exports.SoundCloudPlayer=j;exports.SoundCloudPlayerApi=b;exports.VimeoPlayer=$;exports.VimeoPlayerApi=G;exports.YouTubePlayer=B;exports.YouTubePlayerApi=v;exports.useNostalgicDiva=W;
|
|
2
2
|
//# sourceMappingURL=index.cjs.js.map
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":["../src/players/PlayerApiImpl.ts","../src/players/AudioPlayerApi.ts","../src/players/PlayerConsole.ts","../src/players/PlayerApi.ts","../src/components/useFirstMountState.ts","../src/components/usePreviousDistinct.ts","../src/components/PlayerContainer.tsx","../src/components/AudioPlayer.tsx","../src/players/NiconicoPlayerApi.ts","../src/components/NiconicoPlayer.tsx","../src/components/NostalgicDivaProvider.tsx","../src/players/SoundCloudPlayerApi.ts","../src/players/getScript.ts","../src/players/ensureScriptLoaded.ts","../src/components/SoundCloudPlayer.tsx","../src/players/VimeoPlayerApi.ts","../src/components/VimeoPlayer.tsx","../src/players/YouTubePlayerApi.ts","../src/components/YouTubePlayer.tsx","../src/components/NostalgicDiva.tsx"],"sourcesContent":["import React from 'react';\n\nimport { IPlayerApi, Logger, PlayerOptions } from './PlayerApi';\n\nexport abstract class PlayerApiImpl<TElement extends HTMLElement>\n\timplements IPlayerApi\n{\n\tprotected constructor(\n\t\tprotected readonly logger: Logger,\n\t\tprotected readonly playerElementRef: React.MutableRefObject<TElement>,\n\t\tprotected readonly options: PlayerOptions | undefined,\n\t) {\n\t\tthis.logger.debug('ctor');\n\t}\n\n\tabstract attach(id: string): Promise<void>;\n\tabstract detach(): Promise<void>;\n\tabstract loadVideo(id: string): Promise<void>;\n\tabstract play(): Promise<void>;\n\tabstract pause(): Promise<void>;\n\tabstract setCurrentTime(seconds: number): Promise<void>;\n\tabstract setVolume(volume: number): Promise<void>;\n\tabstract setMuted(muted: boolean): Promise<void>;\n\tabstract getDuration(): Promise<number | undefined>;\n\tabstract getCurrentTime(): Promise<number | undefined>;\n}\n","import React from 'react';\n\nimport { Logger, PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\n// https://github.com/VocaDB/vocadb/blob/61b8c54f3eca906a477101dab4fdd9b154be310e/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerFile.ts.\nexport class AudioPlayerApi extends PlayerApiImpl<HTMLAudioElement> {\n\tprivate readonly player: HTMLAudioElement;\n\n\tconstructor(\n\t\tlogger: Logger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLAudioElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = playerElementRef.current;\n\t}\n\n\tasync attach(): Promise<void> {\n\t\tthis.player.onerror = (event): void => this.options?.onError?.(event);\n\t\tthis.player.onloadeddata = (): void =>\n\t\t\tthis.options?.onLoaded?.({ id: this.player.src });\n\t\tthis.player.onplay = (): void => this.options?.onPlay?.();\n\t\tthis.player.onpause = (): void => this.options?.onPause?.();\n\t\tthis.player.onended = (): void => this.options?.onEnded?.();\n\t\tthis.player.ontimeupdate = (): void => {\n\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\tduration: this.player.duration,\n\t\t\t\tpercent: this.player.currentTime / this.player.duration,\n\t\t\t\tseconds: this.player.currentTime,\n\t\t\t});\n\t\t};\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.player.onerror = null;\n\t\tthis.player.onloadeddata = null;\n\t\tthis.player.onplay = null;\n\t\tthis.player.onpause = null;\n\t\tthis.player.onended = null;\n\t\tthis.player.ontimeupdate = null;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.player.src = id;\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.player.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.player.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.player.currentTime = seconds;\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.player.volume = volume;\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.player.muted = muted;\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn this.player.duration;\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn this.player.currentTime;\n\t}\n}\n","export class PlayerConsole {\n\tprivate static title = 'nostalgic-diva';\n\n\tprivate static createMessage(message: any): string {\n\t\treturn `[${PlayerConsole.title}] ${message}`;\n\t}\n\n\tpublic static assert(\n\t\tcondition?: boolean | undefined,\n\t\tmessage?: any,\n\t\t...optionalParams: any\n\t): void {\n\t\tconsole.assert(\n\t\t\tcondition,\n\t\t\tPlayerConsole.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tpublic static debug(message?: any, ...optionalParams: any): void {\n\t\tconsole.debug(PlayerConsole.createMessage(message), ...optionalParams);\n\t}\n\n\tpublic static error(message?: any, ...optionalParams: any): void {\n\t\tconsole.error(PlayerConsole.createMessage(message), ...optionalParams);\n\t}\n\n\tpublic static warn(message?: any, ...optionalParams: any): void {\n\t\tconsole.warn(PlayerConsole.createMessage(message), ...optionalParams);\n\t}\n}\n","import React from 'react';\n\nimport { PlayerApiImpl } from './PlayerApiImpl';\nimport { PlayerConsole } from './PlayerConsole';\n\nexport type PlayerType =\n\t| 'Audio'\n\t| 'Niconico'\n\t| 'SoundCloud'\n\t| 'Vimeo'\n\t| 'YouTube';\n\nexport interface LoadedEvent {\n\tid: string;\n}\n\nexport interface TimeEvent {\n\tduration: number | undefined;\n\tpercent: number | undefined;\n\tseconds: number | undefined;\n}\n\nexport interface PlayerOptions {\n\tonError?(event: any): void;\n\tonLoaded?(event: LoadedEvent): void;\n\tonPlay?(): void;\n\tonPause?(): void;\n\tonEnded?(): void;\n\tonTimeUpdate?(event: TimeEvent): void;\n}\n\nexport interface IPlayerApi {\n\tloadVideo(id: string): Promise<void>;\n\tplay(): Promise<void>;\n\tpause(): Promise<void>;\n\tsetCurrentTime(seconds: number): Promise<void>;\n\tsetVolume(volume: number): Promise<void>;\n\tsetMuted(muted: boolean): Promise<void>;\n\tgetDuration(): Promise<number | undefined>;\n\tgetCurrentTime(): Promise<number | undefined>;\n}\n\nexport interface Logger {\n\tdebug(message?: any, ...optionalParams: any): void;\n\terror(message?: any, ...optionalParams: any): void;\n}\n\nexport class PlayerApi<\n\tTElement extends HTMLElement,\n\tTPlayer extends PlayerApiImpl<TElement>,\n> implements IPlayerApi, Logger\n{\n\tprivate static nextId = 1;\n\n\tprivate readonly id: number;\n\tprivate impl?: TPlayer;\n\n\tconstructor(\n\t\tprivate readonly type: PlayerType,\n\t\tprivate readonly playerElementRef: React.MutableRefObject<TElement>,\n\t\tprivate readonly options: PlayerOptions | undefined,\n\t\tprivate readonly loadScript: (() => Promise<void>) | undefined,\n\t\tprivate readonly playerApiFactory: new (\n\t\t\tlogger: Logger,\n\t\t\tplayerElementRef: React.MutableRefObject<TElement>,\n\t\t\toptions: PlayerOptions | undefined,\n\t\t) => TPlayer,\n\t) {\n\t\tthis.id = PlayerApi.nextId++;\n\t}\n\n\tprivate createMessage(message: any): string {\n\t\treturn `${this.type}#${this.id} ${message}`;\n\t}\n\n\tpublic debug(message?: any, ...optionalParams: any): void {\n\t\tPlayerConsole.debug(this.createMessage(message), ...optionalParams);\n\t}\n\n\tpublic error(message?: any, ...optionalParams: any): void {\n\t\tPlayerConsole.error(this.createMessage(message), ...optionalParams);\n\t}\n\n\tasync attach(id: string): Promise<void> {\n\t\tthis.debug('attach', id);\n\n\t\tif (this.impl) {\n\t\t\tthis.debug('player is already attached');\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.loadScript?.();\n\n\t\tthis.debug('Attaching player...');\n\n\t\tthis.impl = new this.playerApiFactory(\n\t\t\tthis,\n\t\t\tthis.playerElementRef,\n\t\t\tthis.options,\n\t\t);\n\n\t\tawait this.impl.attach(id);\n\n\t\tthis.debug('player attached');\n\t}\n\n\tprivate assertPlayerAttached(): void {\n\t\tPlayerConsole.assert(!!this.impl, 'player is not attached');\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.debug('detach');\n\t\tthis.assertPlayerAttached();\n\n\t\tawait this.impl?.detach();\n\n\t\tthis.impl = undefined;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.debug('loadVideo', id);\n\t\tthis.assertPlayerAttached();\n\n\t\tthis.debug('Loading video...');\n\n\t\tawait this.impl?.loadVideo(id);\n\n\t\tthis.debug('video loaded', id);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.debug('play');\n\t\tthis.assertPlayerAttached();\n\n\t\tawait this.impl?.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.debug('pause');\n\t\tthis.assertPlayerAttached();\n\n\t\tawait this.impl?.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.debug('setCurrentTime', seconds);\n\t\tthis.assertPlayerAttached();\n\n\t\tawait this.impl?.setCurrentTime(seconds);\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.debug('setVolume', volume);\n\t\tthis.assertPlayerAttached();\n\n\t\tawait this.impl?.setVolume(volume);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.debug('setMuted', muted);\n\t\tthis.assertPlayerAttached();\n\n\t\tawait this.impl?.setMuted(muted);\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\tthis.debug('getDuration');\n\t\tthis.assertPlayerAttached();\n\n\t\treturn await this.impl?.getDuration();\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\tthis.debug('getCurrentTime');\n\t\tthis.assertPlayerAttached();\n\n\t\treturn await this.impl?.getCurrentTime();\n\t}\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/useFirstMountState.ts\nimport { useRef } from 'react';\n\nexport function useFirstMountState(): boolean {\n\tconst isFirst = useRef(true);\n\n\tif (isFirst.current) {\n\t\tisFirst.current = false;\n\n\t\treturn true;\n\t}\n\n\treturn isFirst.current;\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/usePreviousDistinct.ts.\nimport { useRef } from 'react';\n\nimport { useFirstMountState } from './useFirstMountState';\n\nexport type Predicate<T> = (prev: T | undefined, next: T) => boolean;\n\nconst strictEquals = <T>(prev: T | undefined, next: T): boolean =>\n\tprev === next;\n\nexport default function usePreviousDistinct<T>(\n\tvalue: T,\n\tcompare: Predicate<T> = strictEquals,\n): T | undefined {\n\tconst prevRef = useRef<T>();\n\tconst curRef = useRef<T>(value);\n\tconst isFirstMount = useFirstMountState();\n\n\tif (!isFirstMount && !compare(curRef.current, value)) {\n\t\tprevRef.current = curRef.current;\n\t\tcurRef.current = value;\n\t}\n\n\treturn prevRef.current;\n}\n","import React from 'react';\n\nimport {\n\tIPlayerApi,\n\tLogger,\n\tPlayerApi,\n\tPlayerOptions,\n\tPlayerType,\n} from '../players/PlayerApi';\nimport { PlayerApiImpl } from '../players/PlayerApiImpl';\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport usePreviousDistinct from './usePreviousDistinct';\n\nexport interface PlayerProps {\n\ttype: PlayerType;\n\tplayerApiRef: React.MutableRefObject<IPlayerApi | undefined> | undefined;\n\tvideoId: string;\n\toptions: PlayerOptions | undefined;\n}\n\ninterface PlayerContainerProps<\n\tTElement extends HTMLElement,\n\tTPlayer extends PlayerApiImpl<TElement>,\n> extends PlayerProps {\n\tloadScript: (() => Promise<void>) | undefined;\n\tplayerApiFactory: new (\n\t\tlogger: Logger,\n\t\tplayerElementRef: React.MutableRefObject<TElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) => TPlayer;\n\tchildren: (\n\t\tplayerElementRef: React.MutableRefObject<TElement>,\n\t\tvideoId: string,\n\t) => React.ReactNode;\n}\n\nexport const PlayerContainer = <\n\tTElement extends HTMLElement,\n\tTPlayer extends PlayerApiImpl<TElement>,\n>({\n\ttype,\n\tplayerApiRef,\n\tvideoId,\n\toptions,\n\tloadScript,\n\tplayerApiFactory,\n\tchildren,\n}: PlayerContainerProps<TElement, TPlayer>): React.ReactElement<\n\tPlayerContainerProps<TElement, TPlayer>\n> => {\n\tPlayerConsole.debug('PlayerContainer');\n\n\tconst videoIdRef = React.useRef(videoId);\n\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\tconst playerElementRef = React.useRef<TElement>(undefined!);\n\n\tconst [playerApi, setPlayerApi] = React.useState<IPlayerApi>();\n\n\t// Make sure that `options` do not change between re-rendering.\n\tReact.useEffect(() => {\n\t\tconst playerApi = new PlayerApi(\n\t\t\ttype,\n\t\t\tplayerElementRef,\n\t\t\toptions,\n\t\t\tloadScript,\n\t\t\tplayerApiFactory,\n\t\t);\n\n\t\tif (playerApiRef) playerApiRef.current = playerApi;\n\n\t\tplayerApi\n\t\t\t.attach(videoIdRef.current)\n\t\t\t.then(() => setPlayerApi(playerApi));\n\n\t\treturn (): void => {\n\t\t\tif (playerApiRef) {\n\t\t\t\tPlayerConsole.assert(\n\t\t\t\t\tplayerApi === playerApiRef.current,\n\t\t\t\t\t'playerApi differs',\n\t\t\t\t\tplayerApi,\n\t\t\t\t\tplayerApiRef.current,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tplayerApi.detach().then(() => setPlayerApi(undefined));\n\t\t};\n\t}, [type, options, loadScript, playerApiFactory, playerApiRef]);\n\n\tconst previousVideoId = usePreviousDistinct(videoId);\n\tReact.useEffect(() => {\n\t\t// If `previousVideoId` is undefined, then it means that the video has already been loaded by either\n\t\t// 1. `<audio>`s `src` attribute (e.g. `AudioPlayer`),\n\t\t// 2. `<iframe>`'s `src` attribute (e.g. `NiconicoPlayer`, `SoundCloudPlayer` and `VimeoPlayer`), or\n\t\t// 3. the `attach` method of the player API (e.g. `YouTubePlayer`).\n\t\tif (previousVideoId === undefined) return;\n\n\t\tplayerApi?.loadVideo(videoId);\n\t}, [previousVideoId, videoId, playerApi]);\n\n\t// Make sure that `videoId` does not change between re-rendering.\n\treturn <>{children(playerElementRef, videoIdRef.current)}</>;\n};\n","import React from 'react';\n\nimport { AudioPlayerApi } from '../players/AudioPlayerApi';\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const AudioPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tPlayerConsole.debug('AudioPlayer');\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={undefined}\n\t\t\t\tplayerApiFactory={AudioPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t<audio\n\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\tsrc={videoId}\n\t\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t\t\tpreload=\"auto\"\n\t\t\t\t\t\tautoPlay\n\t\t\t\t\t\tcontrols\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { Logger, PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\ndeclare global {\n\tinterface Window {\n\t\tonNicoPlayerFactoryReady: (callback: nico.NicoPlayerFactory) => void;\n\t}\n}\n\nenum PlayerStatus {\n\tPlay = 2,\n\tPause = 3,\n\tEnd = 4,\n}\n\n// https://github.com/VocaDB/vocadb/blob/a4b5f9d8186772d7e6f58f997bbcbb51509d2539/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerNico.ts.\nexport class NiconicoPlayerApi extends PlayerApiImpl<HTMLIFrameElement> {\n\tprivate static readonly origin = 'https://embed.nicovideo.jp';\n\n\tprivate readonly player: HTMLIFrameElement;\n\n\tprivate duration?: number;\n\tprivate currentTime?: number;\n\n\tconstructor(\n\t\tlogger: Logger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLIFrameElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = playerElementRef.current;\n\t}\n\n\tprivate handleMessage(e: nico.PlayerEvent): void {\n\t\tif (e.origin !== NiconicoPlayerApi.origin) return;\n\n\t\tconst data = e.data;\n\n\t\tswitch (data.eventName) {\n\t\t\tcase 'playerStatusChange':\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t`player status changed: ${\n\t\t\t\t\t\tPlayerStatus[data.data.playerStatus] ??\n\t\t\t\t\t\tdata.data.playerStatus\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'statusChange':\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t`status changed: ${\n\t\t\t\t\t\tPlayerStatus[data.data.playerStatus] ??\n\t\t\t\t\t\tdata.data.playerStatus\n\t\t\t\t\t}`,\n\t\t\t\t);\n\n\t\t\t\tswitch (data.data.playerStatus) {\n\t\t\t\t\tcase PlayerStatus.Play:\n\t\t\t\t\t\tthis.options?.onPlay?.();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PlayerStatus.Pause:\n\t\t\t\t\t\tthis.options?.onPause?.();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PlayerStatus.End:\n\t\t\t\t\t\tthis.options?.onEnded?.();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'playerMetadataChange':\n\t\t\t\tif (data.data.duration !== undefined)\n\t\t\t\t\tthis.duration = data.data.duration / 1000;\n\n\t\t\t\tthis.currentTime =\n\t\t\t\t\tdata.data.currentTime === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: data.data.currentTime / 1000;\n\n\t\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\t\tduration: this.duration,\n\t\t\t\t\tpercent:\n\t\t\t\t\t\tthis.currentTime !== undefined &&\n\t\t\t\t\t\tthis.duration !== undefined\n\t\t\t\t\t\t\t? this.currentTime / this.duration\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\tseconds: this.currentTime,\n\t\t\t\t});\n\t\t\t\tbreak;\n\n\t\t\tcase 'loadComplete':\n\t\t\t\tthis.logger.debug('load completed');\n\n\t\t\t\tthis.duration = data.data.videoInfo.lengthInSeconds;\n\n\t\t\t\tthis.options?.onLoaded?.({ id: data.data.videoInfo.watchId });\n\t\t\t\tbreak;\n\n\t\t\tcase 'error':\n\t\t\t\t// TODO: Implement.\n\n\t\t\t\tthis.options?.onError?.(data);\n\t\t\t\tbreak;\n\n\t\t\tcase 'player-error:video:play':\n\t\t\tcase 'player-error:video:seek':\n\t\t\t\tthis.options?.onError?.(data);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthis.logger.debug(\n\t\t\t\t\t'message',\n\t\t\t\t\t(data as any).eventName,\n\t\t\t\t\t(data as any).data,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tasync attach(): Promise<void> {\n\t\twindow.addEventListener('message', this.handleMessage);\n\t}\n\n\tasync detach(): Promise<void> {\n\t\twindow.removeEventListener('message', this.handleMessage);\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tthis.duration = undefined;\n\t\t\tthis.currentTime = undefined;\n\n\t\t\t// Wait for iframe to load.\n\t\t\tthis.player.onload = (): void => {\n\t\t\t\tthis.player.onload = null;\n\t\t\t\tresolve();\n\t\t\t};\n\n\t\t\tthis.player.src = `https://embed.nicovideo.jp/watch/${id}?jsapi=1&playerId=1`;\n\t\t});\n\t}\n\n\t// https://blog.hayu.io/web/create/nicovideo-embed-player-api/.\n\tprivate postMessage(message: any): void {\n\t\tthis.player.contentWindow?.postMessage(\n\t\t\t{\n\t\t\t\t...message,\n\t\t\t\tplayerId: '1' /* Needs to be a string, not a number. */,\n\t\t\t\tsourceConnectorType: 1,\n\t\t\t},\n\t\t\tNiconicoPlayerApi.origin,\n\t\t);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.postMessage({ eventName: 'play' });\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.postMessage({ eventName: 'pause' });\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.postMessage({ eventName: 'seek', data: { time: seconds * 1000 } });\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.postMessage({\n\t\t\teventName: 'volumeChange',\n\t\t\tdata: { volume: volume },\n\t\t});\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.postMessage({\n\t\t\teventName: 'mute',\n\t\t\tdata: { mute: muted },\n\t\t});\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn this.duration;\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn this.currentTime;\n\t}\n}\n","import React from 'react';\n\nimport { NiconicoPlayerApi } from '../players/NiconicoPlayerApi';\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const NiconicoPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tPlayerConsole.debug('NiconicoPlayer');\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={undefined}\n\t\t\t\tplayerApiFactory={NiconicoPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t\t{/* eslint-disable-next-line jsx-a11y/iframe-has-title */}\n\t\t\t\t\t\t<iframe\n\t\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\t\tsrc={`https://embed.nicovideo.jp/watch/${videoId}?jsapi=1&playerId=1`}\n\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\theight=\"100%\"\n\t\t\t\t\t\t\tallowFullScreen\n\t\t\t\t\t\t\tstyle={{ border: 'none' }}\n\t\t\t\t\t\t\t// The player has to have the allow=\"autoplay\" attribute.\n\t\t\t\t\t\t\t// Otherwise it throws a NotAllowedError: \"play() failed because the user didn't interact with the document first\".\n\t\t\t\t\t\t\t// See also: https://github.com/vimeo/player.js/issues/389.\n\t\t\t\t\t\t\t// NOTE: An iframe element created by `PVPlayerNiconico.playerFactory.create` doesn't have the allow=\"autoplay\" attribute,\n\t\t\t\t\t\t\t// which causes the above issue when trying to autoplay a video.\n\t\t\t\t\t\t\tallow=\"autoplay; fullscreen\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { IPlayerApi } from '../players';\n\ninterface NostalgicDivaContextProps extends IPlayerApi {\n\tplayerApiRef: React.MutableRefObject<IPlayerApi | undefined>;\n}\n\nconst NostalgicDivaContext = React.createContext<NostalgicDivaContextProps>(\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\tundefined!,\n);\n\ninterface NostalgicDivaProviderProps {\n\tchildren?: React.ReactNode;\n}\n\nexport const NostalgicDivaProvider = ({\n\tchildren,\n}: NostalgicDivaProviderProps): React.ReactElement => {\n\tconst playerApiRef = React.useRef<IPlayerApi>();\n\n\tconst loadVideo = React.useCallback(async (id: string) => {\n\t\tawait playerApiRef.current?.loadVideo(id);\n\t}, []);\n\n\tconst play = React.useCallback(async () => {\n\t\tawait playerApiRef.current?.play();\n\t}, []);\n\n\tconst pause = React.useCallback(async () => {\n\t\tawait playerApiRef.current?.pause();\n\t}, []);\n\n\tconst setCurrentTime = React.useCallback(async (seconds: number) => {\n\t\tconst playerApi = playerApiRef.current;\n\t\tif (!playerApi) return;\n\n\t\tawait playerApi.setCurrentTime(seconds);\n\t\tawait playerApi.play();\n\t}, []);\n\n\tconst setVolume = React.useCallback(async (volume: number) => {\n\t\tawait playerApiRef.current?.setVolume(volume);\n\t}, []);\n\n\tconst setMuted = React.useCallback(async (muted: boolean) => {\n\t\tawait playerApiRef.current?.setMuted(muted);\n\t}, []);\n\n\tconst getDuration = React.useCallback(async () => {\n\t\treturn await playerApiRef.current?.getDuration();\n\t}, []);\n\n\tconst getCurrentTime = React.useCallback(async () => {\n\t\treturn await playerApiRef.current?.getCurrentTime();\n\t}, []);\n\n\tconst value = React.useMemo(\n\t\t(): NostalgicDivaContextProps => ({\n\t\t\tplayerApiRef,\n\t\t\tloadVideo,\n\t\t\tplay,\n\t\t\tpause,\n\t\t\tsetCurrentTime,\n\t\t\tsetVolume,\n\t\t\tsetMuted,\n\t\t\tgetDuration,\n\t\t\tgetCurrentTime,\n\t\t}),\n\t\t[\n\t\t\tloadVideo,\n\t\t\tplay,\n\t\t\tpause,\n\t\t\tsetCurrentTime,\n\t\t\tsetVolume,\n\t\t\tsetMuted,\n\t\t\tgetDuration,\n\t\t\tgetCurrentTime,\n\t\t],\n\t);\n\n\treturn (\n\t\t<NostalgicDivaContext.Provider value={value}>\n\t\t\t{children}\n\t\t</NostalgicDivaContext.Provider>\n\t);\n};\n\nexport const useNostalgicDiva = (): NostalgicDivaContextProps => {\n\treturn React.useContext(NostalgicDivaContext);\n};\n","import React from 'react';\n\nimport { Logger, PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\n// https://github.com/VocaDB/vocadb/blob/e147650a8f1f85c8fa865d0ab562126c278527ec/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerSoundCloud.ts.\nexport class SoundCloudPlayerApi extends PlayerApiImpl<HTMLIFrameElement> {\n\tprivate readonly player: SC.SoundCloudWidget;\n\n\tconstructor(\n\t\tlogger: Logger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLIFrameElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = SC.Widget(this.playerElementRef.current);\n\t}\n\n\tprivate static playerGetDurationAsync(\n\t\tplayer: SC.SoundCloudWidget,\n\t): Promise<number> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tplayer.getDuration(resolve);\n\t\t});\n\t}\n\n\tattach(id: string): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: reject */) => {\n\t\t\tthis.player.bind(SC.Widget.Events.READY, () => {\n\t\t\t\tthis.player.bind(\n\t\t\t\t\tSC.Widget.Events.PLAY_PROGRESS,\n\t\t\t\t\tasync (event) => {\n\t\t\t\t\t\tconst duration =\n\t\t\t\t\t\t\tawait SoundCloudPlayerApi.playerGetDurationAsync(\n\t\t\t\t\t\t\t\tthis.player,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\t\t\t\tduration: duration / 1000,\n\t\t\t\t\t\t\tpercent: event.currentPosition / duration,\n\t\t\t\t\t\t\tseconds: event.currentPosition / 1000,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.ERROR, (event) =>\n\t\t\t\t\tthis.options?.onError?.(event),\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.PLAY, () =>\n\t\t\t\t\tthis.options?.onPlay?.(),\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.PAUSE, () =>\n\t\t\t\t\tthis.options?.onPause?.(),\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.FINISH, () =>\n\t\t\t\t\tthis.options?.onEnded?.(),\n\t\t\t\t);\n\n\t\t\t\tthis.options?.onLoaded?.({ id: id });\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.player.unbind(SC.Widget.Events.READY);\n\t\tthis.player.unbind(SC.Widget.Events.PLAY_PROGRESS);\n\t\tthis.player.unbind(SC.Widget.Events.ERROR);\n\t\tthis.player.unbind(SC.Widget.Events.PLAY);\n\t\tthis.player.unbind(SC.Widget.Events.PAUSE);\n\t\tthis.player.unbind(SC.Widget.Events.FINISH);\n\t}\n\n\tprivate static playerLoadAsync(\n\t\tplayer: SC.SoundCloudWidget,\n\t\turl: string,\n\t\toptions: Omit<SC.SoundCloudLoadOptions, 'callback'>,\n\t): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tplayer.load(url, { ...options, callback: resolve });\n\t\t});\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tawait SoundCloudPlayerApi.playerLoadAsync(this.player, id, {\n\t\t\tauto_play: true,\n\t\t});\n\n\t\tthis.options?.onLoaded?.({ id: id });\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.player.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.player.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.player.seekTo(seconds * 1000);\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.player.setVolume(volume * 100);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.setVolume(muted ? 0 : 1 /* TODO */);\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\tconst duration = await SoundCloudPlayerApi.playerGetDurationAsync(\n\t\t\tthis.player,\n\t\t);\n\n\t\treturn duration / 1000;\n\t}\n\n\tprivate static playerGetPositionAsync(\n\t\tplayer: SC.SoundCloudWidget,\n\t): Promise<number> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tplayer.getPosition(resolve);\n\t\t});\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\tconst position = await SoundCloudPlayerApi.playerGetPositionAsync(\n\t\t\tthis.player,\n\t\t);\n\n\t\treturn position / 1000;\n\t}\n}\n","// https://stackoverflow.com/a/61903296.\nexport function getScript(url: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst script = document.createElement('script') as any; /* TODO */\n\t\tscript.src = url;\n\t\tscript.async = true;\n\n\t\tscript.onerror = reject;\n\n\t\tscript.onload = script.onreadystatechange = function (): void {\n\t\t\tconst loadState = this.readyState;\n\n\t\t\tif (loadState && loadState !== 'loaded' && loadState !== 'complete')\n\t\t\t\treturn;\n\n\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\tresolve();\n\t\t};\n\n\t\tdocument.head.appendChild(script);\n\t});\n}\n","import { PlayerConsole } from './PlayerConsole';\nimport { getScript } from './getScript';\n\nconst urls: string[] = [];\n\nexport async function ensureScriptLoaded(url: string): Promise<boolean> {\n\tif (urls.includes(url)) {\n\t\tPlayerConsole.debug(url, 'script is already loaded');\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tPlayerConsole.debug(url, 'Loading script...');\n\n\t\tawait getScript(url);\n\n\t\tif (urls.includes(url)) {\n\t\t\tPlayerConsole.debug(url, 'script is already loaded');\n\t\t\treturn false;\n\t\t} else {\n\t\t\turls.push(url);\n\t\t\tPlayerConsole.debug(url, 'script loaded');\n\t\t\treturn true;\n\t\t}\n\t} catch (error) {\n\t\tPlayerConsole.error(url, 'Failed to load script');\n\t\tthrow error;\n\t}\n}\n","import React from 'react';\n\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport { SoundCloudPlayerApi } from '../players/SoundCloudPlayerApi';\nimport { ensureScriptLoaded } from '../players/ensureScriptLoaded';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const SoundCloudPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tPlayerConsole.debug('SoundCloudPlayer');\n\n\t\tconst loadScript = React.useCallback(async () => {\n\t\t\tawait ensureScriptLoaded('https://w.soundcloud.com/player/api.js');\n\t\t}, []);\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={loadScript}\n\t\t\t\tplayerApiFactory={SoundCloudPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t// eslint-disable-next-line jsx-a11y/iframe-has-title\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\tsrc={`https://w.soundcloud.com/player/?url=${videoId}`}\n\t\t\t\t\t\tframeBorder={0}\n\t\t\t\t\t\tallow=\"autoplay\"\n\t\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { Logger, PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\n// https://github.com/cookpete/react-player/blob/e3c324bc6845698179d065fa408db515c2296b4b/src/players/Vimeo.js\nexport class VimeoPlayerApi extends PlayerApiImpl<HTMLIFrameElement> {\n\tprivate readonly player: Vimeo.Player;\n\n\tconstructor(\n\t\tlogger: Logger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLIFrameElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = new Vimeo.Player(this.playerElementRef.current);\n\t}\n\n\tasync attach(): Promise<void> {\n\t\tawait this.player.ready();\n\n\t\tthis.player.on('error', (data) => this.options?.onError?.(data));\n\t\tthis.player.on('loaded', (event) =>\n\t\t\tthis.options?.onLoaded?.({ id: event.id.toString() }),\n\t\t);\n\t\tthis.player.on('play', () => this.options?.onPlay?.());\n\t\tthis.player.on('pause', () => this.options?.onPause?.());\n\t\tthis.player.on('ended', () => this.options?.onEnded?.());\n\t\tthis.player.on('timeupdate', (data) => {\n\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\tduration: data.duration,\n\t\t\t\tpercent: data.percent,\n\t\t\t\tseconds: data.seconds,\n\t\t\t});\n\t\t});\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.player.off('error');\n\t\tthis.player.off('loaded');\n\t\tthis.player.off('play');\n\t\tthis.player.off('pause');\n\t\tthis.player.off('ended');\n\t\tthis.player.off('timeupdate');\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tawait this.player.loadVideo(id);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tawait this.player.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tawait this.player.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tawait this.player.setCurrentTime(seconds);\n\t}\n\n\tasync setVolume(fraction: number): Promise<void> {\n\t\tawait this.player.setVolume(fraction);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tawait this.player.setMuted(muted);\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn await this.player.getDuration();\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn await this.player.getCurrentTime();\n\t}\n}\n","import React from 'react';\n\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport { VimeoPlayerApi } from '../players/VimeoPlayerApi';\nimport { ensureScriptLoaded } from '../players/ensureScriptLoaded';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const VimeoPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tPlayerConsole.debug('VimeoPlayer');\n\n\t\tconst loadScript = React.useCallback(async () => {\n\t\t\tawait ensureScriptLoaded('https://player.vimeo.com/api/player.js');\n\t\t}, []);\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={loadScript}\n\t\t\t\tplayerApiFactory={VimeoPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t// eslint-disable-next-line jsx-a11y/iframe-has-title\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\tsrc={`https://player.vimeo.com/video/${videoId}`}\n\t\t\t\t\t\tframeBorder={0}\n\t\t\t\t\t\tallow=\"autoplay\"\n\t\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { Logger, PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\ndeclare global {\n\tinterface Window {\n\t\tonYouTubeIframeAPIReady(): void;\n\t}\n}\n\nenum PlayerState {\n\tUNSTARTED = -1,\n\tENDED = 0,\n\tPLAYING = 1,\n\tPAUSED = 2,\n\tBUFFERING = 3,\n\tCUED = 5,\n}\n\n// https://github.com/VocaDB/vocadb/blob/076dac9f0808aba5da7332209fdfd2ff4e12c235/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerYoutube.ts.\nexport class YouTubePlayerApi extends PlayerApiImpl<HTMLDivElement> {\n\tprivate static readonly origin = 'https://www.youtube-nocookie.com';\n\n\tprivate readonly player: YT.Player;\n\n\tconstructor(\n\t\tlogger: Logger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLDivElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = new YT.Player(this.playerElementRef.current, {\n\t\t\thost: YouTubePlayerApi.origin,\n\t\t\twidth: '100%',\n\t\t\theight: '100%',\n\t\t});\n\t}\n\n\tprivate previousTime?: number;\n\n\tprivate timeUpdateIntervalId?: number;\n\n\tprivate clearTimeUpdateInterval(): void {\n\t\tthis.logger.debug('clearTimeUpdateInterval', this.timeUpdateIntervalId);\n\n\t\twindow.clearInterval(this.timeUpdateIntervalId);\n\n\t\tthis.timeUpdateIntervalId = undefined;\n\t}\n\n\tprivate invokeTimeUpdate(player: YT.Player): void {\n\t\tconst currentTime = player.getCurrentTime();\n\t\tif (currentTime === this.previousTime) return;\n\n\t\tconst duration = player.getDuration();\n\t\tthis.options?.onTimeUpdate?.({\n\t\t\tduration: duration,\n\t\t\tpercent: currentTime / duration,\n\t\t\tseconds: currentTime,\n\t\t});\n\n\t\tthis.previousTime = currentTime;\n\t}\n\n\tprivate setTimeUpdateInterval(): void {\n\t\tthis.logger.debug('setTimeUpdateInterval');\n\n\t\tthis.clearTimeUpdateInterval();\n\n\t\tthis.timeUpdateIntervalId = window.setInterval(\n\t\t\t() => this.invokeTimeUpdate(this.player),\n\t\t\t250,\n\t\t);\n\n\t\tthis.logger.debug('timeUpdateIntervalId', this.timeUpdateIntervalId);\n\n\t\tthis.invokeTimeUpdate(this.player);\n\t}\n\n\tattach(id: string): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: reject */) => {\n\t\t\tthis.player.addEventListener('onReady', async () => {\n\t\t\t\tthis.player.addEventListener('onError', (event) =>\n\t\t\t\t\tthis.options?.onError?.(event.data),\n\t\t\t\t);\n\t\t\t\tthis.player.addEventListener(\n\t\t\t\t\t'onStateChange',\n\t\t\t\t\t(event: YT.EventArgs): void => {\n\t\t\t\t\t\tthis.logger.debug(\n\t\t\t\t\t\t\t`state changed: ${PlayerState[event.data]}`,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tswitch (event.data) {\n\t\t\t\t\t\t\tcase YT.PlayerState.CUED:\n\t\t\t\t\t\t\t\tthis.options?.onLoaded?.({ id: id });\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase YT.PlayerState.PLAYING:\n\t\t\t\t\t\t\t\tthis.options?.onPlay?.();\n\t\t\t\t\t\t\t\tthis.setTimeUpdateInterval();\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase YT.PlayerState.PAUSED:\n\t\t\t\t\t\t\t\tthis.options?.onPause?.();\n\t\t\t\t\t\t\t\tthis.clearTimeUpdateInterval();\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase YT.PlayerState.ENDED:\n\t\t\t\t\t\t\t\tthis.options?.onEnded?.();\n\t\t\t\t\t\t\t\tthis.clearTimeUpdateInterval();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tawait this.loadVideo(id);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.clearTimeUpdateInterval();\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.previousTime = undefined;\n\t\tthis.player.cueVideoById(id);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.player.playVideo();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.player.pauseVideo();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.player.seekTo(seconds);\n\n\t\tthis.invokeTimeUpdate(this.player);\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.player.setVolume(volume * 100);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tif (muted) {\n\t\t\tthis.player.mute();\n\t\t} else {\n\t\t\tthis.player.unMute();\n\t\t}\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn this.player.getDuration();\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn this.player.getCurrentTime();\n\t}\n}\n","import React from 'react';\n\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport { YouTubePlayerApi } from '../players/YouTubePlayerApi';\nimport { ensureScriptLoaded } from '../players/ensureScriptLoaded';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const YouTubePlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tPlayerConsole.debug('YouTubePlayer');\n\n\t\tconst loadScript = React.useCallback((): Promise<void> => {\n\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\tconst first = await ensureScriptLoaded(\n\t\t\t\t\t'https://www.youtube.com/iframe_api',\n\t\t\t\t);\n\n\t\t\t\tif (first) {\n\t\t\t\t\t// https://stackoverflow.com/a/18154942.\n\t\t\t\t\twindow.onYouTubeIframeAPIReady = (): void => {\n\t\t\t\t\t\tPlayerConsole.debug('YouTube iframe API ready');\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t}, []);\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={loadScript}\n\t\t\t\tplayerApiFactory={YouTubePlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef): React.ReactElement => (\n\t\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t\t<div ref={playerElementRef} />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { PlayerOptions, PlayerType } from '../players/PlayerApi';\nimport { PlayerConsole } from '../players/PlayerConsole';\nimport { AudioPlayer } from './AudioPlayer';\nimport { NiconicoPlayer } from './NiconicoPlayer';\nimport { useNostalgicDiva } from './NostalgicDivaProvider';\nimport { PlayerProps } from './PlayerContainer';\nimport { SoundCloudPlayer } from './SoundCloudPlayer';\nimport { VimeoPlayer } from './VimeoPlayer';\nimport { YouTubePlayer } from './YouTubePlayer';\n\nconst players: Record<PlayerType, React.ElementType<PlayerProps>> = {\n\tAudio: AudioPlayer,\n\tNiconico: NiconicoPlayer,\n\tSoundCloud: SoundCloudPlayer,\n\tVimeo: VimeoPlayer,\n\tYouTube: YouTubePlayer,\n};\n\ninterface NostalgicDivaProps {\n\ttype: PlayerType;\n\tvideoId: string;\n\toptions?: PlayerOptions;\n}\n\nexport const NostalgicDiva = React.memo(\n\t({ type, videoId, options }: NostalgicDivaProps): React.ReactElement => {\n\t\tPlayerConsole.debug('NostalgicDiva');\n\n\t\tconst diva = useNostalgicDiva();\n\n\t\tconst Player = players[type];\n\t\treturn (\n\t\t\t<Player\n\t\t\t\ttype={type}\n\t\t\t\tplayerApiRef={diva.playerApiRef}\n\t\t\t\tvideoId={videoId}\n\t\t\t\toptions={options}\n\t\t\t/>\n\t\t);\n\t},\n);\n"],"names":["PlayerApiImpl","logger","playerElementRef","options","AudioPlayerApi","__publicField","event","_b","_a","id","seconds","volume","muted","_PlayerConsole","message","condition","optionalParams","PlayerConsole","_PlayerApi","type","loadScript","playerApiFactory","PlayerApi","useFirstMountState","isFirst","useRef","strictEquals","prev","next","usePreviousDistinct","value","compare","prevRef","curRef","PlayerContainer","playerApiRef","videoId","children","videoIdRef","React","playerApi","setPlayerApi","previousVideoId","AudioPlayer","props","PlayerStatus","_NiconicoPlayerApi","data","_d","_c","_f","_e","_h","_g","_j","_i","_l","_k","_n","_m","_p","_o","resolve","reject","NiconicoPlayerApi","NiconicoPlayer","NostalgicDivaContext","NostalgicDivaProvider","loadVideo","play","pause","setCurrentTime","setVolume","setMuted","getDuration","getCurrentTime","useNostalgicDiva","SoundCloudPlayerApi","player","duration","url","getScript","script","loadState","urls","ensureScriptLoaded","error","SoundCloudPlayer","VimeoPlayerApi","fraction","VimeoPlayer","PlayerState","_YouTubePlayerApi","currentTime","YouTubePlayerApi","YouTubePlayer","players","NostalgicDiva","diva","Player"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/players/ILogger.ts","../src/players/PlayerApiImpl.ts","../src/players/AudioPlayerApi.ts","../src/players/PlayerApi.ts","../src/components/useFirstMountState.ts","../src/components/usePreviousDistinct.ts","../src/components/PlayerContainer.tsx","../src/components/AudioPlayer.tsx","../src/players/NiconicoPlayerApi.ts","../src/components/NiconicoPlayer.tsx","../src/components/NostalgicDivaProvider.tsx","../src/players/SoundCloudPlayerApi.ts","../src/players/getScript.ts","../src/players/ensureScriptLoaded.ts","../src/components/SoundCloudPlayer.tsx","../src/players/VimeoPlayerApi.ts","../src/components/VimeoPlayer.tsx","../src/players/YouTubePlayerApi.ts","../src/components/YouTubePlayer.tsx","../src/components/NostalgicDiva.tsx"],"sourcesContent":["// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/LogLevel.cs,d07793e8b722b77e,references\nexport enum LogLevel {\n\t/**\n\t * Logs that contain the most detailed messages. These messages may contain sensitive application data.\n\t * These messages are disabled by default and should never be enabled in a production environment.\n\t */\n\tTrace = 0,\n\t/**\n\t * Logs that are used for interactive investigation during development. These logs should primarily contain\n\t * information useful for debugging and have no long-term value.\n\t */\n\tDebug = 1,\n\t/**\n\t * Logs that track the general flow of the application. These logs should have long-term value.\n\t */\n\tInformation = 2,\n\t/**\n\t * Logs that highlight an abnormal or unexpected event in the application flow, but do not otherwise cause the\n\t * application execution to stop.\n\t */\n\tWarning = 3,\n\t/**\n\t * Logs that highlight when the current flow of execution is stopped due to a failure. These should indicate a\n\t * failure in the current activity, not an application-wide failure.\n\t */\n\tError = 4,\n\t/**\n\t * Logs that describe an unrecoverable application or system crash, or a catastrophic failure that requires\n\t * immediate attention.\n\t */\n\tCritical = 5,\n\t/**\n\t * Not used for writing log messages. Specifies that a logging category should not write any messages.\n\t */\n\tNone = 6,\n}\n\n// https://source.dot.net/#Microsoft.Extensions.Logging.Abstractions/ILogger.cs,0976525f5d1b9e54,references\nexport interface ILogger {\n\tisEnabled(logLevel: LogLevel): boolean;\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void;\n}\n","import React from 'react';\n\nimport { ILogger, LogLevel } from './ILogger';\nimport { IPlayerApi, PlayerOptions } from './PlayerApi';\n\nexport abstract class PlayerApiImpl<TElement extends HTMLElement>\n\timplements IPlayerApi\n{\n\tprotected constructor(\n\t\tprotected readonly logger: ILogger,\n\t\tprotected readonly playerElementRef: React.MutableRefObject<TElement>,\n\t\tprotected readonly options: PlayerOptions | undefined,\n\t) {\n\t\tthis.logger.log(LogLevel.Debug, 'ctor');\n\t}\n\n\tabstract attach(id: string): Promise<void>;\n\tabstract detach(): Promise<void>;\n\tabstract loadVideo(id: string): Promise<void>;\n\tabstract play(): Promise<void>;\n\tabstract pause(): Promise<void>;\n\tabstract setCurrentTime(seconds: number): Promise<void>;\n\tabstract setVolume(volume: number): Promise<void>;\n\tabstract setMuted(muted: boolean): Promise<void>;\n\tabstract getDuration(): Promise<number | undefined>;\n\tabstract getCurrentTime(): Promise<number | undefined>;\n}\n","import React from 'react';\n\nimport { ILogger } from './ILogger';\nimport { PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\n// https://github.com/VocaDB/vocadb/blob/61b8c54f3eca906a477101dab4fdd9b154be310e/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerFile.ts.\nexport class AudioPlayerApi extends PlayerApiImpl<HTMLAudioElement> {\n\tprivate readonly player: HTMLAudioElement;\n\n\tconstructor(\n\t\tlogger: ILogger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLAudioElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = playerElementRef.current;\n\t}\n\n\tasync attach(): Promise<void> {\n\t\tthis.player.onerror = (event): void => this.options?.onError?.(event);\n\t\tthis.player.onloadeddata = (): void =>\n\t\t\tthis.options?.onLoaded?.({ id: this.player.src });\n\t\tthis.player.onplay = (): void => this.options?.onPlay?.();\n\t\tthis.player.onpause = (): void => this.options?.onPause?.();\n\t\tthis.player.onended = (): void => this.options?.onEnded?.();\n\t\tthis.player.ontimeupdate = (): void => {\n\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\tduration: this.player.duration,\n\t\t\t\tpercent: this.player.currentTime / this.player.duration,\n\t\t\t\tseconds: this.player.currentTime,\n\t\t\t});\n\t\t};\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.player.onerror = null;\n\t\tthis.player.onloadeddata = null;\n\t\tthis.player.onplay = null;\n\t\tthis.player.onpause = null;\n\t\tthis.player.onended = null;\n\t\tthis.player.ontimeupdate = null;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.player.src = id;\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.player.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.player.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.player.currentTime = seconds;\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.player.volume = volume;\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.player.muted = muted;\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn this.player.duration;\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn this.player.currentTime;\n\t}\n}\n","import React from 'react';\n\nimport { ILogger, LogLevel } from './ILogger';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\nexport type PlayerType =\n\t| 'Audio'\n\t| 'Niconico'\n\t| 'SoundCloud'\n\t| 'Vimeo'\n\t| 'YouTube';\n\nexport interface LoadedEvent {\n\tid: string;\n}\n\nexport interface TimeEvent {\n\tduration: number | undefined;\n\tpercent: number | undefined;\n\tseconds: number | undefined;\n}\n\nexport interface PlayerOptions {\n\tonError?(event: any): void;\n\tonLoaded?(event: LoadedEvent): void;\n\tonPlay?(): void;\n\tonPause?(): void;\n\tonEnded?(): void;\n\tonTimeUpdate?(event: TimeEvent): void;\n}\n\nexport interface IPlayerApi {\n\tloadVideo(id: string): Promise<void>;\n\tplay(): Promise<void>;\n\tpause(): Promise<void>;\n\tsetCurrentTime(seconds: number): Promise<void>;\n\tsetVolume(volume: number): Promise<void>;\n\tsetMuted(muted: boolean): Promise<void>;\n\tgetDuration(): Promise<number | undefined>;\n\tgetCurrentTime(): Promise<number | undefined>;\n}\n\nexport class PlayerApi<\n\tTElement extends HTMLElement,\n\tTPlayer extends PlayerApiImpl<TElement>,\n> implements IPlayerApi\n{\n\tprivate static nextId = 1;\n\n\tprivate readonly id: number;\n\tprivate impl?: TPlayer;\n\n\tconstructor(\n\t\tprivate readonly logger: ILogger,\n\t\tprivate readonly type: PlayerType,\n\t\tprivate readonly playerElementRef: React.MutableRefObject<TElement>,\n\t\tprivate readonly options: PlayerOptions | undefined,\n\t\tprivate readonly loadScript: (() => Promise<void>) | undefined,\n\t\tprivate readonly playerApiFactory: new (\n\t\t\tlogger: ILogger,\n\t\t\tplayerElementRef: React.MutableRefObject<TElement>,\n\t\t\toptions: PlayerOptions | undefined,\n\t\t) => TPlayer,\n\t) {\n\t\tthis.id = PlayerApi.nextId++;\n\t}\n\n\tprivate createMessage(message: any): string {\n\t\treturn `${this.type}#${this.id} ${message}`;\n\t}\n\n\tpublic debug(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tpublic error(message?: any, ...optionalParams: any): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Error,\n\t\t\tthis.createMessage(message),\n\t\t\t...optionalParams,\n\t\t);\n\t}\n\n\tasync attach(id: string): Promise<void> {\n\t\tthis.debug('attach', id);\n\n\t\tif (this.impl) {\n\t\t\tthis.debug('player is already attached');\n\t\t\treturn;\n\t\t}\n\n\t\tawait this.loadScript?.();\n\n\t\tthis.debug('Attaching player...');\n\n\t\tthis.impl = new this.playerApiFactory(\n\t\t\tthis.logger,\n\t\t\tthis.playerElementRef,\n\t\t\tthis.options,\n\t\t);\n\n\t\tawait this.impl.attach(id);\n\n\t\tthis.debug('player attached');\n\t}\n\n\tprivate createPlayerNotAttachedError(): Error {\n\t\treturn new Error('player is not attached');\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.debug('detach');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tawait this.impl.detach();\n\n\t\tthis.impl = undefined;\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.debug('loadVideo', id);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\tthis.debug('Loading video...');\n\n\t\tawait this.impl.loadVideo(id);\n\n\t\tthis.debug('video loaded', id);\n\t}\n\n\tplay(): Promise<void> {\n\t\tthis.debug('play');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.play();\n\t}\n\n\tpause(): Promise<void> {\n\t\tthis.debug('pause');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.pause();\n\t}\n\n\tsetCurrentTime(seconds: number): Promise<void> {\n\t\tthis.debug('setCurrentTime', seconds);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.setCurrentTime(seconds);\n\t}\n\n\tsetVolume(volume: number): Promise<void> {\n\t\tthis.debug('setVolume', volume);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.setVolume(volume);\n\t}\n\n\tsetMuted(muted: boolean): Promise<void> {\n\t\tthis.debug('setMuted', muted);\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.setMuted(muted);\n\t}\n\n\tgetDuration(): Promise<number | undefined> {\n\t\tthis.debug('getDuration');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.getDuration();\n\t}\n\n\tgetCurrentTime(): Promise<number | undefined> {\n\t\tthis.debug('getCurrentTime');\n\n\t\tif (this.impl === undefined) {\n\t\t\tthrow this.createPlayerNotAttachedError();\n\t\t}\n\n\t\treturn this.impl.getCurrentTime();\n\t}\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/useFirstMountState.ts\nimport { useRef } from 'react';\n\nexport function useFirstMountState(): boolean {\n\tconst isFirst = useRef(true);\n\n\tif (isFirst.current) {\n\t\tisFirst.current = false;\n\n\t\treturn true;\n\t}\n\n\treturn isFirst.current;\n}\n","// https://github.com/streamich/react-use/blob/8ceb4c0f0c5625124f487b435a2fd0d3b3bc2a4f/src/usePreviousDistinct.ts.\nimport { useRef } from 'react';\n\nimport { useFirstMountState } from './useFirstMountState';\n\nexport type Predicate<T> = (prev: T | undefined, next: T) => boolean;\n\nconst strictEquals = <T>(prev: T | undefined, next: T): boolean =>\n\tprev === next;\n\nexport default function usePreviousDistinct<T>(\n\tvalue: T,\n\tcompare: Predicate<T> = strictEquals,\n): T | undefined {\n\tconst prevRef = useRef<T>();\n\tconst curRef = useRef<T>(value);\n\tconst isFirstMount = useFirstMountState();\n\n\tif (!isFirstMount && !compare(curRef.current, value)) {\n\t\tprevRef.current = curRef.current;\n\t\tcurRef.current = value;\n\t}\n\n\treturn prevRef.current;\n}\n","import React from 'react';\n\nimport { ILogger, LogLevel } from '../players/ILogger';\nimport {\n\tIPlayerApi,\n\tPlayerApi,\n\tPlayerOptions,\n\tPlayerType,\n} from '../players/PlayerApi';\nimport { PlayerApiImpl } from '../players/PlayerApiImpl';\nimport usePreviousDistinct from './usePreviousDistinct';\n\nexport interface PlayerProps {\n\tlogger: ILogger;\n\ttype: PlayerType;\n\tplayerApiRef: React.MutableRefObject<IPlayerApi | undefined> | undefined;\n\tvideoId: string;\n\toptions: PlayerOptions | undefined;\n}\n\ninterface PlayerContainerProps<\n\tTElement extends HTMLElement,\n\tTPlayer extends PlayerApiImpl<TElement>,\n> extends PlayerProps {\n\tloadScript: (() => Promise<void>) | undefined;\n\tplayerApiFactory: new (\n\t\tlogger: ILogger,\n\t\tplayerElementRef: React.MutableRefObject<TElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) => TPlayer;\n\tchildren: (\n\t\tplayerElementRef: React.MutableRefObject<TElement>,\n\t\tvideoId: string,\n\t) => React.ReactNode;\n}\n\nexport const PlayerContainer = <\n\tTElement extends HTMLElement,\n\tTPlayer extends PlayerApiImpl<TElement>,\n>({\n\tlogger,\n\ttype,\n\tplayerApiRef,\n\tvideoId,\n\toptions,\n\tloadScript,\n\tplayerApiFactory,\n\tchildren,\n}: PlayerContainerProps<TElement, TPlayer>): React.ReactElement<\n\tPlayerContainerProps<TElement, TPlayer>\n> => {\n\tlogger.log(LogLevel.Debug, 'PlayerContainer');\n\n\tconst videoIdRef = React.useRef(videoId);\n\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\tconst playerElementRef = React.useRef<TElement>(undefined!);\n\n\tconst [playerApi, setPlayerApi] = React.useState<IPlayerApi>();\n\n\t// Make sure that `options` do not change between re-rendering.\n\tReact.useEffect(() => {\n\t\tconst playerApi = new PlayerApi(\n\t\t\tlogger,\n\t\t\ttype,\n\t\t\tplayerElementRef,\n\t\t\toptions,\n\t\t\tloadScript,\n\t\t\tplayerApiFactory,\n\t\t);\n\n\t\tif (playerApiRef) playerApiRef.current = playerApi;\n\n\t\tplayerApi\n\t\t\t.attach(videoIdRef.current)\n\t\t\t.then(() => setPlayerApi(playerApi));\n\n\t\treturn (): void => {\n\t\t\tif (playerApiRef) {\n\t\t\t\tif (playerApi !== playerApiRef.current) {\n\t\t\t\t\tthrow new Error('playerApi differs');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tplayerApi.detach().then(() => setPlayerApi(undefined));\n\t\t};\n\t}, [logger, type, options, loadScript, playerApiFactory, playerApiRef]);\n\n\tconst previousVideoId = usePreviousDistinct(videoId);\n\tReact.useEffect(() => {\n\t\t// If `previousVideoId` is undefined, then it means that the video has already been loaded by either\n\t\t// 1. `<audio>`s `src` attribute (e.g. `AudioPlayer`),\n\t\t// 2. `<iframe>`'s `src` attribute (e.g. `NiconicoPlayer`, `SoundCloudPlayer` and `VimeoPlayer`), or\n\t\t// 3. the `attach` method of the player API (e.g. `YouTubePlayer`).\n\t\tif (previousVideoId === undefined) return;\n\n\t\tplayerApi?.loadVideo(videoId);\n\t}, [previousVideoId, videoId, playerApi]);\n\n\t// Make sure that `videoId` does not change between re-rendering.\n\treturn <>{children(playerElementRef, videoIdRef.current)}</>;\n};\n","import React from 'react';\n\nimport { AudioPlayerApi } from '../players/AudioPlayerApi';\nimport { LogLevel } from '../players/ILogger';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const AudioPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tconst { logger } = props;\n\n\t\tlogger.log(LogLevel.Debug, 'AudioPlayer');\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={undefined}\n\t\t\t\tplayerApiFactory={AudioPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t<audio\n\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\tsrc={videoId}\n\t\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t\t\tpreload=\"auto\"\n\t\t\t\t\t\tautoPlay\n\t\t\t\t\t\tcontrols\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { ILogger, LogLevel } from './ILogger';\nimport { PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\ndeclare global {\n\tinterface Window {\n\t\tonNicoPlayerFactoryReady: (callback: nico.NicoPlayerFactory) => void;\n\t}\n}\n\nenum PlayerStatus {\n\tPlay = 2,\n\tPause = 3,\n\tEnd = 4,\n}\n\n// https://github.com/VocaDB/vocadb/blob/a4b5f9d8186772d7e6f58f997bbcbb51509d2539/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerNico.ts.\nexport class NiconicoPlayerApi extends PlayerApiImpl<HTMLIFrameElement> {\n\tprivate static readonly origin = 'https://embed.nicovideo.jp';\n\n\tprivate readonly player: HTMLIFrameElement;\n\n\tprivate duration?: number;\n\tprivate currentTime?: number;\n\n\tconstructor(\n\t\tlogger: ILogger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLIFrameElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = playerElementRef.current;\n\t}\n\n\tprivate handleMessage(e: nico.PlayerEvent): void {\n\t\tif (e.origin !== NiconicoPlayerApi.origin) return;\n\n\t\tconst data = e.data;\n\n\t\tswitch (data.eventName) {\n\t\t\tcase 'playerStatusChange':\n\t\t\t\tthis.logger.log(\n\t\t\t\t\tLogLevel.Debug,\n\t\t\t\t\t`player status changed: ${\n\t\t\t\t\t\tPlayerStatus[data.data.playerStatus] ??\n\t\t\t\t\t\tdata.data.playerStatus\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'statusChange':\n\t\t\t\tthis.logger.log(\n\t\t\t\t\tLogLevel.Debug,\n\t\t\t\t\t`status changed: ${\n\t\t\t\t\t\tPlayerStatus[data.data.playerStatus] ??\n\t\t\t\t\t\tdata.data.playerStatus\n\t\t\t\t\t}`,\n\t\t\t\t);\n\n\t\t\t\tswitch (data.data.playerStatus) {\n\t\t\t\t\tcase PlayerStatus.Play:\n\t\t\t\t\t\tthis.options?.onPlay?.();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PlayerStatus.Pause:\n\t\t\t\t\t\tthis.options?.onPause?.();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PlayerStatus.End:\n\t\t\t\t\t\tthis.options?.onEnded?.();\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'playerMetadataChange':\n\t\t\t\tif (data.data.duration !== undefined)\n\t\t\t\t\tthis.duration = data.data.duration / 1000;\n\n\t\t\t\tthis.currentTime =\n\t\t\t\t\tdata.data.currentTime === undefined\n\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t: data.data.currentTime / 1000;\n\n\t\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\t\tduration: this.duration,\n\t\t\t\t\tpercent:\n\t\t\t\t\t\tthis.currentTime !== undefined &&\n\t\t\t\t\t\tthis.duration !== undefined\n\t\t\t\t\t\t\t? this.currentTime / this.duration\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t\tseconds: this.currentTime,\n\t\t\t\t});\n\t\t\t\tbreak;\n\n\t\t\tcase 'loadComplete':\n\t\t\t\tthis.logger.log(LogLevel.Debug, 'load completed');\n\n\t\t\t\tthis.duration = data.data.videoInfo.lengthInSeconds;\n\n\t\t\t\tthis.options?.onLoaded?.({ id: data.data.videoInfo.watchId });\n\t\t\t\tbreak;\n\n\t\t\tcase 'error':\n\t\t\t\t// TODO: Implement.\n\n\t\t\t\tthis.options?.onError?.(data);\n\t\t\t\tbreak;\n\n\t\t\tcase 'player-error:video:play':\n\t\t\tcase 'player-error:video:seek':\n\t\t\t\tthis.options?.onError?.(data);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthis.logger.log(\n\t\t\t\t\tLogLevel.Debug,\n\t\t\t\t\t'message',\n\t\t\t\t\t(data as any).eventName,\n\t\t\t\t\t(data as any).data,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tasync attach(): Promise<void> {\n\t\twindow.addEventListener('message', this.handleMessage);\n\t}\n\n\tasync detach(): Promise<void> {\n\t\twindow.removeEventListener('message', this.handleMessage);\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tthis.duration = undefined;\n\t\t\tthis.currentTime = undefined;\n\n\t\t\t// Wait for iframe to load.\n\t\t\tthis.player.onload = (): void => {\n\t\t\t\tthis.player.onload = null;\n\t\t\t\tresolve();\n\t\t\t};\n\n\t\t\tthis.player.src = `https://embed.nicovideo.jp/watch/${id}?jsapi=1&playerId=1`;\n\t\t});\n\t}\n\n\t// https://blog.hayu.io/web/create/nicovideo-embed-player-api/.\n\tprivate postMessage(message: any): void {\n\t\tthis.player.contentWindow?.postMessage(\n\t\t\t{\n\t\t\t\t...message,\n\t\t\t\tplayerId: '1' /* Needs to be a string, not a number. */,\n\t\t\t\tsourceConnectorType: 1,\n\t\t\t},\n\t\t\tNiconicoPlayerApi.origin,\n\t\t);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.postMessage({ eventName: 'play' });\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.postMessage({ eventName: 'pause' });\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.postMessage({ eventName: 'seek', data: { time: seconds * 1000 } });\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.postMessage({\n\t\t\teventName: 'volumeChange',\n\t\t\tdata: { volume: volume },\n\t\t});\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.postMessage({\n\t\t\teventName: 'mute',\n\t\t\tdata: { mute: muted },\n\t\t});\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn this.duration;\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn this.currentTime;\n\t}\n}\n","import React from 'react';\n\nimport { LogLevel } from '../players/ILogger';\nimport { NiconicoPlayerApi } from '../players/NiconicoPlayerApi';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const NiconicoPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tconst { logger } = props;\n\n\t\tlogger.log(LogLevel.Debug, 'NiconicoPlayer');\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={undefined}\n\t\t\t\tplayerApiFactory={NiconicoPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t\t{/* eslint-disable-next-line jsx-a11y/iframe-has-title */}\n\t\t\t\t\t\t<iframe\n\t\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\t\tsrc={`https://embed.nicovideo.jp/watch/${videoId}?jsapi=1&playerId=1`}\n\t\t\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\t\t\theight=\"100%\"\n\t\t\t\t\t\t\tallowFullScreen\n\t\t\t\t\t\t\tstyle={{ border: 'none' }}\n\t\t\t\t\t\t\t// The player has to have the allow=\"autoplay\" attribute.\n\t\t\t\t\t\t\t// Otherwise it throws a NotAllowedError: \"play() failed because the user didn't interact with the document first\".\n\t\t\t\t\t\t\t// See also: https://github.com/vimeo/player.js/issues/389.\n\t\t\t\t\t\t\t// NOTE: An iframe element created by `PVPlayerNiconico.playerFactory.create` doesn't have the allow=\"autoplay\" attribute,\n\t\t\t\t\t\t\t// which causes the above issue when trying to autoplay a video.\n\t\t\t\t\t\t\tallow=\"autoplay; fullscreen\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { IPlayerApi } from '../players';\nimport { ILogger, LogLevel } from '../players/ILogger';\n\ninterface NostalgicDivaContextProps extends IPlayerApi {\n\tlogger: ILogger;\n\tplayerApiRef: React.MutableRefObject<IPlayerApi | undefined>;\n}\n\nconst NostalgicDivaContext = React.createContext<NostalgicDivaContextProps>(\n\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\tundefined!,\n);\n\ninterface NostalgicDivaProviderProps {\n\tlogger?: ILogger;\n\tchildren?: React.ReactNode;\n}\n\nconst defaultLogger = new (class implements ILogger {\n\tprivate readonly title = 'nostalgic-diva';\n\n\tprivate createMessage(message: any): string {\n\t\treturn `[${this.title}] ${message}`;\n\t}\n\n\tprivate debug(message?: any, ...optionalParams: any): void {\n\t\tconsole.debug(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate error(message?: any, ...optionalParams: any): void {\n\t\tconsole.error(this.createMessage(message), ...optionalParams);\n\t}\n\n\tprivate warn(message?: any, ...optionalParams: any): void {\n\t\tconsole.warn(this.createMessage(message), ...optionalParams);\n\t}\n\n\tisEnabled(): boolean {\n\t\treturn true;\n\t}\n\n\tlog(logLevel: LogLevel, message?: any, ...optionalParams: any[]): void {\n\t\tswitch (logLevel) {\n\t\t\tcase LogLevel.Debug:\n\t\t\t\tthis.debug(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Warning:\n\t\t\t\tthis.warn(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t\tcase LogLevel.Error:\n\t\t\t\tthis.error(message, ...optionalParams);\n\t\t\t\tbreak;\n\t\t}\n\t}\n})();\n\nexport const NostalgicDivaProvider = ({\n\tlogger = defaultLogger,\n\tchildren,\n}: NostalgicDivaProviderProps): React.ReactElement => {\n\tconst playerApiRef = React.useRef<IPlayerApi>();\n\n\tconst loadVideo = React.useCallback(async (id: string) => {\n\t\tawait playerApiRef.current?.loadVideo(id);\n\t}, []);\n\n\tconst play = React.useCallback(async () => {\n\t\tawait playerApiRef.current?.play();\n\t}, []);\n\n\tconst pause = React.useCallback(async () => {\n\t\tawait playerApiRef.current?.pause();\n\t}, []);\n\n\tconst setCurrentTime = React.useCallback(async (seconds: number) => {\n\t\tconst playerApi = playerApiRef.current;\n\t\tif (!playerApi) return;\n\n\t\tawait playerApi.setCurrentTime(seconds);\n\t\tawait playerApi.play();\n\t}, []);\n\n\tconst setVolume = React.useCallback(async (volume: number) => {\n\t\tawait playerApiRef.current?.setVolume(volume);\n\t}, []);\n\n\tconst setMuted = React.useCallback(async (muted: boolean) => {\n\t\tawait playerApiRef.current?.setMuted(muted);\n\t}, []);\n\n\tconst getDuration = React.useCallback(async () => {\n\t\treturn await playerApiRef.current?.getDuration();\n\t}, []);\n\n\tconst getCurrentTime = React.useCallback(async () => {\n\t\treturn await playerApiRef.current?.getCurrentTime();\n\t}, []);\n\n\tconst value = React.useMemo(\n\t\t(): NostalgicDivaContextProps => ({\n\t\t\tlogger,\n\t\t\tplayerApiRef,\n\t\t\tloadVideo,\n\t\t\tplay,\n\t\t\tpause,\n\t\t\tsetCurrentTime,\n\t\t\tsetVolume,\n\t\t\tsetMuted,\n\t\t\tgetDuration,\n\t\t\tgetCurrentTime,\n\t\t}),\n\t\t[\n\t\t\tlogger,\n\t\t\tloadVideo,\n\t\t\tplay,\n\t\t\tpause,\n\t\t\tsetCurrentTime,\n\t\t\tsetVolume,\n\t\t\tsetMuted,\n\t\t\tgetDuration,\n\t\t\tgetCurrentTime,\n\t\t],\n\t);\n\n\treturn (\n\t\t<NostalgicDivaContext.Provider value={value}>\n\t\t\t{children}\n\t\t</NostalgicDivaContext.Provider>\n\t);\n};\n\nexport const useNostalgicDiva = (): NostalgicDivaContextProps => {\n\treturn React.useContext(NostalgicDivaContext);\n};\n","import React from 'react';\n\nimport { ILogger } from './ILogger';\nimport { PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\n// https://github.com/VocaDB/vocadb/blob/e147650a8f1f85c8fa865d0ab562126c278527ec/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerSoundCloud.ts.\nexport class SoundCloudPlayerApi extends PlayerApiImpl<HTMLIFrameElement> {\n\tprivate readonly player: SC.SoundCloudWidget;\n\n\tconstructor(\n\t\tlogger: ILogger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLIFrameElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = SC.Widget(this.playerElementRef.current);\n\t}\n\n\tprivate static playerGetDurationAsync(\n\t\tplayer: SC.SoundCloudWidget,\n\t): Promise<number> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tplayer.getDuration(resolve);\n\t\t});\n\t}\n\n\tattach(id: string): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: reject */) => {\n\t\t\tthis.player.bind(SC.Widget.Events.READY, () => {\n\t\t\t\tthis.player.bind(\n\t\t\t\t\tSC.Widget.Events.PLAY_PROGRESS,\n\t\t\t\t\tasync (event) => {\n\t\t\t\t\t\tconst duration =\n\t\t\t\t\t\t\tawait SoundCloudPlayerApi.playerGetDurationAsync(\n\t\t\t\t\t\t\t\tthis.player,\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\t\t\t\tduration: duration / 1000,\n\t\t\t\t\t\t\tpercent: event.currentPosition / duration,\n\t\t\t\t\t\t\tseconds: event.currentPosition / 1000,\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.ERROR, (event) =>\n\t\t\t\t\tthis.options?.onError?.(event),\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.PLAY, () =>\n\t\t\t\t\tthis.options?.onPlay?.(),\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.PAUSE, () =>\n\t\t\t\t\tthis.options?.onPause?.(),\n\t\t\t\t);\n\t\t\t\tthis.player.bind(SC.Widget.Events.FINISH, () =>\n\t\t\t\t\tthis.options?.onEnded?.(),\n\t\t\t\t);\n\n\t\t\t\tthis.options?.onLoaded?.({ id: id });\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.player.unbind(SC.Widget.Events.READY);\n\t\tthis.player.unbind(SC.Widget.Events.PLAY_PROGRESS);\n\t\tthis.player.unbind(SC.Widget.Events.ERROR);\n\t\tthis.player.unbind(SC.Widget.Events.PLAY);\n\t\tthis.player.unbind(SC.Widget.Events.PAUSE);\n\t\tthis.player.unbind(SC.Widget.Events.FINISH);\n\t}\n\n\tprivate static playerLoadAsync(\n\t\tplayer: SC.SoundCloudWidget,\n\t\turl: string,\n\t\toptions: Omit<SC.SoundCloudLoadOptions, 'callback'>,\n\t): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tplayer.load(url, { ...options, callback: resolve });\n\t\t});\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tawait SoundCloudPlayerApi.playerLoadAsync(this.player, id, {\n\t\t\tauto_play: true,\n\t\t});\n\n\t\tthis.options?.onLoaded?.({ id: id });\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.player.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.player.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.player.seekTo(seconds * 1000);\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.player.setVolume(volume * 100);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tthis.setVolume(muted ? 0 : 1 /* TODO */);\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\tconst duration = await SoundCloudPlayerApi.playerGetDurationAsync(\n\t\t\tthis.player,\n\t\t);\n\n\t\treturn duration / 1000;\n\t}\n\n\tprivate static playerGetPositionAsync(\n\t\tplayer: SC.SoundCloudWidget,\n\t): Promise<number> {\n\t\treturn new Promise((resolve, reject /* TODO: Reject. */) => {\n\t\t\tplayer.getPosition(resolve);\n\t\t});\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\tconst position = await SoundCloudPlayerApi.playerGetPositionAsync(\n\t\t\tthis.player,\n\t\t);\n\n\t\treturn position / 1000;\n\t}\n}\n","// https://stackoverflow.com/a/61903296.\nexport function getScript(url: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst script = document.createElement('script') as any; /* TODO */\n\t\tscript.src = url;\n\t\tscript.async = true;\n\n\t\tscript.onerror = reject;\n\n\t\tscript.onload = script.onreadystatechange = function (): void {\n\t\t\tconst loadState = this.readyState;\n\n\t\t\tif (loadState && loadState !== 'loaded' && loadState !== 'complete')\n\t\t\t\treturn;\n\n\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\tresolve();\n\t\t};\n\n\t\tdocument.head.appendChild(script);\n\t});\n}\n","import { ILogger, LogLevel } from './ILogger';\nimport { getScript } from './getScript';\n\nconst urls: string[] = [];\n\nexport async function ensureScriptLoaded(\n\turl: string,\n\tlogger: ILogger,\n): Promise<boolean> {\n\tif (urls.includes(url)) {\n\t\tlogger.log(LogLevel.Debug, url, 'script is already loaded');\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tlogger.log(LogLevel.Debug, url, 'Loading script...');\n\n\t\tawait getScript(url);\n\n\t\tif (urls.includes(url)) {\n\t\t\tlogger.log(LogLevel.Debug, url, 'script is already loaded');\n\t\t\treturn false;\n\t\t} else {\n\t\t\turls.push(url);\n\t\t\tlogger.log(LogLevel.Debug, url, 'script loaded');\n\t\t\treturn true;\n\t\t}\n\t} catch (error) {\n\t\tlogger.log(LogLevel.Error, url, 'Failed to load script');\n\t\tthrow error;\n\t}\n}\n","import React from 'react';\n\nimport { LogLevel } from '../players/ILogger';\nimport { SoundCloudPlayerApi } from '../players/SoundCloudPlayerApi';\nimport { ensureScriptLoaded } from '../players/ensureScriptLoaded';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const SoundCloudPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tconst { logger } = props;\n\n\t\tlogger.log(LogLevel.Debug, 'SoundCloudPlayer');\n\n\t\tconst loadScript = React.useCallback(async () => {\n\t\t\tawait ensureScriptLoaded(\n\t\t\t\t'https://w.soundcloud.com/player/api.js',\n\t\t\t\tlogger,\n\t\t\t);\n\t\t}, [logger]);\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={loadScript}\n\t\t\t\tplayerApiFactory={SoundCloudPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t// eslint-disable-next-line jsx-a11y/iframe-has-title\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\tsrc={`https://w.soundcloud.com/player/?url=${videoId}`}\n\t\t\t\t\t\tframeBorder={0}\n\t\t\t\t\t\tallow=\"autoplay\"\n\t\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { ILogger } from './ILogger';\nimport { PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\n// https://github.com/cookpete/react-player/blob/e3c324bc6845698179d065fa408db515c2296b4b/src/players/Vimeo.js\nexport class VimeoPlayerApi extends PlayerApiImpl<HTMLIFrameElement> {\n\tprivate readonly player: Vimeo.Player;\n\n\tconstructor(\n\t\tlogger: ILogger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLIFrameElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = new Vimeo.Player(this.playerElementRef.current);\n\t}\n\n\tasync attach(): Promise<void> {\n\t\tawait this.player.ready();\n\n\t\tthis.player.on('error', (data) => this.options?.onError?.(data));\n\t\tthis.player.on('loaded', (event) =>\n\t\t\tthis.options?.onLoaded?.({ id: event.id.toString() }),\n\t\t);\n\t\tthis.player.on('play', () => this.options?.onPlay?.());\n\t\tthis.player.on('pause', () => this.options?.onPause?.());\n\t\tthis.player.on('ended', () => this.options?.onEnded?.());\n\t\tthis.player.on('timeupdate', (data) => {\n\t\t\tthis.options?.onTimeUpdate?.({\n\t\t\t\tduration: data.duration,\n\t\t\t\tpercent: data.percent,\n\t\t\t\tseconds: data.seconds,\n\t\t\t});\n\t\t});\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.player.off('error');\n\t\tthis.player.off('loaded');\n\t\tthis.player.off('play');\n\t\tthis.player.off('pause');\n\t\tthis.player.off('ended');\n\t\tthis.player.off('timeupdate');\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tawait this.player.loadVideo(id);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tawait this.player.play();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tawait this.player.pause();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tawait this.player.setCurrentTime(seconds);\n\t}\n\n\tasync setVolume(fraction: number): Promise<void> {\n\t\tawait this.player.setVolume(fraction);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tawait this.player.setMuted(muted);\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn await this.player.getDuration();\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn await this.player.getCurrentTime();\n\t}\n}\n","import React from 'react';\n\nimport { LogLevel } from '../players/ILogger';\nimport { VimeoPlayerApi } from '../players/VimeoPlayerApi';\nimport { ensureScriptLoaded } from '../players/ensureScriptLoaded';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const VimeoPlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tconst { logger } = props;\n\n\t\tlogger.log(LogLevel.Debug, 'VimeoPlayer');\n\n\t\tconst loadScript = React.useCallback(async () => {\n\t\t\tawait ensureScriptLoaded(\n\t\t\t\t'https://player.vimeo.com/api/player.js',\n\t\t\t\tlogger,\n\t\t\t);\n\t\t}, [logger]);\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={loadScript}\n\t\t\t\tplayerApiFactory={VimeoPlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef, videoId): React.ReactElement => (\n\t\t\t\t\t// eslint-disable-next-line jsx-a11y/iframe-has-title\n\t\t\t\t\t<iframe\n\t\t\t\t\t\tref={playerElementRef}\n\t\t\t\t\t\tsrc={`https://player.vimeo.com/video/${videoId}`}\n\t\t\t\t\t\tframeBorder={0}\n\t\t\t\t\t\tallow=\"autoplay\"\n\t\t\t\t\t\tstyle={{ width: '100%', height: '100%' }}\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { ILogger, LogLevel } from './ILogger';\nimport { PlayerOptions } from './PlayerApi';\nimport { PlayerApiImpl } from './PlayerApiImpl';\n\ndeclare global {\n\tinterface Window {\n\t\tonYouTubeIframeAPIReady(): void;\n\t}\n}\n\nenum PlayerState {\n\tUNSTARTED = -1,\n\tENDED = 0,\n\tPLAYING = 1,\n\tPAUSED = 2,\n\tBUFFERING = 3,\n\tCUED = 5,\n}\n\n// https://github.com/VocaDB/vocadb/blob/076dac9f0808aba5da7332209fdfd2ff4e12c235/VocaDbWeb/Scripts/ViewModels/PVs/PVPlayerYoutube.ts.\nexport class YouTubePlayerApi extends PlayerApiImpl<HTMLDivElement> {\n\tprivate static readonly origin = 'https://www.youtube-nocookie.com';\n\n\tprivate readonly player: YT.Player;\n\n\tconstructor(\n\t\tlogger: ILogger,\n\t\tplayerElementRef: React.MutableRefObject<HTMLDivElement>,\n\t\toptions: PlayerOptions | undefined,\n\t) {\n\t\tsuper(logger, playerElementRef, options);\n\n\t\tthis.player = new YT.Player(this.playerElementRef.current, {\n\t\t\thost: YouTubePlayerApi.origin,\n\t\t\twidth: '100%',\n\t\t\theight: '100%',\n\t\t});\n\t}\n\n\tprivate previousTime?: number;\n\n\tprivate timeUpdateIntervalId?: number;\n\n\tprivate clearTimeUpdateInterval(): void {\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\t'clearTimeUpdateInterval',\n\t\t\tthis.timeUpdateIntervalId,\n\t\t);\n\n\t\twindow.clearInterval(this.timeUpdateIntervalId);\n\n\t\tthis.timeUpdateIntervalId = undefined;\n\t}\n\n\tprivate invokeTimeUpdate(player: YT.Player): void {\n\t\tconst currentTime = player.getCurrentTime();\n\t\tif (currentTime === this.previousTime) return;\n\n\t\tconst duration = player.getDuration();\n\t\tthis.options?.onTimeUpdate?.({\n\t\t\tduration: duration,\n\t\t\tpercent: currentTime / duration,\n\t\t\tseconds: currentTime,\n\t\t});\n\n\t\tthis.previousTime = currentTime;\n\t}\n\n\tprivate setTimeUpdateInterval(): void {\n\t\tthis.logger.log(LogLevel.Debug, 'setTimeUpdateInterval');\n\n\t\tthis.clearTimeUpdateInterval();\n\n\t\tthis.timeUpdateIntervalId = window.setInterval(\n\t\t\t() => this.invokeTimeUpdate(this.player),\n\t\t\t250,\n\t\t);\n\n\t\tthis.logger.log(\n\t\t\tLogLevel.Debug,\n\t\t\t'timeUpdateIntervalId',\n\t\t\tthis.timeUpdateIntervalId,\n\t\t);\n\n\t\tthis.invokeTimeUpdate(this.player);\n\t}\n\n\tattach(id: string): Promise<void> {\n\t\treturn new Promise((resolve, reject /* TODO: reject */) => {\n\t\t\tthis.player.addEventListener('onReady', async () => {\n\t\t\t\tthis.player.addEventListener('onError', (event) =>\n\t\t\t\t\tthis.options?.onError?.(event.data),\n\t\t\t\t);\n\t\t\t\tthis.player.addEventListener(\n\t\t\t\t\t'onStateChange',\n\t\t\t\t\t(event: YT.EventArgs): void => {\n\t\t\t\t\t\tthis.logger.log(\n\t\t\t\t\t\t\tLogLevel.Debug,\n\t\t\t\t\t\t\t`state changed: ${PlayerState[event.data]}`,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tswitch (event.data) {\n\t\t\t\t\t\t\tcase YT.PlayerState.CUED:\n\t\t\t\t\t\t\t\tthis.options?.onLoaded?.({ id: id });\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase YT.PlayerState.PLAYING:\n\t\t\t\t\t\t\t\tthis.options?.onPlay?.();\n\t\t\t\t\t\t\t\tthis.setTimeUpdateInterval();\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase YT.PlayerState.PAUSED:\n\t\t\t\t\t\t\t\tthis.options?.onPause?.();\n\t\t\t\t\t\t\t\tthis.clearTimeUpdateInterval();\n\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\tcase YT.PlayerState.ENDED:\n\t\t\t\t\t\t\t\tthis.options?.onEnded?.();\n\t\t\t\t\t\t\t\tthis.clearTimeUpdateInterval();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\tawait this.loadVideo(id);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tasync detach(): Promise<void> {\n\t\tthis.clearTimeUpdateInterval();\n\t}\n\n\tasync loadVideo(id: string): Promise<void> {\n\t\tthis.previousTime = undefined;\n\t\tthis.player.cueVideoById(id);\n\t}\n\n\tasync play(): Promise<void> {\n\t\tthis.player.playVideo();\n\t}\n\n\tasync pause(): Promise<void> {\n\t\tthis.player.pauseVideo();\n\t}\n\n\tasync setCurrentTime(seconds: number): Promise<void> {\n\t\tthis.player.seekTo(seconds);\n\n\t\tthis.invokeTimeUpdate(this.player);\n\t}\n\n\tasync setVolume(volume: number): Promise<void> {\n\t\tthis.player.setVolume(volume * 100);\n\t}\n\n\tasync setMuted(muted: boolean): Promise<void> {\n\t\tif (muted) {\n\t\t\tthis.player.mute();\n\t\t} else {\n\t\t\tthis.player.unMute();\n\t\t}\n\t}\n\n\tasync getDuration(): Promise<number | undefined> {\n\t\treturn this.player.getDuration();\n\t}\n\n\tasync getCurrentTime(): Promise<number | undefined> {\n\t\treturn this.player.getCurrentTime();\n\t}\n}\n","import React from 'react';\n\nimport { LogLevel } from '../players/ILogger';\nimport { YouTubePlayerApi } from '../players/YouTubePlayerApi';\nimport { ensureScriptLoaded } from '../players/ensureScriptLoaded';\nimport { PlayerContainer, PlayerProps } from './PlayerContainer';\n\nexport const YouTubePlayer = React.memo(\n\t({ ...props }: PlayerProps): React.ReactElement => {\n\t\tconst { logger } = props;\n\n\t\tlogger.log(LogLevel.Debug, 'YouTubePlayer');\n\n\t\tconst loadScript = React.useCallback((): Promise<void> => {\n\t\t\treturn new Promise(async (resolve, reject) => {\n\t\t\t\tconst first = await ensureScriptLoaded(\n\t\t\t\t\t'https://www.youtube.com/iframe_api',\n\t\t\t\t\tlogger,\n\t\t\t\t);\n\n\t\t\t\tif (first) {\n\t\t\t\t\t// https://stackoverflow.com/a/18154942.\n\t\t\t\t\twindow.onYouTubeIframeAPIReady = (): void => {\n\t\t\t\t\t\tlogger.log(LogLevel.Debug, 'YouTube iframe API ready');\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t});\n\t\t}, [logger]);\n\n\t\treturn (\n\t\t\t<PlayerContainer\n\t\t\t\t{...props}\n\t\t\t\tloadScript={loadScript}\n\t\t\t\tplayerApiFactory={YouTubePlayerApi}\n\t\t\t>\n\t\t\t\t{(playerElementRef): React.ReactElement => (\n\t\t\t\t\t<div style={{ width: '100%', height: '100%' }}>\n\t\t\t\t\t\t<div ref={playerElementRef} />\n\t\t\t\t\t</div>\n\t\t\t\t)}\n\t\t\t</PlayerContainer>\n\t\t);\n\t},\n);\n","import React from 'react';\n\nimport { LogLevel } from '../players/ILogger';\nimport { PlayerOptions, PlayerType } from '../players/PlayerApi';\nimport { AudioPlayer } from './AudioPlayer';\nimport { NiconicoPlayer } from './NiconicoPlayer';\nimport { useNostalgicDiva } from './NostalgicDivaProvider';\nimport { PlayerProps } from './PlayerContainer';\nimport { SoundCloudPlayer } from './SoundCloudPlayer';\nimport { VimeoPlayer } from './VimeoPlayer';\nimport { YouTubePlayer } from './YouTubePlayer';\n\nconst players: Record<PlayerType, React.ElementType<PlayerProps>> = {\n\tAudio: AudioPlayer,\n\tNiconico: NiconicoPlayer,\n\tSoundCloud: SoundCloudPlayer,\n\tVimeo: VimeoPlayer,\n\tYouTube: YouTubePlayer,\n};\n\ninterface NostalgicDivaProps {\n\ttype: PlayerType;\n\tvideoId: string;\n\toptions?: PlayerOptions;\n}\n\nexport const NostalgicDiva = React.memo(\n\t({ type, videoId, options }: NostalgicDivaProps): React.ReactElement => {\n\t\tconst { logger, playerApiRef } = useNostalgicDiva();\n\n\t\tlogger.log(LogLevel.Debug, 'NostalgicDiva');\n\n\t\tconst Player = players[type];\n\t\treturn (\n\t\t\t<Player\n\t\t\t\tlogger={logger}\n\t\t\t\ttype={type}\n\t\t\t\tplayerApiRef={playerApiRef}\n\t\t\t\tvideoId={videoId}\n\t\t\t\toptions={options}\n\t\t\t/>\n\t\t);\n\t},\n);\n"],"names":["LogLevel","PlayerApiImpl","logger","playerElementRef","options","AudioPlayerApi","__publicField","event","_b","_a","id","seconds","volume","muted","_PlayerApi","type","loadScript","playerApiFactory","message","optionalParams","PlayerApi","useFirstMountState","isFirst","useRef","strictEquals","prev","next","usePreviousDistinct","value","compare","prevRef","curRef","PlayerContainer","playerApiRef","videoId","children","videoIdRef","React","playerApi","setPlayerApi","previousVideoId","AudioPlayer","props","PlayerStatus","_NiconicoPlayerApi","data","_d","_c","_f","_e","_h","_g","_j","_i","_l","_k","_n","_m","resolve","reject","NiconicoPlayerApi","NiconicoPlayer","NostalgicDivaContext","defaultLogger","logLevel","NostalgicDivaProvider","loadVideo","play","pause","setCurrentTime","setVolume","setMuted","getDuration","getCurrentTime","useNostalgicDiva","SoundCloudPlayerApi","player","duration","url","getScript","script","loadState","urls","ensureScriptLoaded","error","SoundCloudPlayer","VimeoPlayerApi","fraction","VimeoPlayer","PlayerState","_YouTubePlayerApi","currentTime","YouTubePlayerApi","YouTubePlayer","players","NostalgicDiva","Player"],"mappings":"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"}
|