diff --git a/plugins/sponsorblock/back.js b/plugins/sponsorblock/back.js index 592d486d..04667b85 100644 --- a/plugins/sponsorblock/back.js +++ b/plugins/sponsorblock/back.js @@ -13,7 +13,7 @@ module.exports = (win, options) => { ...options, }; - ipcMain.on("song-info-request", async (_, data) => { + ipcMain.on("video-src-changed", async (_, data) => { videoID = JSON.parse(data)?.videoDetails?.videoId; const segments = await fetchSegments(apiURL, categories); win.webContents.send("sponsorblock-skip", segments); diff --git a/providers/song-info-front.js b/providers/song-info-front.js index 03a8c6b1..8b3c302f 100644 --- a/providers/song-info-front.js +++ b/providers/song-info-front.js @@ -16,11 +16,19 @@ module.exports = () => { document.addEventListener('apiLoaded', apiEvent => { const video = document.querySelector('video'); // name = "dataloaded" and abit later "dataupdated" - apiEvent.detail.addEventListener('videodatachange', (name, dataEvent) => { + apiEvent.detail.addEventListener('videodatachange', (name, _dataEvent) => { if (name !== 'dataloaded') return; video.dispatchEvent(srcChangedEvent); - ipcRenderer.send("song-info-request", JSON.stringify(dataEvent.playerResponse)); + ipcRenderer.send("video-src-changed", JSON.stringify(apiEvent.detail.getPlayerResponse())); }) - + for (const status of ['playing', 'pause']) { + video.addEventListener(status, sendSongInfo); + } + function sendSongInfo() { + const data = apiEvent.detail.getPlayerResponse(); + data.videoDetails.elapsedSeconds = Math.floor(video.currentTime); + data.videoDetails.isPaused = video.paused; + ipcRenderer.send("song-info-request", JSON.stringify(apiEvent.detail.getPlayerResponse())); + } }, { once: true, passive: true }); }; diff --git a/providers/song-info.js b/providers/song-info.js index 1c2c96c7..37954df2 100644 --- a/providers/song-info.js +++ b/providers/song-info.js @@ -4,32 +4,6 @@ const fetch = require("node-fetch"); const config = require("../config"); -// Grab the progress using the selector -const getProgress = async (win) => { - // Get current value of the progressbar element - return win.webContents.executeJavaScript( - 'document.querySelector("#progress-bar").value' - ); -}; - -// Grab the native image using the src -const getImage = async (src) => { - const result = await fetch(src); - const buffer = await result.buffer(); - const output = nativeImage.createFromBuffer(buffer); - if (output.isEmpty() && !src.endsWith(".jpg") && src.includes(".jpg")) { // fix hidden webp files (https://github.com/th-ch/youtube-music/issues/315) - return getImage(src.slice(0, src.lastIndexOf(".jpg")+4)); - } else { - return output; - } -}; - -// To find the paused status, we check if the title contains `-` -const getPausedStatus = async (win) => { - const title = await win.webContents.executeJavaScript("document.title"); - return !title.includes("-"); -}; - // Fill songInfo with empty values /** * @typedef {songInfo} SongInfo @@ -47,21 +21,48 @@ const songInfo = { url: "", }; +// Grab the native image using the src +const getImage = async (src) => { + const result = await fetch(src); + const buffer = await result.buffer(); + const output = nativeImage.createFromBuffer(buffer); + if (output.isEmpty() && !src.endsWith(".jpg") && src.includes(".jpg")) { // fix hidden webp files (https://github.com/th-ch/youtube-music/issues/315) + return getImage(src.slice(0, src.lastIndexOf(".jpg") + 4)); + } else { + return output; + } +}; + const handleData = async (responseText, win) => { - let data = JSON.parse(responseText); - songInfo.title = cleanupName(data?.videoDetails?.title); - songInfo.artist =cleanupName(data?.videoDetails?.author); - songInfo.views = data?.videoDetails?.viewCount; - songInfo.imageSrc = data?.videoDetails?.thumbnail?.thumbnails?.pop()?.url.split("?")[0]; - songInfo.songDuration = data?.videoDetails?.lengthSeconds; - songInfo.image = await getImage(songInfo.imageSrc); - songInfo.uploadDate = data?.microformat?.microformatDataRenderer?.uploadDate; - songInfo.url = data?.microformat?.microformatDataRenderer?.urlCanonical?.split("&")[0]; + const data = JSON.parse(responseText); + if (!data) return; - // used for options.resumeOnStart - config.set("url", data?.microformat?.microformatDataRenderer?.urlCanonical); + const microformat = data.microformat?.microformatDataRenderer; + if (microformat) { + songInfo.uploadDate = microformat.uploadDate; + songInfo.url = microformat.urlCanonical?.split("&")[0]; - win.webContents.send("update-song-info", JSON.stringify(songInfo)); + // used for options.resumeOnStart + config.set("url", microformat.urlCanonical); + } + + const videoDetails = data.videoDetails; + if (videoDetails) { + songInfo.title = cleanupName(videoDetails.title); + songInfo.artist = cleanupName(videoDetails.author); + songInfo.views = videoDetails.viewCount; + songInfo.songDuration = videoDetails.lengthSeconds; + songInfo.elapsedSeconds = videoDetails.elapsedSeconds; + songInfo.isPaused = videoDetails.isPaused; + + const oldUrl = songInfo.imageSrc; + songInfo.imageSrc = videoDetails.thumbnail?.thumbnails?.pop()?.url.split("?")[0]; + if (oldUrl !== songInfo.imageSrc) { + songInfo.image = await getImage(songInfo.imageSrc); + } + + win.webContents.send("update-song-info", JSON.stringify(songInfo)); + } }; // This variable will be filled with the callbacks once they register @@ -81,19 +82,6 @@ const registerCallback = (callback) => { }; const registerProvider = (win) => { - win.on("page-title-updated", async () => { - // Get and set the new data - songInfo.isPaused = await getPausedStatus(win); - - const elapsedSeconds = await getProgress(win); - songInfo.elapsedSeconds = elapsedSeconds; - - // Trigger the callbacks - callbacks.forEach((c) => { - c(songInfo); - }); - }); - // This will be called when the song-info-front finds a new request with song data ipcMain.on("song-info-request", async (_, responseText) => { await handleData(responseText, win); @@ -114,7 +102,7 @@ const suffixesToRemove = [ function cleanupName(name) { if (!name) return name; - const lowCaseName = name.toLowerCase(); + const lowCaseName = name.toLowerCase(); for (const suffix of suffixesToRemove) { if (lowCaseName.endsWith(suffix)) { return name.slice(0, -suffix.length);