diff --git a/www/js/channel/channel.js b/www/js/channel/channel.js index a246996..c373e56 100644 --- a/www/js/channel/channel.js +++ b/www/js/channel/channel.js @@ -39,7 +39,7 @@ class channel{ //Set defaults for any unset settings and run any required process steps for the current config this.setDefaults(false, true); - //Freak out any weirdos who take a peek in the dev console for gaffs + //Freak out any weirdos who take a peek in the dev console for shits n gigs console.log("👁️👄👁️ ℬℴ𝓊𝓃𝒿ℴ𝓊𝓇."); } @@ -152,6 +152,22 @@ class channel{ } } + //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 + const 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}); + } + //Stop while we're ahead return; } diff --git a/www/js/channel/mediaHandler.js b/www/js/channel/mediaHandler.js index e6f7e2a..4b6079f 100644 --- a/www/js/channel/mediaHandler.js +++ b/www/js/channel/mediaHandler.js @@ -64,9 +64,15 @@ class mediaHandler{ } start(){ + this.setVideoTitle(this.nowPlaying.title); } sync(timestamp = this.lastTimestamp){ + //Skip sync calls that won't seek so we don't pointlessly throw selfAct + if(timestamp != this.video.currentTime){ + //Set self act flag + this.selfAct = true; + } } reload(){ @@ -95,8 +101,8 @@ class mediaHandler{ } setPlayerLock(lock){ - //set lock property - this.lock = lock; + //set lock property + this.lock = lock; } getRatio(){ @@ -165,14 +171,6 @@ class rawFileBase extends mediaHandler{ super.destroyPlayer(); } - sync(timestamp = this.lastTimestamp){ - //Skip sync calls that won't seek so we don't pointlessly throw selfAct - if(timestamp != this.video.currentTime){ - //Set self act flag - this.selfAct = true; - } - } - reload(){ //Call derived method super.reload(); @@ -270,9 +268,6 @@ class rawFileHandler extends rawFileBase{ //Set video volume this.video.volume = this.player.volume; - //Set video title - this.setVideoTitle(this.nowPlaying.title); - //Unlock player this.setPlayerLock(false); @@ -309,6 +304,21 @@ class youtubeEmbedHandler extends mediaHandler{ constructor(client, player, media){ //Call derived constructor super(client, player, media, 'ytEmbed'); + + //Set flag to notify functions when the player is actually ready + this.ready = false; + + //Create property to hold video iframe for easy access + this.iframe = null; + } + + //custom start media function since we want the youtube player to call the start function once it's ready + startMedia(media){ + //If we properly ingested the media + if(this.ingestMedia(media)){ + //Build the video player + this.buildPlayer(); + } } buildPlayer(){ @@ -318,10 +328,6 @@ class youtubeEmbedHandler extends mediaHandler{ return console.warn("youtubeEmbedHandler.buildPlayer() Called before YT Iframe API Loaded, waiting on refresh to rebuild..."); } - //Clear out the player title so that youtube's baked in title can do it's thing. - //This will be replaced once we complete the full player control and remove the defualt youtube UI - this.player.title.textContent = ""; - //Create temp div for yt api to replace const tempDiv = document.createElement('div'); //Name the div @@ -333,9 +339,9 @@ class youtubeEmbedHandler extends mediaHandler{ this.video = new YT.Player('youtube-embed-player', { //Inject video id videoId: this.nowPlaying.id, - //Set up event listeners (NGL kinda nice of google to do it this way...) events: { - 'onReady': this.initializePlayer.bind(this) + 'onReady': this.start.bind(this), + 'onStateChange': this.onStateChange.bind(this) } }); @@ -343,8 +349,140 @@ class youtubeEmbedHandler extends mediaHandler{ super.buildPlayer(); } - initializePlayer(){ + start(){ + //Call derived start function + super.start(); + + //Set volume based on player volume + this.video.setVolume(this.player.volume * 100); + //Kick the video off this.video.playVideo(); + + //Pull iframe + this.iframe = this.video.getIframe() + + //Throw the ready flag + this.ready = true; + } + + destroyPlayer(){ + //If we've had enough time to create a player frame + if(this.ready){ + //Pull volume from player before destroying since google didn't give us a volume change event like a bunch of dicks + this.player.volume = (this.video.getVolume() / 100); + + //Use the embed api's built in destroy function + this.video.destroy(); + } + + //If we have any leftovers + if(this.iframe != null){ + //Nukem like last nights chicken + iframe.remove(); + } + + //Call derived destroy function + super.destroyPlayer(); + } + + sync(timestamp = this.lastTimestamp){ + //If we're not ready + if(!this.ready){ + //Kick off a timer to wait it out and try again l8r + setTimeout(this.sync.bind(this), 100); + + //If it failed, tell randy to fuck off + return; + } + + //Seek to timestamp, allow buffering + this.video.seekTo(timestamp, true); + } + + reload(){ + //if we're ready + if(this.ready){ + //re-load the video by id + this.video.loadVideoById(this.nowPlaying.id); + } + } + + play(){ + //If we're ready + if(this.ready){ + //play the video + this.video.playVideo(); + } + } + + pause(){ + //If we're ready + if(this.ready){ + //pause the video + this.video.pauseVideo(); + } + } + + getRatio(){ + //TODO: Implement a type-specific metadata property object in the media class to hold type-sepecifc meta-data + //Alternatively we could fill in resolution information from the raw link + //However keeping embedded functionality dependant on raw-links seems like bad practice + } + + getTimestamp(){ + //If we're ready + if(this.ready){ + //Return the timestamp + return this.video.getCurrentTime(); + } + + //If we fall through, simply report that the video hasn't gone anywhere yet + return 0; + } + + setVideoTitle(){ + //Clear out the player title so that youtube's baked in title can do it's thing. + //This will be replaced once we complete the full player control and remove the defualt youtube UI + this.player.title.textContent = ""; + } + + //Generic handler for state changes since google is a dick + onStateChange(event){ + switch(event.data){ + //video unstarted + case -1: + return; + //video ended + case 0: + return; + //video playing + case 1: + return; + //video paused + case 2: + super.onPause(event); + return; + //video buffering + case 3: + //There is no good way to tell slow connections apart from user seeking + //This will be easier to implement once we get custom player controls up + //super.onSeek(event); + return; + //video queued + case 5: + return; + //bad status code + default: + return; + } + } + + setPlayerLock(lock){ + super.setPlayerLock(lock); + + if(this.ready){ + this.iframe.style.pointerEvents = (lock ? "none" : ""); + } } } \ No newline at end of file diff --git a/www/js/channel/player.js b/www/js/channel/player.js index ec59b1e..55b8387 100644 --- a/www/js/channel/player.js +++ b/www/js/channel/player.js @@ -149,6 +149,12 @@ class player{ } updateCurrentRawFile(data){ + //typecheck the media handler to see if we really need to do any of this shit, if not... + if(this.mediaHandler.type == 'ytEmbed'){ + //Ignore it + return; + } + //Grab current item from media handler const currentItem = this.mediaHandler.nowPlaying;