Some fixes

This commit is contained in:
Tronax 2026-05-15 21:11:59 +02:00
parent ec216264b1
commit cf0703f7f5
13 changed files with 798 additions and 0 deletions

124
background.js Normal file
View file

@ -0,0 +1,124 @@
// ============================================================
// Volume Booster — Background Service Worker
// In Manifest V3 kann der Service Worker selbst KEIN Audio
// capturen (kein DOM, kein getUserMedia). Er holt nur eine
// Stream-ID via chrome.tabCapture.getMediaStreamId und reicht
// sie an ein Offscreen-Dokument weiter, das den GainNode hält.
// ============================================================
let creating = null; // Promise-Lock, damit nicht zwei Offscreen-Docs entstehen
async function ensureOffscreen() {
const contexts = await chrome.runtime.getContexts({
contextTypes: ["OFFSCREEN_DOCUMENT"],
});
if (contexts.length > 0) return;
if (creating) {
await creating;
return;
}
creating = chrome.offscreen.createDocument({
url: "offscreen.html",
reasons: ["USER_MEDIA"],
justification: "Tab-Audio verstärken (Volume Booster)",
});
await creating;
creating = null;
}
// Nachrichten aus dem Popup
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
// Nachrichten fürs Offscreen-Dokument hier nicht behandeln
if (msg.target === "offscreen") return false;
(async () => {
try {
if (msg.type === "SET_VOLUME") {
const { tabId, value } = msg; // value: 0.0 6.0
await ensureOffscreen();
if (value === 1) {
// Exakt 100 %: Boost beenden, kein Capture nötig
const res = await chrome.runtime.sendMessage({
target: "offscreen",
type: "STOP",
tabId,
});
sendResponse(res || { ok: true, boosting: false });
return;
}
// ERST prüfen, ob dieser Tab schon einen aktiven Stream hat.
// Wenn ja, NUR den Gain ändern — keine neue Stream-ID holen!
// (Eine getMediaStreamId-ID ist einmalig und der Tab kann nicht
// ein zweites Mal gecaptured werden, solange der erste Stream läuft.)
const state = await chrome.runtime.sendMessage({
target: "offscreen",
type: "STATE",
tabId,
});
if (state && state.boosting) {
// Tab läuft schon: nur Lautstärke anpassen
const gainRes = await chrome.runtime.sendMessage({
target: "offscreen",
type: "GAIN",
tabId,
value,
});
if (gainRes && gainRes.ok) {
sendResponse(gainRes);
return;
}
// Falls der Stream zwischendurch verloren ging: unten neu capturen
}
// Tab noch nicht aktiv: jetzt eine frische Stream-ID holen
const streamId = await chrome.tabCapture.getMediaStreamId({
targetTabId: tabId,
});
const applyRes = await chrome.runtime.sendMessage({
target: "offscreen",
type: "APPLY",
tabId,
streamId,
value,
});
sendResponse(
applyRes || { ok: false, error: "Keine Antwort vom Offscreen-Dokument" }
);
} else if (msg.type === "GET_STATE") {
await ensureOffscreen();
const res = await chrome.runtime.sendMessage({
target: "offscreen",
type: "STATE",
tabId: msg.tabId,
});
sendResponse(res || { ok: true, boosting: false, value: 1 });
} else if (msg.type === "RESET") {
await ensureOffscreen();
const res = await chrome.runtime.sendMessage({
target: "offscreen",
type: "STOP",
tabId: msg.tabId,
});
sendResponse(res || { ok: true });
}
} catch (err) {
sendResponse({ ok: false, error: String((err && err.message) || err) });
}
})();
return true; // async sendResponse
});
// Aufräumen, wenn ein Tab geschlossen wird
chrome.tabs.onRemoved.addListener((tabId) => {
chrome.runtime
.sendMessage({ target: "offscreen", type: "STOP", tabId })
.catch(() => {});
});