2024-03-01 21:01:22 +01:00
|
|
|
//@ts-check
|
|
|
|
|
|
|
|
import JadefinIntegrity from '../JadefinIntegrity.js';
|
|
|
|
|
2024-10-19 02:40:36 +02:00
|
|
|
import Jadefin from "../Jadefin.js";
|
2024-03-01 21:01:22 +01:00
|
|
|
import JadefinMod from "../JadefinMod.js";
|
|
|
|
import JadefinModules from "../JadefinModules.js";
|
|
|
|
import JadefinUtils from "../JadefinUtils.js";
|
|
|
|
|
|
|
|
export default JadefinIntegrity("VolumeBoost", import.meta.url, () => new (class VolumeBoost extends JadefinMod {
|
|
|
|
audioCtx = new AudioContext();
|
|
|
|
audioBypass = this.audioCtx.createGain();
|
|
|
|
audioGain = this.audioCtx.createGain();
|
|
|
|
audioComp = this.audioCtx.createDynamicsCompressor();
|
|
|
|
audioCompGain = this.audioCtx.createGain();
|
|
|
|
|
|
|
|
_currentGain = 1;
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
|
|
|
|
this.audioBypass.gain.value = 1;
|
|
|
|
|
|
|
|
this.audioGain.gain.value = 0;
|
|
|
|
|
|
|
|
this.audioComp.knee.value = 40;
|
|
|
|
this.audioComp.ratio.value = 12;
|
|
|
|
this.audioComp.attack.value = 0;
|
|
|
|
this.audioComp.release.value = 0.25;
|
|
|
|
|
|
|
|
this.audioCompGain.gain.value = 0;
|
|
|
|
|
|
|
|
this.audioBypass.connect(this.audioCtx.destination);
|
|
|
|
this.audioGain.connect(this.audioComp).connect(this.audioCompGain).connect(this.audioCtx.destination);
|
|
|
|
|
|
|
|
document.addEventListener("click", e => this.audioCtxResume(), true);
|
|
|
|
}
|
|
|
|
|
|
|
|
get currentGain() {
|
|
|
|
return this._currentGain;
|
|
|
|
}
|
|
|
|
|
|
|
|
set currentGain(value) {
|
|
|
|
this.log.i(`Changing gain to ${value}`);
|
|
|
|
|
|
|
|
const diff = Math.abs(this._currentGain - value);
|
|
|
|
const timeNow = this.audioCtx.currentTime;
|
|
|
|
const time = this.audioCtx.currentTime + Math.min(0.5 * diff, 2);
|
|
|
|
|
|
|
|
if (diff != 0) {
|
|
|
|
this.audioBypass.gain.setValueAtTime(this.audioBypass.gain.value, timeNow);
|
|
|
|
this.audioGain.gain.setValueAtTime(this.audioGain.gain.value, timeNow);
|
|
|
|
this.audioCompGain.gain.setValueAtTime(this.audioCompGain.gain.value, timeNow);
|
|
|
|
this.audioBypass.gain.linearRampToValueAtTime((value <= 1) ? value : 0, time);
|
|
|
|
this.audioGain.gain.linearRampToValueAtTime((value <= 1) ? 0 : value, time);
|
|
|
|
this.audioCompGain.gain.linearRampToValueAtTime((value <= 1) ? 0 : 1, time);
|
|
|
|
}
|
|
|
|
|
|
|
|
this._currentGain = value;
|
|
|
|
this.connect();
|
|
|
|
}
|
|
|
|
|
|
|
|
async init(name, url) {
|
|
|
|
await super.init(name, url);
|
|
|
|
|
2024-10-19 02:40:36 +02:00
|
|
|
const ExtrasMenu = /** @type {import("./ExtrasMenu.js").default} */ (Jadefin.getMod("ExtrasMenu"));
|
|
|
|
|
|
|
|
ExtrasMenu.items.push({
|
|
|
|
name: "Volume Boost",
|
|
|
|
in: ExtrasMenu.IN_CUSTOM,
|
|
|
|
inCustom: (current, item) => {
|
|
|
|
item.asideText = `${this.currentGain}x`;
|
|
|
|
|
|
|
|
return (current & (ExtrasMenu.IN_PLAYBACKSETTINGS)) == current;
|
|
|
|
},
|
|
|
|
cb: async (positionTo) => {
|
|
|
|
JadefinModules.actionSheet.show({
|
|
|
|
positionTo,
|
|
|
|
items: [
|
|
|
|
{id: "1", name: "1x", selected: this.currentGain == 1},
|
|
|
|
{id: "2", name: "2x", selected: this.currentGain == 2},
|
|
|
|
{id: "3", name: "3x", selected: this.currentGain == 3},
|
|
|
|
{id: "4", name: "4x", selected: this.currentGain == 4},
|
|
|
|
]
|
|
|
|
}).then(id => {
|
|
|
|
if (!id) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.currentGain = parseInt(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
2024-03-01 21:01:22 +01:00
|
|
|
|
|
|
|
document.addEventListener("viewshow", () => {
|
|
|
|
if (JadefinUtils.routePathIsVideo) {
|
|
|
|
this.log.i("Navigating to video");
|
|
|
|
this.audioCtxResume();
|
|
|
|
|
|
|
|
if (this._connectRepeat) {
|
|
|
|
clearInterval(this._connectRepeat);
|
|
|
|
}
|
|
|
|
|
|
|
|
clearInterval(this._connectRepeat);
|
|
|
|
this._connectRepeat = setInterval(() => this.connect(), 100);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.log.i("Ready");
|
|
|
|
}
|
|
|
|
|
|
|
|
connect() {
|
|
|
|
const video = JadefinUtils.video;
|
|
|
|
if (!video) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const last = this.video;
|
|
|
|
const lastSrc = this.videoSrc;
|
|
|
|
|
|
|
|
if (video != last) {
|
|
|
|
lastSrc?.disconnect();
|
|
|
|
this.videoSrc = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.video = video;
|
|
|
|
if (!this.videoSrc) {
|
|
|
|
this.log.i("Connected to video element");
|
|
|
|
this.log.dir(this.video);
|
|
|
|
|
|
|
|
this.videoSrc = this.audioCtx.createMediaElementSource(this.video);
|
|
|
|
this.videoSrc.connect(this.audioBypass);
|
|
|
|
this.videoSrc.connect(this.audioGain);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._connectRepeat) {
|
|
|
|
clearInterval(this._connectRepeat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
audioCtxResume() {
|
|
|
|
if (this.audioCtx.state === "suspended") {
|
|
|
|
this.audioCtx.resume();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})());
|