diff --git a/.gitignore b/.gitignore index 4d019d4..b7bef3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules/ -log/ +log/crash/* package-lock.json config.json state.json diff --git a/src/views/partial/panels/settings.ejs b/src/views/partial/panels/settings.ejs index 5b0eab5..ad14ec5 100644 --- a/src/views/partial/panels/settings.ejs +++ b/src/views/partial/panels/settings.ejs @@ -16,6 +16,7 @@ along with this program. If not, see . %>

Client Settings

+

Player Settings

Youtube Player Type:

+ +

Internet Archive CDN Server:

+ +
\ No newline at end of file diff --git a/www/css/panel/settings.css b/www/css/panel/settings.css index 95bfa62..869e0d5 100644 --- a/www/css/panel/settings.css +++ b/www/css/panel/settings.css @@ -17,6 +17,7 @@ along with this program. If not, see .*/ display: flex; flex-direction: column; gap: 1em; + align-items: center; } #settings-panel h2{ @@ -24,10 +25,22 @@ along with this program. If not, see .*/ margin: 1em 0 0; } +#settings-panel h4{ + text-align: center; + margin: 0; +} + .settings-panel-setting{ display: flex; flex-direction: row; text-wrap: nowrap; height: 1em; align-items: center; + max-width: 30em; + width: 100% +} + +.settings-panel-setting :is(input, select){ + width: 1px; + flex: 1 1 auto; } \ No newline at end of file diff --git a/www/js/channel/channel.js b/www/js/channel/channel.js index 49f9dc9..3e4ff1a 100644 --- a/www/js/channel/channel.js +++ b/www/js/channel/channel.js @@ -166,6 +166,9 @@ class channel{ * @param {*} value - Value to set setting to */ processConfig(key, value){ + //Unfortunately we can't scope constants to switch-cases so this is the best we got if we wanna re-use the name + let nowPlaying; + //Switch/case by config key switch(key){ case 'ytPlayerType': @@ -205,18 +208,35 @@ class channel{ return; } - //Get current video - const nowPlaying = this.player.mediaHandler.nowPlaying; + nowPlaying = this.player.mediaHandler.nowPlaying; //If we're playing a youtube video if(nowPlaying != null && nowPlaying.type == 'yt'){ //Restart the video - this.player.start({media: nowPlaying}); + this.player.hardReload(); } //Stop while we're ahead return; + + case 'IACDN': + //If the player or mediaHandler isn't loaded + if(this.player == null || this.player.mediaHandler == null){ + //We're fuggin done here + return; + } + + //Get current video + nowPlaying = this.player.mediaHandler.nowPlaying; + + //If we're playing a video from Internet Archive + if(nowPlaying != null && nowPlaying.type == 'ia'){ + //Hard reload the media, forcing media handler re-creation + this.player.hardReload(); + } + + return; } } @@ -224,7 +244,8 @@ class channel{ * Default channel config */ static defaultConfig = new Map([ - ["ytPlayerType","raw"] + ["ytPlayerType","raw"], + ["IACDN",""] ]); } diff --git a/www/js/channel/panels/settingsPanel.js b/www/js/channel/panels/settingsPanel.js index 73849a7..3f9ca54 100644 --- a/www/js/channel/panels/settingsPanel.js +++ b/www/js/channel/panels/settingsPanel.js @@ -32,8 +32,16 @@ class settingsPanel extends panelObj{ } docSwitch(){ + /** + * Youtube Source Selector + */ this.youtubeSource = this.panelDocument.querySelector("#settings-panel-youtube-source select"); + /** + * Internet Archive CDN Server Input + */ + this.IACDNInput = this.panelDocument.querySelector("#settings-panel-ia-server input"); + this.renderSettings(); this.setupInput(); } @@ -43,6 +51,7 @@ class settingsPanel extends panelObj{ */ setupInput(){ this.youtubeSource.addEventListener('change', this.updateYoutubeSource.bind(this)); + this.IACDNInput.addEventListener('keydown', this.updateIACDN.bind(this)); } /** @@ -50,6 +59,7 @@ class settingsPanel extends panelObj{ */ renderSettings(){ this.youtubeSource.value = localStorage.getItem("ytPlayerType"); + this.IACDNInput.value = localStorage.getItem("IACDN"); } /** @@ -59,4 +69,15 @@ class settingsPanel extends panelObj{ localStorage.setItem("ytPlayerType", this.youtubeSource.value); client.processConfig("ytPlayerType", this.youtubeSource.value); } + + /** + * Event handler for Internet Archive CDN Server input + * @param {Event} event - Event handed down by event listener + */ + updateIACDN(event){ + if(event.key == "Enter"){ + localStorage.setItem("IACDN", this.IACDNInput.value); + client.processConfig("IACDN", this.IACDNInput.value); + } + } } \ No newline at end of file diff --git a/www/js/channel/player.js b/www/js/channel/player.js index 5db4734..ec218f0 100644 --- a/www/js/channel/player.js +++ b/www/js/channel/player.js @@ -192,6 +192,18 @@ class player{ this.mediaHandler = new hlsDailymotionHandler(this.client, this, data.media); //Otherwise, if we have a raw-file compatible source }else if(data.media.type == 'ia' || data.media.type == 'raw' || data.media.type == 'yt' || data.media.type == 'dm'){ + //If we're running a source from IA + if(data.media.type == 'ia'){ + //Replace specified CDN with generic URL, in-case of hard reload + data.media.rawLink = data.media.rawLink.replace(/^https(.*)archive\.org(.*)items/g, "https://archive.org/download") + + //If we have an IA source and a custom IA CDN Server set + if(data.media.type == 'ia' && localStorage.getItem("IACDN") != ""){ + //Generate and set new link + data.media.rawLink = data.media.rawLink.replace("https://archive.org/download", `https://${localStorage.getItem("IACDN")}.archive.org/0/items`); + } + } + //Create a new raw file handler for it this.mediaHandler = new rawFileHandler(client, this, data.media); //Sync to time stamp @@ -244,6 +256,27 @@ class player{ } } + /** + * Destroys and Re-Creates media handler + */ + hardReload(){ + if(this.mediaHandler != null){ + //Re-create data we'd get from server + const data = { + media: this.mediaHandler.nowPlaying, + timestamp: this.mediaHandler.getTimestamp() + } + + //End current media handler + this.end(); + + console.log(data); + + //Restart from last media handlers + this.start(data); + } + } + /** * Handles End-Media Commands from the Server */