puppeteer-stream
Version:
An Extension for Puppeteer to retrieve audio and/or video streams of a page
86 lines (85 loc) • 2.69 kB
JavaScript
const recorders = {};
const START_RECORDING = async ({ index, video, audio, frameSize, audioBitsPerSecond, videoBitsPerSecond, bitsPerSecond, mimeType, videoConstraints, audioConstraints, delay, tabId, }) => {
console.log("[PUPPETEER_STREAM] START_RECORDING", JSON.stringify({
index,
video,
audio,
frameSize,
audioBitsPerSecond,
videoBitsPerSecond,
bitsPerSecond,
mimeType,
videoConstraints,
audioConstraints,
tabId,
}));
const client = new WebSocket(`ws://localhost:${window.location.hash.substring(1)}/?index=${index}`, []);
await new Promise((resolve) => {
if (client.readyState === WebSocket.OPEN)
resolve();
client.addEventListener("open", () => resolve());
});
const stream = await new Promise((resolve, reject) => {
chrome.tabCapture.capture({
audio,
video,
audioConstraints,
videoConstraints,
}, (stream) => {
var _a;
if (chrome.runtime.lastError || !stream) {
reject((_a = chrome.runtime.lastError) === null || _a === void 0 ? void 0 : _a.message);
}
else {
resolve(stream);
}
});
});
// somtimes needed to sync audio and video
if (delay)
await new Promise((resolve) => setTimeout(resolve, delay));
const recorder = new MediaRecorder(stream, {
audioBitsPerSecond,
videoBitsPerSecond,
bitsPerSecond,
mimeType,
});
recorder.ondataavailable = async (e) => {
if (!e.data.size)
return;
const buffer = await e.data.arrayBuffer();
client.send(buffer);
};
recorders[index] = recorder;
// TODO: recorder onerror
recorder.onerror = () => recorder.stop();
recorder.onstop = function () {
try {
const tracks = stream.getTracks();
tracks.forEach(function (track) {
track.stop();
});
if (client.readyState === WebSocket.OPEN)
client.close();
}
catch (error) { }
};
stream.onremovetrack = () => {
try {
recorder.stop();
}
catch (error) { }
};
recorder.start(frameSize);
};
const STOP_RECORDING = async (index) => {
console.log("[PUPPETEER_STREAM] STOP_RECORDING", index);
if (!recorders[index])
return;
if (recorders[index].state === "inactive")
return;
recorders[index].stop();
};
globalThis.START_RECORDING = START_RECORDING;
globalThis.STOP_RECORDING = STOP_RECORDING;
export {};