jadefin/mods/VolumeBoost.js

147 lines
4.6 KiB
JavaScript

//@ts-check
import JadefinIntegrity from '../JadefinIntegrity.js';
import Jadefin from "../Jadefin.js";
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);
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);
});
}
});
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();
}
}
})());