Compare commits

..

15 Commits

Author SHA1 Message Date
c5bda4f3be Merge pull request #178 from th-ch/snyk-upgrade-da4beb25f2fa1631098996298cd49f89
[Snyk] Upgrade electron-store from 7.0.1 to 7.0.2
2021-03-09 19:50:17 +01:00
3dc92b4939 fix: upgrade electron-store from 7.0.1 to 7.0.2
Snyk has created this PR to upgrade electron-store from 7.0.1 to 7.0.2.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-03-05 02:19:09 +00:00
TC
150146385f Bump version 2021-03-04 23:09:27 +01:00
TC
f50bd32fa3 Fix resumeOnStart option 2021-03-04 23:09:01 +01:00
0dcf820944 Merge pull request #177 from NNowakowski/resume-last-song-on-start
Added function to toggle resuming of last song when app starts
2021-03-04 22:57:41 +01:00
6fd16684f7 Merge pull request #175 from th-ch/snyk-upgrade-024effb4b0bec6e73345b87366580cf3
[Snyk] Upgrade discord-rpc from 3.1.4 to 3.2.0
2021-03-04 22:54:13 +01:00
TC
eaa957168f Add plugin to disable autoplay 2021-03-04 22:47:53 +01:00
TC
796a7aaaf1 Fix download/speed menu item 2021-03-04 21:29:37 +01:00
9aaae7b2d9 🚀 Added function to toggle resuming of last song when app starts 2021-03-04 14:14:49 +01:00
c00609223b fix: upgrade discord-rpc from 3.1.4 to 3.2.0
Snyk has created this PR to upgrade discord-rpc from 3.1.4 to 3.2.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-03-04 02:19:26 +00:00
5641c3fc87 Merge pull request #154 from th-ch/snyk-upgrade-3f26f6e01fe99104189d358a840963dd
[Snyk] Upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0
2021-02-24 23:11:02 +01:00
dd1bdae947 Added metadata to downloader plugin, and updated packages 2021-02-24 22:53:31 +01:00
TC
70973b2281 Clear cache after 20s if option is enabled 2021-02-24 21:08:25 +01:00
TC
5842a6d42f Handle uncaught errors 2021-02-24 20:53:41 +01:00
538ab52abd fix: upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0
Snyk has created this PR to upgrade @cliqz/adblocker-electron from 1.19.0 to 1.20.0.

See this package in npm:


See this project in Snyk:
https://app.snyk.io/org/th-ch/project/81809c53-bb7b-46b9-a0d7-806d45d74ac6?utm_source=github&utm_medium=upgrade-pr
2021-02-12 02:19:15 +00:00
14 changed files with 1991 additions and 1830 deletions

View File

