Merge pull request #1065 from Araxeus/add-crossfade-menu-options

[crossfade] add menu options
This commit is contained in:
th-ch
2023-04-04 22:03:49 +02:00
committed by GitHub
9 changed files with 194 additions and 33 deletions

View File

@ -1,7 +1,9 @@
const { ipcMain } = require("electron");
const { Innertube } = require("youtubei.js");
module.exports = async (win, options) => {
require("./config");
module.exports = async () => {
const yt = await Innertube.create();
ipcMain.handle("audio-url", async (_, videoID) => {

View File

@ -0,0 +1,3 @@
const { PluginConfig } = require("../../config/dynamic");
const config = new PluginConfig("crossfade", { enableFront: true });
module.exports = { ...config };

View File

@ -8,13 +8,12 @@ let transitionAudio; // Howler audio used to fade out the current music
let firstVideo = true;
let waitForTransition;
// Crossfade options that can be overridden in plugin options
let crossfadeOptions = {
fadeInDuration: 1500, // ms
fadeOutDuration: 5000, // ms
exitMusicBeforeEnd: 10, // s
fadeScaling: "linear",
};
const defaultConfig = require("../../config/defaults").plugins.crossfade;
const configProvider = require("./config");
let config;
const configGetNum = (key) => Number(config[key]) || defaultConfig[key];
const getStreamURL = async (videoID) => {
const url = await ipcRenderer.invoke("audio-url", videoID);
@ -32,7 +31,7 @@ const isReadyToCrossfade = () => {
const watchVideoIDChanges = (cb) => {
navigation.addEventListener("navigate", (event) => {
const currentVideoID = getVideoIDFromURL(
event.currentTarget.currentEntry.url
event.currentTarget.currentEntry.url,
);
const nextVideoID = getVideoIDFromURL(event.destination.url);
@ -67,9 +66,10 @@ const createAudioForCrossfade = async (url) => {
const syncVideoWithTransitionAudio = async () => {
const video = document.querySelector("video");
const videoFader = new VolumeFader(video, {
fadeScaling: crossfadeOptions.fadeScaling,
fadeDuration: crossfadeOptions.fadeInDuration,
fadeScaling: configGetNum("fadeScaling"),
fadeDuration: configGetNum("fadeInDuration"),
});
await transitionAudio.play();
@ -94,8 +94,7 @@ const syncVideoWithTransitionAudio = async () => {
// Exit just before the end for the transition
const transitionBeforeEnd = () => {
if (
video.currentTime >=
video.duration - crossfadeOptions.exitMusicBeforeEnd &&
video.currentTime >= video.duration - configGetNum("secondsBeforeEnd") &&
isReadyToCrossfade()
) {
video.removeEventListener("timeupdate", transitionBeforeEnd);
@ -115,7 +114,7 @@ const onApiLoaded = () => {
});
};
const crossfade = (cb) => {
const crossfade = async (cb) => {
if (!isReadyToCrossfade()) {
cb();
return;
@ -130,8 +129,8 @@ const crossfade = (cb) => {
const fader = new VolumeFader(transitionAudio._sounds[0]._node, {
initialVolume: video.volume,
fadeScaling: crossfadeOptions.fadeScaling,
fadeDuration: crossfadeOptions.fadeOutDuration,
fadeScaling: configGetNum("fadeScaling"),
fadeDuration: configGetNum("fadeOutDuration"),
});
// Fade out the music
@ -142,11 +141,12 @@ const crossfade = (cb) => {
});
};
module.exports = (options) => {
crossfadeOptions = {
...crossfadeOptions,
options,
};
module.exports = async () => {
config = await configProvider.getAll();
configProvider.subscribeAll((newConfig) => {
config = newConfig;
});
document.addEventListener("apiLoaded", onApiLoaded, {
once: true,

72
plugins/crossfade/menu.js Normal file
View File

@ -0,0 +1,72 @@
const config = require("./config");
const defaultOptions = require("../../config/defaults").plugins.crossfade;
const prompt = require("custom-electron-prompt");
const promptOptions = require("../../providers/prompt-options");
module.exports = (win) => [
{
label: "Advanced",
click: async () => {
const newOptions = await promptCrossfadeValues(win, config.getAll());
if (newOptions) config.setAll(newOptions);
},
},
];
async function promptCrossfadeValues(win, options) {
const res = await prompt(
{
title: "Crossfade Options",
type: "multiInput",
multiInputOptions: [
{
label: "Fade in duration (ms)",
value: options.fadeInDuration || defaultOptions.fadeInDuration,
inputAttrs: {
type: "number",
required: true,
min: 0,
step: 100,
},
},
{
label: "Fade out duration (ms)",
value: options.fadeOutDuration || defaultOptions.fadeOutDuration,
inputAttrs: {
type: "number",
required: true,
min: 0,
step: 100,
},
},
{
label: "Crossfade x seconds before end",
value:
options.secondsBeforeEnd || defaultOptions.secondsBeforeEnd,
inputAttrs: {
type: "number",
required: true,
min: 0,
},
},
{
label: "Fade scaling",
selectOptions: { linear: "Linear", logarithmic: "Logarithmic" },
value: options.fadeScaling || defaultOptions.fadeScaling,
},
],
resizable: true,
height: 360,
...promptOptions(),
},
win,
).catch(console.error);
if (!res) return undefined;
return {
fadeInDuration: Number(res[0]),
fadeOutDuration: Number(res[1]),
secondsBeforeEnd: Number(res[2]),
fadeScaling: res[3],
};
}