// ==UserScript==
// @name Extract YouTube Heatmap Points
// @namespace http://tampermonkey.net/
// @version 1
// @description Extract heatmap points from YouTube video player's heatmap path,返回视频秒数对应的热度值,最大值100
// @author Your Name
// @match https://www.youtube.com/watch*
// @grant none
// ==/UserScript==
(function() {
'use strict';
function pathToPoints(path, total) {
const commands = path.split(/(?=[LMC])/);
const points = [];
for (const command of commands) {
const [type, ...args] = command.split(/[\s,]+/);
if (type === 'M' || type === 'L') {
points.push([Math.round(+args[0]), Math.round((100 - +args[1]) * 100) / 100]);
} else if (type === 'C') {
points.push(
[Math.round(+args[0]), Math.round((100 - +args[1]) * 100) / 100],
[Math.round(+args[2]), Math.round((100 - +args[3]) * 100) / 100],
[Math.round(+args[4]), Math.round((100 - +args[5]) * 100) / 100]
);
}
}
const lastX = points[points.length - 1][0];
const ratio = total / lastX;
return points
.map(([x, y]) => [Math.round(x * ratio), Math.round(y * 100) / 100])
.filter(([x], i, arr) => x <= total && (!arr[i + 1] || arr[i + 1][0] !== x));
}
function extractHeatmapPoints() {
let totalTimeStr = document.getElementsByClassName("ytp-time-duration")[0].textContent;
let totalSeconds = timeToSeconds(totalTimeStr);
let path = document.getElementsByClassName("ytp-heat-map-path")[0].getAttribute("d");
let points = pathToPoints(path, totalSeconds);
return points;
}
function timeToSeconds(time) {
const parts = time.split(':');
let hours = 0;
let minutes = 0;
let seconds = 0;
if (parts.length === 3) {
hours = +parts[0];
minutes = +parts[1];
seconds = +parts[2];
} else if (parts.length === 2) {
minutes = +parts[0];
seconds = +parts[1];
} else {
seconds = +parts[0];
}
return hours * 3600 + minutes * 60 + seconds;
}
function addButton() {
// Check if the current URL matches the video player URL
if (!window.location.href.startsWith('https://www.youtube.com/watch')) {
return;
}
// Create a download button
const downloadButton = document.createElement('button');
downloadButton.textContent = 'Heat';
downloadButton.style.position = 'fixed';
downloadButton.style.top = '500px';
downloadButton.style.left = '0px';
downloadButton.addEventListener('click', () => {
const points = extractHeatmapPoints();
const json = JSON.stringify(points);
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'points.json';
a.click();
URL.revokeObjectURL(url);
});
document.body.appendChild(downloadButton);
}
addButton();
})();
上一篇
Python-贪吃蛇小游戏
2023-05-31
下一篇
JavaScript-获取YouTube视频播放进度条上的热度统计数据
2023-05-30