-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathoffscreen.js
More file actions
53 lines (49 loc) · 1.93 KB
/
Copy pathoffscreen.js
File metadata and controls
53 lines (49 loc) · 1.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// Offscreen document: the ONLY place OpenJam can run getUserMedia + MediaRecorder
// (the MV3 service worker has no DOM). Records mic narration to a webm/opus blob,
// returns it to the worker as a base64 data URL (chrome messaging is JSON-only, so
// a Blob/ArrayBuffer would be lost). Created and closed by background.js per
// recording. Reuses the extension-scoped mic grant obtained in the popup.
const MIME = "audio/webm;codecs=opus";
let recorder = null;
let chunks = [];
let stream = null;
let startWall = null;
async function start(deviceId) {
stream = await navigator.mediaDevices.getUserMedia({
audio: deviceId ? { deviceId: { exact: deviceId } } : true,
});
chunks = [];
recorder = new MediaRecorder(stream, MediaRecorder.isTypeSupported(MIME) ? { mimeType: MIME } : undefined);
recorder.ondataavailable = (e) => { if (e.data && e.data.size) chunks.push(e.data); };
startWall = Date.now();
recorder.start();
}
function stop() {
return new Promise((resolve) => {
if (!recorder) return resolve(null);
recorder.onstop = async () => {
const durationMs = Date.now() - startWall;
const blob = new Blob(chunks, { type: MIME });
const dataUrl = await new Promise((res) => {
const fr = new FileReader();
fr.onloadend = () => res(fr.result);
fr.readAsDataURL(blob);
});
if (stream) stream.getTracks().forEach((t) => t.stop());
recorder = null; stream = null;
resolve({ dataUrl, mime: MIME, startWall, durationMs });
};
recorder.stop();
});
}
chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
if (msg.type === "oj-audio-start") {
start(msg.deviceId || null).then(() => sendResponse({ ok: true }))
.catch((e) => sendResponse({ ok: false, error: String(e) }));
return true; // async response
}
if (msg.type === "oj-audio-stop") {
stop().then((r) => sendResponse(r)).catch(() => sendResponse(null));
return true;
}
});