Some fixes
This commit is contained in:
parent
ec216264b1
commit
cf0703f7f5
13 changed files with 798 additions and 0 deletions
95
offscreen.js
Normal file
95
offscreen.js
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// ============================================================
|
||||
// Volume Booster — Offscreen Document
|
||||
// Läuft in einem unsichtbaren DOM-Kontext. Nur hier sind
|
||||
// getUserMedia + AudioContext verfügbar. Hält pro Tab einen
|
||||
// GainNode und gibt den verstärkten Stream wieder aus.
|
||||
// ============================================================
|
||||
|
||||
// Map<tabId, { context, gain, source, stream }>
|
||||
const active = new Map();
|
||||
|
||||
function teardown(tabId) {
|
||||
const entry = active.get(tabId);
|
||||
if (!entry) return;
|
||||
try {
|
||||
entry.source.disconnect();
|
||||
entry.gain.disconnect();
|
||||
entry.stream.getTracks().forEach((t) => t.stop());
|
||||
entry.context.close();
|
||||
} catch (e) {
|
||||
/* trotzdem aufräumen */
|
||||
}
|
||||
active.delete(tabId);
|
||||
}
|
||||
|
||||
async function applyBoost(tabId, streamId, value) {
|
||||
// Falls (z. B. nach Fehler) noch ein alter Eintrag existiert: erst sauber weg.
|
||||
if (active.has(tabId)) {
|
||||
teardown(tabId);
|
||||
}
|
||||
|
||||
// Stream aus der ID erzeugen
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: {
|
||||
mandatory: {
|
||||
chromeMediaSource: "tab",
|
||||
chromeMediaSourceId: streamId,
|
||||
},
|
||||
},
|
||||
video: false,
|
||||
});
|
||||
|
||||
const context = new AudioContext();
|
||||
const source = context.createMediaStreamSource(stream);
|
||||
const gain = context.createGain();
|
||||
gain.gain.value = value;
|
||||
|
||||
source.connect(gain);
|
||||
gain.connect(context.destination); // Audio bleibt für den Nutzer hörbar
|
||||
|
||||
// Wenn der Stream endet (Tab neu geladen / geschlossen)
|
||||
const track = stream.getAudioTracks()[0];
|
||||
if (track) {
|
||||
track.addEventListener("ended", () => teardown(tabId));
|
||||
}
|
||||
|
||||
active.set(tabId, { context, gain, source, stream });
|
||||
return { ok: true, boosting: true, value };
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
||||
if (msg.target !== "offscreen") return false;
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
if (msg.type === "APPLY") {
|
||||
const res = await applyBoost(msg.tabId, msg.streamId, msg.value);
|
||||
sendResponse(res);
|
||||
} else if (msg.type === "GAIN") {
|
||||
// Nur die Lautstärke eines bereits aktiven Tabs ändern
|
||||
const entry = active.get(msg.tabId);
|
||||
if (entry) {
|
||||
entry.gain.gain.value = msg.value;
|
||||
sendResponse({ ok: true, boosting: true, value: msg.value });
|
||||
} else {
|
||||
// Kein aktiver Stream (mehr) — Popup soll neu anwenden
|
||||
sendResponse({ ok: false, error: "no active stream", boosting: false });
|
||||
}
|
||||
} else if (msg.type === "STOP") {
|
||||
teardown(msg.tabId);
|
||||
sendResponse({ ok: true, boosting: false });
|
||||
} else if (msg.type === "STATE") {
|
||||
const entry = active.get(msg.tabId);
|
||||
sendResponse({
|
||||
ok: true,
|
||||
boosting: !!entry,
|
||||
value: entry ? entry.gain.gain.value : 1,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
sendResponse({ ok: false, error: String((err && err.message) || err) });
|
||||
}
|
||||
})();
|
||||
|
||||
return true; // async
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue