Skip to content

Commit

Permalink
Merge branch 'master' into mpris+tuna-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
Araxeus authored Dec 1, 2021
2 parents c99b95e + 362003e commit 2c39c0e
Show file tree
Hide file tree
Showing 12 changed files with 254 additions and 163 deletions.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"npm": "Please use yarn and not npm"
},
"dependencies": {
"@cliqz/adblocker-electron": "^1.22.6",
"@cliqz/adblocker-electron": "^1.23.0",
"@ffmpeg/core": "^0.10.0",
"@ffmpeg/ffmpeg": "^0.10.0",
"async-mutex": "^0.3.2",
Expand All @@ -78,11 +78,11 @@
"electron-localshortcut": "^3.2.1",
"electron-store": "^7.0.3",
"electron-unhandled": "^3.0.2",
"electron-updater": "^4.4.6",
"electron-updater": "^4.6.1",
"filenamify": "^4.3.0",
"md5": "^2.3.0",
"mpris-service": "^2.1.2",
"node-fetch": "^2.6.2",
"node-fetch": "^2.6.6",
"node-notifier": "^9.0.1",
"ytdl-core": "^4.9.1",
"ytpl": "^2.2.3"
Expand Down
10 changes: 6 additions & 4 deletions plugins/blur-nav-bar/style.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#nav-bar-background, #header.ytmusic-item-section-renderer {
background: rgba(0, 0, 0, 0.3) !important;
backdrop-filter: blur(18px) !important;
#nav-bar-background,
#header.ytmusic-item-section-renderer,
ytmusic-tabs {
background: rgba(0, 0, 0, 0.3) !important;
backdrop-filter: blur(8px) !important;
}

#nav-bar-divider {
display: none !important;
display: none !important;
}
13 changes: 10 additions & 3 deletions plugins/disable-autoplay/front.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
module.exports = () => {
document.addEventListener('apiLoaded', () => {
document.querySelector('video').addEventListener('loadeddata', e => {
e.target.pause();
document.addEventListener('apiLoaded', apiEvent => {
apiEvent.detail.addEventListener('videodatachange', name => {
if (name === 'dataloaded') {
apiEvent.detail.pauseVideo();
document.querySelector('video').ontimeupdate = e => {
e.target.pause();
}
} else {
document.querySelector('video').ontimeupdate = null;
}
})
}, { once: true, passive: true })
};
20 changes: 9 additions & 11 deletions plugins/downloader/menu.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
const { existsSync, mkdirSync } = require("fs");
const { join } = require("path");
const { URL } = require("url");

const { dialog } = require("electron");
const { dialog, ipcMain } = require("electron");
const is = require("electron-is");
const ytpl = require("ytpl");
const chokidar = require('chokidar');

const { setOptions } = require("../../config/plugins");
const registerCallback = require("../../providers/song-info");
const { sendError } = require("./back");
const { defaultMenuDownloadLabel, getFolder } = require("./utils");

let downloadLabel = defaultMenuDownloadLabel;
let metadataURL = undefined;
let playingPlaylistId = undefined;
let callbackIsRegistered = false;

module.exports = (win, options) => {
if (!callbackIsRegistered) {
registerCallback((info) => {
metadataURL = info.url;
ipcMain.on("video-src-changed", async (_, data) => {
playingPlaylistId = JSON.parse(data)?.videoDetails?.playlistId;
});
callbackIsRegistered = true;
}
Expand All @@ -28,17 +26,17 @@ module.exports = (win, options) => {
{
label: downloadLabel,
click: async () => {
const currentURL = metadataURL || win.webContents.getURL();
const playlistID = new URL(currentURL).searchParams.get("list");
if (!playlistID) {
const currentPagePlaylistId = new URL(win.webContents.getURL()).searchParams.get("list");
const playlistId = currentPagePlaylistId || playingPlaylistId;
if (!playlistId) {
sendError(win, new Error("No playlist ID found"));
return;
}

console.log(`trying to get playlist ID: '${playlistID}'`);
console.log(`trying to get playlist ID: '${playlistId}'`);
let playlist;
try {
playlist = await ytpl(playlistID, {
playlist = await ytpl(playlistId, {
limit: options.playlistMaxItems || Infinity,
});
} catch (e) {
Expand Down
47 changes: 47 additions & 0 deletions plugins/exponential-volume/front.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// "Youtube Music fix volume ratio 0.4" by Marco Pfeiffer
// https://greasyfork.org/en/scripts/397686-youtube-music-fix-volume-ratio/

const exponentialVolume = () => {
// manipulation exponent, higher value = lower volume
// 3 is the value used by pulseaudio, which Barteks2x figured out this gist here: https://gist.github.com/Barteks2x/a4e189a36a10c159bb1644ffca21c02a
// 0.05 (or 5%) is the lowest you can select in the UI which with an exponent of 3 becomes 0.000125 or 0.0125%
const EXPONENT = 3;

const storedOriginalVolumes = new WeakMap();
const { get, set } = Object.getOwnPropertyDescriptor(
HTMLMediaElement.prototype,
"volume"
);
Object.defineProperty(HTMLMediaElement.prototype, "volume", {
get() {
const lowVolume = get.call(this);
const calculatedOriginalVolume = lowVolume ** (1 / EXPONENT);

// The calculated value has some accuracy issues which can lead to problems for implementations that expect exact values.
// To avoid this, I'll store the unmodified volume to return it when read here.
// This mostly solves the issue, but the initial read has no stored value and the volume can also change though external influences.
// To avoid ill effects, I check if the stored volume is somewhere in the same range as the calculated volume.
const storedOriginalVolume = storedOriginalVolumes.get(this);
const storedDeviation = Math.abs(
storedOriginalVolume - calculatedOriginalVolume
);

const originalVolume =
storedDeviation < 0.01
? storedOriginalVolume
: calculatedOriginalVolume;
return originalVolume;
},
set(originalVolume) {
const lowVolume = originalVolume ** EXPONENT;
storedOriginalVolumes.set(this, originalVolume);
set.call(this, lowVolume);
},
});
};

module.exports = () =>
document.addEventListener("apiLoaded", exponentialVolume, {
once: true,
passive: true,
});
17 changes: 10 additions & 7 deletions plugins/in-app-menu/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
font-size: 14px !important;
}

/* fixes nav-bar-background opacity bug and allows clicking scrollbar through it */
/* fixes nav-bar-background opacity bug, reposition it, and allows clicking scrollbar through it */
#nav-bar-background {
opacity: 1 !important;
pointer-events: none;
pointer-events: none !important;
position: sticky !important;
top: 0 !important;
height: 75px !important;
}

/* remove window dragging for nav bar (conflict with titlebar drag) */
Expand All @@ -17,9 +20,10 @@ ytmusic-pivot-bar-item-renderer {
-webkit-app-region: unset !important;
}

/* move up item selection renderer by 13 px */
ytmusic-item-section-renderer.stuck #header.ytmusic-item-section-renderer {
top: calc(var(--ytmusic-nav-bar-height) - 13px) !important;
/* move up item selection renderers */
ytmusic-item-section-renderer.stuck #header.ytmusic-item-section-renderer,
ytmusic-tabs.stuck {
top: calc(var(--ytmusic-nav-bar-height) - 15px) !important;
}

/* fix weird positioning in search screen*/
Expand All @@ -28,8 +32,7 @@ ytmusic-header-renderer.ytmusic-search-page {
}

/* Move navBar downwards */
ytmusic-nav-bar[slot="nav-bar"],
#nav-bar-background {
ytmusic-nav-bar[slot="nav-bar"] {
top: 17px !important;
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/playback-speed/front.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const observePopupContainer = () => {

const observeVideo = () => {
$('video').addEventListener('ratechange', forcePlaybackRate)
$('video').addEventListener('loadeddata', forcePlaybackRate)
$('video').addEventListener('srcChanged', forcePlaybackRate)
}

const setupWheelListener = () => {
Expand Down
15 changes: 5 additions & 10 deletions plugins/sponsorblock/back.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
const fetch = require("node-fetch");
const is = require("electron-is");
const { ipcMain } = require("electron");

const defaultConfig = require("../../config/defaults");
const registerCallback = require("../../providers/song-info");
const { sortSegments } = require("./segments");

let videoID;
Expand All @@ -13,15 +13,10 @@ module.exports = (win, options) => {
...options,
};

registerCallback(async (info) => {
const newURL = info.url || win.webContents.getURL();
const newVideoID = new URL(newURL).searchParams.get("v");

if (videoID !== newVideoID) {
videoID = newVideoID;
const segments = await fetchSegments(apiURL, categories);
win.webContents.send("sponsorblock-skip", segments);
}
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);
});
};

Expand Down
44 changes: 31 additions & 13 deletions plugins/video-toggle/front.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ function $(selector) { return document.querySelector(selector); }

let options;

let api;

const switchButtonDiv = ElementFromFile(
templatePath(__dirname, "button_template.html")
);
Expand All @@ -17,7 +19,9 @@ module.exports = (_options) => {
document.addEventListener('apiLoaded', setup, { once: true, passive: true });
}

function setup() {
function setup(e) {
api = e.detail;

$('ytmusic-player-page').prepend(switchButtonDiv);

$('#song-image.ytmusic-player').style.display = "block"
Expand All @@ -35,13 +39,15 @@ function setup() {
setOptions("video-toggle", options);
})

$('video').addEventListener('loadedmetadata', videoStarted);
$('video').addEventListener('srcChanged', videoStarted);

observeThumbnail();
}

function changeDisplay(showVideo) {
if (!showVideo && $('ytmusic-player').getAttribute('playback-mode') !== "ATV_PREFERRED") {
if (!showVideo) {
$('video').style.top = "0";
$('ytmusic-player').style.margin = "auto 21.5px";
$('ytmusic-player').style.margin = "auto 0px";
$('ytmusic-player').setAttribute('playback-mode', "ATV_PREFERRED");
}

Expand All @@ -51,11 +57,8 @@ function changeDisplay(showVideo) {
}

function videoStarted() {
if (videoExist()) {
const thumbnails = $('#movie_player').getPlayerResponse()?.videoDetails?.thumbnail?.thumbnails;
if (thumbnails && thumbnails.length > 0) {
$('#song-image img').src = thumbnails[thumbnails.length-1].url;
}
if (api.getPlayerResponse().videoDetails.musicVideoType === 'MUSIC_VIDEO_TYPE_OMV') { // or `$('#player').videoMode_`
forceThumbnail($('#song-image img'));
switchButtonDiv.style.display = "initial";
if (!options.hideVideo && $('#song-video.ytmusic-player').style.display === "none") {
changeDisplay(true);
Expand All @@ -66,10 +69,6 @@ function videoStarted() {
}
}

function videoExist() {
return $('#player').videoMode_;
}

// on load, after a delay, the page overrides the playback-mode to 'OMV_PREFERRED' which causes weird aspect ratio in the image container
// this function fix the problem by overriding that override :)
function forcePlaybackMode() {
Expand All @@ -83,3 +82,22 @@ function forcePlaybackMode() {
});
playbackModeObserver.observe($('ytmusic-player'), { attributeFilter: ["playback-mode"] })
}

function observeThumbnail() {
const playbackModeObserver = new MutationObserver(mutations => {
if (!$('#player').videoMode_) return;

mutations.forEach(mutation => {
if (!mutation.target.src.startsWith('data:')) return;
forceThumbnail(mutation.target)
});
});
playbackModeObserver.observe($('#song-image img'), { attributeFilter: ["src"] })
}

function forceThumbnail(img) {
const thumbnails = $('#movie_player').getPlayerResponse()?.videoDetails?.thumbnail?.thumbnails;
if (thumbnails && thumbnails.length > 0) {
img.src = thumbnails[thumbnails.length - 1].url.split("?")[0];
}
}
39 changes: 31 additions & 8 deletions providers/song-info-front.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,41 @@ ipcRenderer.on("update-song-info", async (_, extractedSongInfo) => {
global.songInfo.image = await getImage(global.songInfo.imageSrc);
});

// used because 'loadeddata' or 'loadedmetadata' weren't firing on song start for some users (https://github.com/th-ch/youtube-music/issues/473)
const srcChangedEvent = new CustomEvent('srcChanged');

module.exports = () => {
document.addEventListener('apiLoaded', e => {
if (config.plugins.isEnabled('tuna-obs')) {
document.addEventListener('apiLoaded', apiEvent => {
if (config.plugins.isEnabled('tuna-obs')) {
setupTimeChangeListener();
}
const video = $('video');
// name = "dataloaded" and abit later "dataupdated"
apiEvent.detail.addEventListener('videodatachange', (name, _dataEvent) => {
if (name !== 'dataloaded') return;
video.dispatchEvent(srcChangedEvent);
sendSongInfo();
})

for (const status of ['playing', 'pause']) {
video.addEventListener(status, e => {
if (Math.round(e.target.currentTime) > 0) {
ipcRenderer.send("playPaused", {
isPaused: status === 'pause',
elapsedSeconds: Math.floor(e.target.currentTime)
});
}
});
}

$('video').addEventListener('loadedmetadata', () => {
const data = e.detail.getPlayerResponse();
data.videoDetails.album = $('ytmusic-player-page')?.__data?.playerPageWatchMetadata?.albumName?.runs[0].text
ipcRenderer.send("song-info-request", JSON.stringify(data));
});
}, { once: true, passive: true })
function sendSongInfo() {
const data = apiEvent.detail.getPlayerResponse();
data.videoDetails.album = $('ytmusic-player-page')?.__data?.playerPageWatchMetadata?.albumName?.runs[0].text
data.videoDetails.elapsedSeconds = Math.floor(video.currentTime);
data.videoDetails.isPaused = false;
ipcRenderer.send("video-src-changed", JSON.stringify(data));
}
}, { once: true, passive: true });
};

function setupTimeChangeListener() {
Expand Down
Loading

0 comments on commit 2c39c0e

Please sign in to comment.