@ -14,6 +14,7 @@ const defaultConfig = {
restartOnConfigChanges: false,
trayClickPlayPause: false,
autoResetAppCache: false,
resumeOnStart: true,
},
plugins: {
// Enabled plugins

View File

@ -1,3 +1,4 @@
const defaultConfig = require("./defaults");
const plugins = require("./plugins");
const store = require("./store");
@ -10,6 +11,7 @@ const get = (key) => {
};
module.exports = {
defaultConfig,
get,
set,
edit: () => store.openInEditor(),

View File

@ -3,6 +3,11 @@ const Store = require("electron-store");
const defaults = require("./defaults");
const migrations = {
">=1.11.0": (store) => {
if (store.get("options.resumeOnStart") === undefined) {
store.set("options.resumeOnStart", true);
}
},
">=1.7.0": (store) => {
const enabledPlugins = store.get("plugins");
if (!Array.isArray(enabledPlugins)) {

View File

@ -3,6 +3,7 @@ const path = require("path");
const electron = require("electron");
const is = require("electron-is");
const unhandled = require("electron-unhandled");
const { autoUpdater } = require("electron-updater");
const config = require("./config");
@ -11,6 +12,12 @@ const { fileExists, injectCSS } = require("./plugins/utils");
const { isTesting } = require("./utils/testing");
const { setUpTray } = require("./tray");
// Catch errors and log them
unhandled({
logger: console.error,
showDialog: false,
});
const app = electron.app;
app.commandLine.appendSwitch(
"js-flags",
@ -104,7 +111,10 @@ function createMainWindow() {
win.maximize();
}
win.webContents.loadURL(config.get("url"));
const urlToLoad = config.get("options.resumeOnStart")
? config.get("url")
: config.defaultConfig.url;
win.webContents.loadURL(urlToLoad);
win.on("closed", onClosed);
win.on("move", () => {
@ -202,8 +212,14 @@ app.on("activate", () => {
app.on("ready", () => {
if (config.get("options.autoResetAppCache")) {
// Clear cache
electron.session.defaultSession.clearCache();
// Clear cache after 20s
const clearCacheTimeout = setTimeout(() => {
if (is.dev()) {
console.log("Clearing app cache.");
}
electron.session.defaultSession.clearCache();
clearTimeout(clearCacheTimeout);
}, 20000);
}
mainWindow = createMainWindow();

View File

@ -66,6 +66,14 @@ const mainMenuTemplate = (win) => [
config.set("options.autoResetAppCache", item.checked);
},
},
{
label: "Resume last song when app starts",
type: "checkbox",
checked: config.get("options.resumeOnStart"),
click: (item) => {
config.set("options.resumeOnStart", item.checked);
},
},
...(is.windows() || is.linux()
? [
{

View File

@ -1,7 +1,7 @@
{
"name": "youtube-music",
"productName": "YouTube Music",
"version": "1.10.0",
"version": "1.11.0",
"description": "YouTube Music Desktop App - including custom plugins",
"license": "MIT",
"repository": "th-ch/youtube-music",
@ -19,7 +19,10 @@
},
"win": {
"icon": "assets/generated/icons/win/icon.ico",
"target": ["nsis", "portable"]
"target": [
"nsis",
"portable"
]
},
"nsis": {
"runAfterFinish": false
@ -59,31 +62,33 @@
"npm": "Please use yarn and not npm"
},
"dependencies": {
"@cliqz/adblocker-electron": "^1.19.0",
"@cliqz/adblocker-electron": "^1.20.0",
"@ffmpeg/core": "^0.8.5",
"@ffmpeg/ffmpeg": "^0.9.7",
"YoutubeNonStop": "git://github.com/lawfx/YoutubeNonStop.git#v0.8.1",
"discord-rpc": "^3.1.4",
"browser-id3-writer": "^4.4.0",
"discord-rpc": "^3.2.0",
"downloads-folder": "^3.0.1",
"electron-debug": "^3.2.0",
"electron-is": "^3.0.0",
"electron-localshortcut": "^3.2.1",
"electron-store": "^6.0.1",
"electron-store": "^7.0.2",
"electron-unhandled": "^3.0.2",
"electron-updater": "^4.3.6",
"filenamify": "^4.2.0",
"node-fetch": "^2.6.1",
"ytdl-core": "^4.3.0"
"ytdl-core": "^4.4.5"
},
"devDependencies": {
"electron": "^11.1.1",
"electron-builder": "^22.8.1",
"electron": "^11.2.3",
"electron-builder": "^22.9.1",
"electron-devtools-installer": "^3.1.1",
"electron-icon-maker": "0.0.5",
"get-port": "^5.1.1",
"jest": "^26.4.2",
"jest": "^26.6.3",
"rimraf": "^3.0.2",
"spectron": "^13.0.0",
"xo": "^0.33.1"
"xo": "^0.37.1"
},
"resolutions": {
"yargs-parser": "18.1.3"

View File

@ -0,0 +1,25 @@
let videoElement = null;
const observer = new MutationObserver((mutations, observer) => {
if (!videoElement) {
videoElement = document.querySelector("video");
}
if (videoElement) {
videoElement.ontimeupdate = () => {
if (videoElement.currentTime === 0 && videoElement.duration !== NaN) {
// auto-confirm-when-paused plugin can interfere here if not disabled!
videoElement.pause();
}
};
}
});
function observeVideoElement() {
observer.observe(document, {
childList: true,
subtree: true,
});
}
module.exports = observeVideoElement;

View File

@ -1,6 +1,8 @@
const { writeFileSync } = require("fs");
const { join } = require("path");
const { dialog } = require("electron");
const ID3Writer = require("browser-id3-writer");
const { dialog, ipcMain } = require("electron");
const getSongInfo = require("../../providers/song-info");
const { injectCSS, listenAction } = require("../utils");
@ -23,10 +25,7 @@ function handle(win) {
injectCSS(win.webContents, join(__dirname, "style.css"));
const registerCallback = getSongInfo(win);
registerCallback((info) => {
metadata = {
...info,
image: info.image ? info.image.toDataURL() : undefined,
};
metadata = info;
});
listenAction(CHANNEL, (event, action, error) => {
@ -41,6 +40,33 @@ function handle(win) {
console.log("Unknown action: " + action);
}
});
ipcMain.on("add-metadata", (event, filePath, songBuffer) => {
let fileBuffer = songBuffer;
try {
const coverBuffer = metadata.image.toPNG();
const writer = new ID3Writer(songBuffer);
// Create the metadata tags
writer
.setFrame("TIT2", metadata.title)
.setFrame("TPE1", [metadata.artist])
.setFrame("APIC", {
type: 3,
data: coverBuffer,
description: "",
});
writer.addTag();
fileBuffer = Buffer.from(writer.arrayBuffer);
} catch (error) {
sendError(win, error);
}
writeFileSync(filePath, fileBuffer);
// Notify the youtube-dl file
event.reply("add-metadata-done");
});
}
module.exports = handle;

View File

@ -1,5 +1,6 @@
const { contextBridge } = require("electron");
const { getSongMenu } = require("../../providers/dom-elements");
const { ElementFromFile, templatePath, triggerAction } = require("../utils");
const { ACTIONS, CHANNEL } = require("./actions.js");
const { downloadVideoToMP3 } = require("./youtube-dl");
@ -13,7 +14,7 @@ let pluginOptions = {};
const observer = new MutationObserver((mutations, observer) => {
if (!menu) {
menu = document.querySelector("ytmusic-menu-popup-renderer paper-listbox");
menu = getSongMenu();
}
if (menu && !menu.contains(downloadButton)) {

View File

@ -1,8 +1,8 @@
const { randomBytes } = require("crypto");
const { writeFileSync } = require("fs");
const { join } = require("path");
const downloadsFolder = require("downloads-folder");
const { ipcRenderer } = require("electron");
const is = require("electron-is");
const filenamify = require("filenamify");
@ -109,12 +109,15 @@ const toMP3 = async (
const filename = filenamify(name + "." + extension, {
replacement: "_",
});
writeFileSync(
// Add the metadata
sendFeedback("Adding metadata…");
ipcRenderer.send(
"add-metadata",
join(folder, filename),
ffmpeg.FS("readFile", safeVideoName + "." + extension)
);
reinit();
ipcRenderer.once("add-metadata-done", reinit);
} catch (e) {
sendError(e);
}

View File

@ -1,4 +1,7 @@
const { watchDOMElement } = require("../../providers/dom-elements");
const {
getSongMenu,
watchDOMElement,
} = require("../../providers/dom-elements");
const { ElementFromFile, templatePath } = require("../utils");
const slider = ElementFromFile(templatePath(__dirname, "slider.html"));
@ -49,8 +52,7 @@ module.exports = () => {
watchDOMElement(
"menu",
(document) =>
document.querySelector("ytmusic-menu-popup-renderer paper-listbox"),
(document) => getSongMenu(document),
(menuElement) => {
if (!menuElement.contains(slider)) {
menuElement.prepend(slider);

View File

@ -5,7 +5,7 @@
aria-disabled="false"
aria-selected="false"
>
<paper-slider
<tp-yt-paper-slider
id="playback-speed-slider"
class="volume-slider style-scope ytmusic-player-bar on-hover"
max="100"
@ -22,68 +22,53 @@
aria-disabled="false"
value="50"
><!--css-build:shady-->
<div id="sliderContainer" class="style-scope paper-slider">
<div class="bar-container style-scope paper-slider">
<paper-progress
<div id="sliderContainer" class="style-scope tp-yt-paper-slider">
<div class="bar-container style-scope tp-yt-paper-slider">
<tp-yt-paper-progress
id="sliderBar"
aria-hidden="true"
class="style-scope paper-slider"
class="style-scope tp-yt-paper-slider"
role="progressbar"
value="50"
aria-valuenow="50"
aria-valuemin="0"
aria-valuemax="100"
aria-disabled="false"
style="touch-action: none;"
style="touch-action: none"
><!--css-build:shady-->
<div id="progressContainer" class="style-scope paper-progress">
<div id="progressContainer" class="style-scope tp-yt-paper-progress">
<div
id="secondaryProgress"
class="style-scope paper-progress"
class="style-scope tp-yt-paper-progress"
hidden="true"
style="transform: scaleX(0);"
style="transform: scaleX(0)"
></div>
<div
id="primaryProgress"
class="style-scope paper-progress"
style="transform: scaleX(0.5);"
class="style-scope tp-yt-paper-progress"
style="transform: scaleX(0.5)"
></div>
</div>
</paper-progress>
</tp-yt-paper-progress>
</div>
<dom-if class="style-scope paper-slider"
<dom-if class="style-scope tp-yt-paper-slider"
><template is="dom-if"></template
></dom-if>
<div
id="sliderKnob"
class="slider-knob style-scope paper-slider"
style="left: 50%; touch-action: none;"
class="slider-knob style-scope tp-yt-paper-slider"
style="left: 50%; touch-action: none"
>
<div
class="slider-knob-inner style-scope paper-slider"
class="slider-knob-inner style-scope tp-yt-paper-slider"
value="50"
></div>
<paper-ripple
id="ink"
center=""
class="circle style-scope paper-slider"
style="display: none;"
><!--css-build:shady-->
<div
id="background"
class="style-scope paper-ripple"
style="opacity: 0.006008;"
></div>
<div id="waves" class="style-scope paper-ripple"></div>
</paper-ripple>
</div>
</div>
<dom-if class="style-scope paper-slider"
><template is="dom-if"></template
></dom-if>
</paper-slider>
<dom-if class="style-scope tp-yt-paper-slider"
><template is="dom-if"></template></dom-if
></tp-yt-paper-slider>
<div
class="text style-scope ytmusic-toggle-menu-service-item-renderer"

View File

@ -17,4 +17,7 @@ const watchDOMElement = (name, selectorFn, cb) => {
});
};
module.exports = { watchDOMElement };
const getSongMenu = () =>
document.querySelector("ytmusic-menu-popup-renderer tp-yt-paper-listbox");
module.exports = { getSongMenu, watchDOMElement };

3617
yarn.lock

File diff suppressed because it is too large Load Diff