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 {};