diff --git a/NUXT/components/videoPlayer.vue b/NUXT/components/videoPlayer.vue
index 6c1f165..a5158ed 100644
--- a/NUXT/components/videoPlayer.vue
+++ b/NUXT/components/videoPlayer.vue
@@ -1,38 +1,35 @@
-
-
-
-
diff --git a/NUXT/pages/watch.vue b/NUXT/pages/watch.vue
index 59e4e91..9dfa94c 100644
--- a/NUXT/pages/watch.vue
+++ b/NUXT/pages/watch.vue
@@ -4,6 +4,7 @@
@@ -95,6 +96,7 @@
import { Share } from "@capacitor/share";
import ShelfRenderer from "~/components/SectionRenderers/shelfRenderer.vue";
import VidLoadRenderer from "~/components/vidLoadRenderer.vue";
+import { getCpn } from "~/plugins/utils";
import SlimVideoDescriptionRenderer from "~/components/UtilRenderers/slimVideoDescriptionRenderer.vue";
export default {
@@ -135,6 +137,7 @@ export default {
views: null,
recommends: null,
loaded: false,
+ interval: null,
};
},
watch: {
@@ -144,18 +147,24 @@ export default {
handler(newRt, oldRt) {
if (newRt.query.v != oldRt.query.v) {
// Exit fullscreen if currently in fullscreen
- if (this.$refs.player) this.$refs.player.webkitExitFullscreen();
+ // if (this.$refs.player) this.$refs.player.webkitExitFullscreen();
// Reset player and run getVideo function again
this.vidSrc = "";
+ this.startTime = Math.floor(Date.now() / 1000);
+ clearInterval(this.interval);
this.getVideo();
}
},
},
},
mounted() {
- this.$youtube.saveApiStats("detailpage", this.$route.query.v, "streamingstats")
+ this.startTime = Math.floor(Date.now() / 1000);
this.getVideo();
},
+
+ destroyed() {
+ clearInterval(this.interval);
+ },
methods: {
getVideo() {
this.likes = 100;
@@ -186,6 +195,14 @@ export default {
this.recommends = result.renderedData.recommendations;
// .catch((error) => this.$logger("Watch", error, true));
console.log("recommendations:", this.recommends);
+
+ //--- API WatchTime call ---//
+ this.playbackTracking = result.playbackTracking;
+ this.cpn = getCpn();
+ this.initWatchTime().then(() => {
+ this.sendWatchTime();
+ this.interval = setInterval(this.sendWatchTime, 30000);
+ });
});
this.$youtube.getReturnYoutubeDislike(this.$route.query.v, (data) => {
@@ -208,6 +225,29 @@ export default {
dialogTitle: "Share video",
});
},
+ sendWatchTime() {
+ const player = this.$refs.player.getPlayer();
+ this.$youtube.saveApiStats(
+ {
+ cpn: this.cpn,
+ rt: Math.floor(Date.now() / 1000) - this.startTime,
+ et: player.currentTime,
+ state: player.paused ? "paused" : "playing",
+ volume: 100,
+ },
+ this.playbackTracking.videostatsWatchtimeUrl.baseUrl
+ );
+ },
+
+ async initWatchTime() {
+ await this.$youtube.saveApiStats(
+ {
+ cpn: this.cpn,
+ rt: Math.floor(Date.now() / 1000) - this.startTime,
+ },
+ this.playbackTracking.videostatsPlaybackUrl.baseUrl
+ );
+ },
},
};
diff --git a/NUXT/plugins/constants.js b/NUXT/plugins/constants.js
index 81d03cb..97425c4 100644
--- a/NUXT/plugins/constants.js
+++ b/NUXT/plugins/constants.js
@@ -6,7 +6,6 @@ const url = {
YT_MUSIC_URL: "https://music.youtube.com",
YT_BASE_API: "https://www.youtube.com/youtubei/v1",
YT_SUGGESTIONS: "https://suggestqueries.google.com/complete",
- YT_API_STATS: "https://www.youtube.com/api/stats/atr",
VT_GITHUB: "https://api.github.com/repos/Frontesque/VueTube",
};
diff --git a/NUXT/plugins/innertube.js b/NUXT/plugins/innertube.js
index b34006e..4716b26 100644
--- a/NUXT/plugins/innertube.js
+++ b/NUXT/plugins/innertube.js
@@ -189,20 +189,13 @@ class Innertube {
}
// WARNING: This is tracking the user's activity, but is required for recommendations to properly work
- async apiStats(currentPageType, id, event) {
- const params = {
- key: this.key,
- el: currentPageType,
- ns: "yt",
- docid: id,
- event: event,
- feature: "g-high-rec",
- c: this.context.client.clientName,
- volume: 100,
- cver: this.context.client.clientVersion,
- hl: this.context.client.hl,
- };
- await Http.post({ url: constants.URLS.YT_API_STATS, params: params });
+ async apiStats(params, url) {
+ console.log(params);
+ await Http.get({
+ url: url,
+ params: params,
+ headers: this.header,
+ });
}
// Static methods
@@ -303,6 +296,7 @@ class Innertube {
recommendationsContinuation:
columnUI?.continuations[0].reloadContinuationData?.continuation,
},
+ playbackTracking: responseInfo.playbackTracking,
};
console.log(vidData);
diff --git a/NUXT/plugins/utils.js b/NUXT/plugins/utils.js
index 92325bc..b918d2e 100644
--- a/NUXT/plugins/utils.js
+++ b/NUXT/plugins/utils.js
@@ -28,8 +28,18 @@ function rgbToHex(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
}
+function getCpn() {
+ const chars =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+ let result = "";
+ for (let i = 16; i > 0; --i)
+ result += chars[Math.round(Math.random() * (chars.length - 1))];
+ return result;
+}
+
module.exports = {
getBetweenStrings,
hexToRgb,
rgbToHex,
+ getCpn,
};
diff --git a/NUXT/plugins/youtube.js b/NUXT/plugins/youtube.js
index 335fb81..53fa021 100644
--- a/NUXT/plugins/youtube.js
+++ b/NUXT/plugins/youtube.js
@@ -152,8 +152,8 @@ const innertubeModule = {
}
},
- async saveApiStats(currentPageType, id, event) {
- await InnertubeAPI.apiStats(currentPageType, id, event);
+ async saveApiStats(query, url) {
+ await InnertubeAPI.apiStats(query, url);
},
};