From d2766f3af08eacc89c8b778c20c44d7c89af02c9 Mon Sep 17 00:00:00 2001 From: Ethan Matzdorf Date: Thu, 6 Oct 2022 22:12:06 -0400 Subject: [PATCH] fix player errors related to intervals / event handlers --- NUXT/components/Player/index.vue | 177 ++++++++++++++------------- NUXT/components/Player/watchtime.vue | 44 ++----- NUXT/plugins/vuetube.js | 2 +- 3 files changed, 104 insertions(+), 119 deletions(-) diff --git a/NUXT/components/Player/index.vue b/NUXT/components/Player/index.vue index 13962a8..041e405 100644 --- a/NUXT/components/Player/index.vue +++ b/NUXT/components/Player/index.vue @@ -202,12 +202,7 @@ :video="$refs.player" :buffering="bufferingDetected" @play="$refs.player.play(), $refs.audio.play()" - @pause=" - $refs.player.pause(), - $refs.audio.pause(), - clearTimeout(bufferingDetected), - (bufferingDetected = false) - " + @pause="pauseHandler" /> @@ -385,6 +380,9 @@ export default { }, recommends: { type: Array, + default: () => { + return []; + }, }, }, data() { @@ -407,12 +405,13 @@ export default { isVerticalVideo: false, // maybe rename(refactor everywhere used) to isShort bufferingDetected: false, isMusic: false, + vid: null, }; }, mounted() { console.log("sources", this.sources); console.log("recommends", this.recommends); - let vid = this.$refs.player; + this.vid = this.$refs.player; // TODO: this.$store.state.player.quality, check if exists and select the closest one if (this.$store.state.player.preload) this.prebuffer(this.sources[5].url); @@ -437,7 +436,18 @@ export default { // TODO: detect this.isMusic from the video or channel metadata instead of just SB segments - this.$refs.player.addEventListener("loadeddata", (e) => { + this.$refs.player.addEventListener("loadeddata", this.loadedDataEvent); + }, + created() { + screen.orientation.addEventListener("change", () => + this.fullscreenHandler(false) + ); + }, + beforeDestroy() { + this.cleanup(); + }, + methods: { + loadedDataEvent() { // console.log(e); // if (vid.networkState === vid.NETWORK_LOADING) { // // The user agent is actively trying to download data. @@ -446,10 +456,10 @@ export default { // if (vid.readyState < vid.HAVE_FUTURE_DATA) { // // There is not enough data to keep playing from this point // } - if (vid.readyState >= 3) { + if (this.vid.readyState >= 3) { this.$refs.audio.play(); this.bufferingDetected = false; - this.$refs.audio.currentTime = vid.currentTime; + this.$refs.audio.currentTime = this.vid.currentTime; if (!this.isMusic) { this.$refs.audio.playbackRate = this.$store.state.player.speed; @@ -461,81 +471,71 @@ export default { this.$refs.player.loop = this.$store.state.player.loop; this.$refs.audio.loop = this.$store.state.player.loop; - this.$refs.player.addEventListener("timeupdate", () => { - if (!this.seeking) this.progress = vid.currentTime; // for seekbar - - // console.log("sb check", this.blocks); - // iterate over data.segments array - // for sponsorblock - if (this.blocks.length > 0) - this.blocks.forEach((sponsor) => { - let vidTime = vid.currentTime; - - if ( - vidTime >= sponsor.segment[0] && - vidTime <= sponsor.segment[1] - ) { - console.log("Skipping the sponsor"); - this.$youtube.showToast("Skipped sponsor"); - this.$refs.player.currentTime = sponsor.segment[1] + 1; - this.$refs.audio.currentTime = this.$refs.player.currentTime; - } - }); - }); + this.$refs.player.addEventListener("timeupdate", this.timeUpdateEvent); // TODO: handle video ending with a "replay" button instead of if not on loop // TODO: split buffering into multiple sections as it should be for back/forth scrubbing - this.$refs.player.addEventListener("progress", () => { - if (this.bufferingDetected) { - this.$refs.audio.currentTime = vid.currentTime; - clearTimeout(this.bufferingDetected); - this.bufferingDetected = false; - } - if (this.$refs.audio.paused && !this.$refs.player.paused) this.$refs.audio.play(); - this.buffered = (vid.buffered.end(0) / vid.duration) * 100; - }); - - // buffering detection & sync - let threshold = 250; //ms after which user perceives buffering - - this.$refs.player.addEventListener("waiting", () => { - if (!this.$refs.player.paused) { - this.bufferingDetected = setTimeout(() => { - this.bufferingDetected = true; - this.$refs.audio.pause(); - //show buffering - }, threshold); - } - }); - this.$refs.player.addEventListener("playing", () => { - if (this.bufferingDetected != false) { - clearTimeout(this.bufferingDetected); - this.$refs.audio.currentTime = vid.currentTime; - this.bufferingDetected = false; - this.$refs.audio.play(); - } - }); + this.$refs.player.addEventListener("progress", this.progressEvent); + this.$refs.player.addEventListener("waiting", this.waitingEvent); + this.$refs.player.addEventListener("playing", this.playingEvent); } - }); - }, - created() { - screen.orientation.addEventListener("change", () => - this.fullscreenHandler(false) - ); - }, - beforeDestroy() { - this.cleanup(); - }, - methods: { + }, + timeUpdateEvent() { + if (!this.seeking) this.progress = this.vid.currentTime; // for seekbar + + // console.log("sb check", this.blocks); + // iterate over data.segments array + // for sponsorblock + if (this.blocks.length > 0) + this.blocks.forEach((sponsor) => { + let vidTime = this.vid.currentTime; + + if (vidTime >= sponsor.segment[0] && vidTime <= sponsor.segment[1]) { + console.log("Skipping the sponsor"); + this.$youtube.showToast("Skipped sponsor"); + this.$refs.player.currentTime = sponsor.segment[1] + 1; + this.$refs.audio.currentTime = this.$refs.player.currentTime; + } + }); + }, + progressEvent() { + if (this.bufferingDetected) { + this.$refs.audio.currentTime = this.vid.currentTime; + clearTimeout(this.bufferingDetected); + this.bufferingDetected = false; + } + if (this.$refs.audio.paused && !this.$refs.player.paused) + this.$refs.audio.play(); + this.buffered = (this.vid.buffered.end(0) / this.vid.duration) * 100; + }, + waitingEvent() { + // buffering detection & sync + let threshold = 250; //ms after which user perceives buffering + if (!this.$refs.player.paused) { + this.bufferingDetected = setTimeout(() => { + this.bufferingDetected = true; + this.$refs.audio.pause(); + //show buffering + }, threshold); + } + }, + playingEvent() { + if (this.bufferingDetected != false) { + clearTimeout(this.bufferingDetected); + this.$refs.audio.currentTime = this.vid.currentTime; + this.bufferingDetected = false; + this.$refs.audio.play(); + } + }, cleanup() { if (this.xhr) this.xhr.abort(); if (this.isFullscreen) this.exitFullscreen(); if (this.bufferingDetected) clearTimeout(this.bufferingDetected); screen.orientation.removeEventListener("change"); - //! this.$refs.player.removeEventListener("loadeddata"); // NOTE: needs a function to be passed as the 2nd argument, but breaks if called with vue method as the 2nd argument in mounted() - // this.$refs.player.removeEventListener("timeupdate"); - this.$refs.player.removeEventListener("progress", () => {}); - this.$refs.player.removeEventListener("waiting", () => {}); - this.$refs.player.removeEventListener("playing", () => {}); + this.$refs.player.removeEventListener("loadeddata", this.loadedDataEvent); + this.$refs.player.removeEventListener("timeupdate", this.timeUpdateEvent); + this.$refs.player.removeEventListener("progress", this.progressEvent); + this.$refs.player.removeEventListener("waiting", this.waitingEvent); + this.$refs.player.removeEventListener("playing", this.playingEvent); }, prebuffer(url) { this.xhr = new XMLHttpRequest(); @@ -689,15 +689,26 @@ export default { this.isFullscreen = true; //--- Fix pressing back button in fullscreen exiting the watch page ---// - this.$vuetube.addBackAction(new backType( - () => { this.exitFullscreen(true); }, - () => { return this.isFullscreen; } - )); - + this.$vuetube.addBackAction( + new backType( + () => { + this.exitFullscreen(true); + }, + () => { + return this.isFullscreen; + } + ) + ); }, getPlayer() { return this.$refs.player; }, + pauseHandler() { + this.$refs.player.pause(); + this.$refs.audio.pause(); + clearTimeout(this.bufferingDetected); + this.bufferingDetected = false; + }, }, }; diff --git a/NUXT/components/Player/watchtime.vue b/NUXT/components/Player/watchtime.vue index 0aef5c4..e703bd0 100644 --- a/NUXT/components/Player/watchtime.vue +++ b/NUXT/components/Player/watchtime.vue @@ -21,41 +21,15 @@ export default { required: true, }, }, - data() { - return { - humanWatchTime: "0:00", - humanDuration: "0:00", - - runWatchTimeUpdates: null - } + computed: { + humanDuration() { + if (this.duration) return this.$vuetube.humanTime(this.duration); + return "0:00"; + }, + humanWatchTime() { + if (this.currentTime) return this.$vuetube.humanTime(this.currentTime); + return "0:00"; + }, }, - mounted() { - //--- Only show end duration when 'this.duration' becomes defined ---// - const durationTimer = setInterval(() => { - if (this.duration) { - this.humanDuration = this.$vuetube.humanTime(this.duration); - return clearInterval(durationTimer); - } - }, 100); - //--- END Only show end duration when 'this.duration' becomes defined ---// - }, - - methods: { - updateWatchTime() { - this.humanWatchTime = this.$vuetube.humanTime(this.currentTime); - } - }, - - watch: { - controls(newVal) { - if (newVal) { // controls are VISIBLE - this.updateWatchTime(); // Call to immediately update - this.runWatchTimeUpdates = setInterval(this.updateWatchTime, 500); - } else { // Controls are INVISIBLE - clearInterval(this.runWatchTimeUpdates); - } - } - } - }; diff --git a/NUXT/plugins/vuetube.js b/NUXT/plugins/vuetube.js index cf0f7a8..88e56fd 100644 --- a/NUXT/plugins/vuetube.js +++ b/NUXT/plugins/vuetube.js @@ -138,7 +138,7 @@ const module = { } // join the array into a string with : as a sepatrator let returntext = levels.join(":"); - console.log(returntext); + // console.log(returntext); return returntext; }, //--- End Convert Time To Human Readable String ---//