mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 18:41:47 +00:00
Split providers in 2
This commit is contained in:
18
providers/song-controls.js
Normal file
18
providers/song-controls.js
Normal file
@ -0,0 +1,18 @@
|
||||
// This is used for to control the songs
|
||||
const pressKey = (window, key) => {
|
||||
window.webContents.sendInputEvent({
|
||||
type: "keydown",
|
||||
keyCode: key,
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = (win) => {
|
||||
return {
|
||||
previous: () => pressKey(win, "k"),
|
||||
next: () => pressKey(win, "j"),
|
||||
playPause: () => pressKey(win, "space"),
|
||||
like: () => pressKey(win, "_"),
|
||||
dislike: () => pressKey(win, "+"),
|
||||
search: () => pressKey(win, "/"),
|
||||
};
|
||||
};
|
||||
114
providers/song-info.js
Normal file
114
providers/song-info.js
Normal file
@ -0,0 +1,114 @@
|
||||
const { nativeImage } = require("electron");
|
||||
|
||||
const fetch = require("node-fetch");
|
||||
|
||||
// This selects the song title
|
||||
const titleSelector = ".title.style-scope.ytmusic-player-bar";
|
||||
|
||||
// This selects the song image
|
||||
const imageSelector =
|
||||
"#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > img";
|
||||
|
||||
// This selects the song subinfo, this includes artist, views, likes
|
||||
const subInfoSelector =
|
||||
"#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > div.content-info-wrapper.style-scope.ytmusic-player-bar > span";
|
||||
|
||||
// Grab the title using the selector
|
||||
const getTitle = (win) => {
|
||||
return win.webContents
|
||||
.executeJavaScript(
|
||||
"document.querySelector('" + titleSelector + "').innerText"
|
||||
)
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Grab the image src using the selector
|
||||
const getImageSrc = (win) => {
|
||||
return win.webContents
|
||||
.executeJavaScript("document.querySelector('" + imageSelector + "').src")
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Grab the subinfo using the selector
|
||||
const getSubInfo = async (win) => {
|
||||
// Get innerText of subinfo element
|
||||
const subInfoString = await win.webContents.executeJavaScript(
|
||||
'document.querySelector("' + subInfoSelector + '").innerText'
|
||||
);
|
||||
|
||||
// Split and clean the string
|
||||
const splittedSubInfo = subInfoString.replaceAll("\n", "").split(" • ");
|
||||
|
||||
// Make sure we always return 3 elements in the aray
|
||||
const subInfo = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
// Fill array with empty string if not defined
|
||||
subInfo.push(splittedSubInfo[i] || "");
|
||||
}
|
||||
|
||||
return subInfo;
|
||||
};
|
||||
|
||||
// Grab the native image using the src
|
||||
const getImage = async (src) => {
|
||||
const result = await fetch(src);
|
||||
const buffer = await result.buffer();
|
||||
return nativeImage.createFromBuffer(buffer);
|
||||
};
|
||||
|
||||
const getPausedStatus = async (win) => {
|
||||
const title = await win.webContents.executeJavaScript("document.title");
|
||||
return !title.includes("-");
|
||||
};
|
||||
|
||||
// Fill songInfo with empty values
|
||||
const songInfo = {
|
||||
title: "",
|
||||
artist: "",
|
||||
views: "",
|
||||
likes: "",
|
||||
imageSrc: "",
|
||||
image: null,
|
||||
isPaused: true,
|
||||
};
|
||||
|
||||
const registerProvider = (win) => {
|
||||
// This variable will be filled with the callbacks once they register
|
||||
const callbacks = [];
|
||||
|
||||
// This function will allow plugins to register callback that will be triggered when data changes
|
||||
const registerCallback = (callback) => {
|
||||
callbacks.push(callback);
|
||||
};
|
||||
|
||||
win.on("page-title-updated", async () => {
|
||||
// Save the old title temporarily
|
||||
const oldTitle = songInfo.title;
|
||||
// Get and set the new data
|
||||
songInfo.title = await getTitle(win);
|
||||
songInfo.isPaused = await getPausedStatus(win);
|
||||
|
||||
// If title changed then we do need to update other info
|
||||
if (oldTitle !== songInfo.title) {
|
||||
const subInfo = await getSubInfo(win);
|
||||
songInfo.artist = subInfo[0];
|
||||
songInfo.views = subInfo[1];
|
||||
songInfo.likes = subInfo[2];
|
||||
songInfo.imageSrc = await getImageSrc(win);
|
||||
songInfo.image = await getImage(songInfo.imageSrc);
|
||||
}
|
||||
|
||||
// Trigger the callbacks
|
||||
callbacks.forEach((c) => {
|
||||
c(songInfo);
|
||||
});
|
||||
});
|
||||
|
||||
return registerCallback;
|
||||
};
|
||||
|
||||
module.exports = registerProvider;
|
||||
@ -1,120 +0,0 @@
|
||||
const {nativeImage} = require('electron');
|
||||
const fetch = require('node-fetch');
|
||||
|
||||
// This selects the song title
|
||||
const titleSelector = '.title.style-scope.ytmusic-player-bar';
|
||||
|
||||
// This selects the song image
|
||||
const imageSelector = '#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > img';
|
||||
|
||||
// This selects the song subinfo, this includes artist, views, likes
|
||||
const subInfoSelector = '#layout > ytmusic-player-bar > div.middle-controls.style-scope.ytmusic-player-bar > div.content-info-wrapper.style-scope.ytmusic-player-bar > span';
|
||||
|
||||
// This is used for to control the songs
|
||||
const presskey = (window, key) => {
|
||||
window.webContents.sendInputEvent({
|
||||
type: 'keydown',
|
||||
keyCode: key
|
||||
});
|
||||
};
|
||||
|
||||
// Grab the title using the selector
|
||||
const getTitle = win => {
|
||||
return win.webContents.executeJavaScript(
|
||||
'document.querySelector(\'' + titleSelector + '\').innerText'
|
||||
).catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Grab the image src using the selector
|
||||
const getImageSrc = win => {
|
||||
return win.webContents.executeJavaScript(
|
||||
'document.querySelector(\'' + imageSelector + '\').src'
|
||||
).catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// Grab the subinfo using the selector
|
||||
const getSubInfo = async win => {
|
||||
// Get innerText of subinfo element
|
||||
const subInfoString = await win.webContents.executeJavaScript(
|
||||
'document.querySelector("' + subInfoSelector + '").innerText');
|
||||
|
||||
// Split and clean the string
|
||||
const splittedSubInfo = subInfoString.replaceAll('\n', '').split(' • ');
|
||||
|
||||
// Make sure we always return 3 elements in the aray
|
||||
const subInfo = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
// Fill array with empty string if not defined
|
||||
subInfo.push(splittedSubInfo[i] || '');
|
||||
}
|
||||
|
||||
return subInfo;
|
||||
};
|
||||
|
||||
// Grab the native image using the src
|
||||
const getImage = async src => {
|
||||
const result = await fetch(src);
|
||||
const buffer = await result.buffer();
|
||||
return nativeImage.createFromBuffer(buffer);
|
||||
};
|
||||
|
||||
const getPausedStatus = async win => {
|
||||
const title = await win.webContents.executeJavaScript('document.title');
|
||||
return !title.includes('-');
|
||||
};
|
||||
|
||||
// This variable will be filled with the callbacks once they register
|
||||
const callbacks = [];
|
||||
|
||||
module.exports = win => {
|
||||
// Fill songInfo with empty values
|
||||
global.songInfo = {
|
||||
title: '',
|
||||
artist: '',
|
||||
views: '',
|
||||
likes: '',
|
||||
imageSrc: '',
|
||||
image: null,
|
||||
isPaused: true
|
||||
};
|
||||
// The song control functions
|
||||
global.songControls = {
|
||||
previous: () => presskey(win, 'k'),
|
||||
next: () => presskey(win, 'j'),
|
||||
pause: () => presskey(win, 'space'),
|
||||
like: () => presskey(win, '_'),
|
||||
dislike: () => presskey(win, '+')
|
||||
};
|
||||
|
||||
// This function will allow plugins to register callback that will be triggered when data changes
|
||||
global.songInfo.onNewData = callback => {
|
||||
callbacks.push(callback);
|
||||
};
|
||||
|
||||
win.on('page-title-updated', async () => {
|
||||
// Save the old title temporarily
|
||||
const oldTitle = global.songInfo.title;
|
||||
// Get and set the new data
|
||||
global.songInfo.title = await getTitle(win);
|
||||
global.songInfo.isPaused = await getPausedStatus(win);
|
||||
|
||||
// If title changed then we do need to update other info
|
||||
if (oldTitle !== global.songInfo.title) {
|
||||
const subInfo = await getSubInfo(win);
|
||||
global.songInfo.artist = subInfo[0];
|
||||
global.songInfo.views = subInfo[1];
|
||||
global.songInfo.likes = subInfo[2];
|
||||
global.songInfo.imageSrc = await getImageSrc(win);
|
||||
global.songInfo.image = await getImage(global.songInfo.imageSrc);
|
||||
}
|
||||
|
||||
// Trigger the callbacks
|
||||
callbacks.forEach(c => {
|
||||
c(global.songInfo);
|
||||
});
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user