1
0

added seek bar functionality

This commit is contained in:
anon 2024-10-15 14:56:50 +00:00
parent 0b6058965f
commit 132ffe86ba

166
script.js
View File

@ -1,8 +1,8 @@
// ==UserScript==
// @name antisocial.moe - youtube music scrobbler
// @namespace http://tampermonkey.net/
// @version 2.0
// @author
// @version 2.1
// @description Scrobbles songs from YouTube Music to antisocial.moe, with progress bar monitoring
// @match https://music.youtube.com/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
@ -186,6 +186,90 @@
// Timer for scrobbling after 10 seconds of playback
let playbackTimer = null;
/**
* ============================
* Progress Monitoring Logic
* ============================
*/
/**
* Gets the current progress percentage of the song.
* @returns {number|null} Progress percentage (0-100) or null if not available.
*/
function getProgressPercentage() {
const progressBar = querySelectorDeep('#progress-bar');
if (progressBar) {
const valueNow = parseInt(progressBar.getAttribute('aria-valuenow'), 10);
const valueMax = parseInt(progressBar.getAttribute('aria-valuemax'), 10);
if (!isNaN(valueNow) && !isNaN(valueMax) && valueMax > 0) {
return (valueNow / valueMax) * 100;
}
}
return null;
}
// Variable to keep track of last progress percentage
let lastProgressPercentage = null;
/**
* Handles progress changes and detects jumps from >95% to <5%.
* @param {number} newPercentage - The new progress percentage.
*/
function handleProgressChange(newPercentage) {
if (lastProgressPercentage === null) {
lastProgressPercentage = newPercentage;
return;
}
if (lastProgressPercentage > 95 && newPercentage < 5) {
console.log('Progress jumped from >95% to <5%. Sending new scrobble.');
const songInfo = getSongInfo();
if (songInfo) {
scrobble(songInfo.title, songInfo.author, songInfo.album);
} else {
console.warn('Cannot scrobble: song information not found.');
}
}
lastProgressPercentage = newPercentage;
}
/**
* Initializes a MutationObserver to monitor the progress bar's aria-valuenow.
*/
function initProgressObserver() {
const progressBar = querySelectorDeep('#progress-bar');
if (!progressBar) {
console.error('Progress bar not found. Progress monitoring not initialized.');
return;
}
// Initialize lastProgressPercentage
lastProgressPercentage = getProgressPercentage();
console.debug('Initial progress percentage:', lastProgressPercentage);
// Create observer
const progressObserver = new MutationObserver((mutations) => {
for (let mutation of mutations) {
if (mutation.type === 'attributes' && mutation.attributeName === 'aria-valuenow') {
const newPercentage = getProgressPercentage();
if (newPercentage !== null) {
console.debug(`Progress updated: ${newPercentage.toFixed(2)}%`);
handleProgressChange(newPercentage);
}
}
}
});
// Observe aria-valuenow
progressObserver.observe(progressBar, { attributes: true, attributeFilter: ['aria-valuenow'] });
console.log('Progress observer initialized.');
}
/**
* ============================
* Scrobbling Logic (continued)
* ============================
*/
/**
* Handles the scrobbling logic when a song change or playback state change is detected.
* Scrobbles the song only if it has been playing for more than 10 seconds and is currently playing.
@ -208,31 +292,33 @@
if (!areSongsEqual(lastScrobbledSong, songInfo)) {
console.log(`New song detected: "${songInfo.title}" by ${songInfo.author} from "${songInfo.album}"`);
// Update lastScrobbledSong to prevent repeated attempts
// Note: We update it here to prevent multiple timers for the same song
lastScrobbledSong = songInfo;
// Clear any existing timer
if (playbackTimer) {
clearTimeout(playbackTimer);
playbackTimer = null;
}
// Check if the song is currently playing
if (isPlaying()) {
if (!scrobbleScheduled) {
scrobbleScheduled = true;
playbackTimer = setTimeout(() => {
if (isPlaying()) {
scrobble(songInfo.title, songInfo.author, songInfo.album);
playbackTimer = null;
} else {
console.log('Playback stopped before scrobble threshold.');
scrobbleScheduled = false;
}
}, 10000); // 10 seconds
console.log('Started 10-second timer for scrobble.');
}
if (isPlaying() && !scrobbleScheduled) {
scrobbleScheduled = true;
// Update lastScrobbledSong to prevent repeated attempts
// Note: We update it here to prevent multiple timers for the same song
lastScrobbledSong = songInfo;
// Clear any existing timer
if (playbackTimer) {
clearTimeout(playbackTimer);
playbackTimer = null;
scrobbleScheduled = false;
}
playbackTimer = setTimeout(() => {
if (isPlaying()) {
scrobble(songInfo.title, songInfo.author, songInfo.album);
playbackTimer = null;
} else {
console.log('Playback stopped before scrobble threshold.');
scrobbleScheduled = false;
}
}, 10000); // 10 seconds
console.log('Started 10-second timer for scrobble.');
} else {
console.debug(`isPlaying: ${isPlaying()} scrobbleScheduled: ${scrobbleScheduled}`)
}
} else {
console.debug('Same song, no action needed.');
@ -298,6 +384,12 @@
console.log('YouTube Music Scrobbler with Conditional Scrobbling is now active.');
}
/**
* ============================
* Initialization
* ============================
*/
/**
* Waits for the player bar to be available in the DOM before initializing the observer.
*/
@ -309,6 +401,9 @@
initObserver();
// Initial scrobble handling
handleScrobble();
// Initialize progress observer
initProgressObserver();
}
}, 1000); // Check every second
@ -319,12 +414,6 @@
// }, 30000); // 30 seconds
}
/**
* ============================
* UI for Managing AUTH_KEY
* ============================
*/
/**
* Prompts the user to enter their AUTH_KEY and stores it using GM_setValue.
*/
@ -350,15 +439,8 @@
}
/**
* ============================
* Initialization
* ============================
* Optionally, prompt the user to set the AUTH_KEY if it's not already set.
*/
// Register the menu command for setting the AUTH_KEY
registerMenuCommands();
// Optionally, prompt the user to set the AUTH_KEY if it's not already set
function promptForAuthKeyIfNeeded() {
const authKey = GM_getValue('AUTH_KEY', '');
if (!authKey) {
@ -366,6 +448,9 @@
}
}
// Register the menu command for setting the AUTH_KEY
registerMenuCommands();
// Start the script by waiting for the player bar to load
waitForPlayerBar();
@ -373,4 +458,3 @@
promptForAuthKeyIfNeeded();
})();