//desktopRecord.js const convertBlobToBase64 = (blob) => { return new Promise((resolve) => { const reader = new FileReader(); reader.readAsDataURL(blob); reader.onloadend = () => { const base64data = reader.result; resolve(base64data); }; }); }; const fetchBlob = async (url) => { const response = await fetch(url); const blob = await response.blob(); const base64 = await convertBlobToBase64(blob); return base64; }; let recorder = null; let recordingData = null; chrome.runtime.onMessage.addListener(function (request, sender) { console.log("message received", request, sender); switch (request.type) { case "start-recording": startRecording(request.focusedTabId, request.quality); break; case "stop-recording": stopRecording(); break; default: console.log("default"); } return true; }); async function stopRecording() { console.log("Entered stopRecording"); if (recorder?.state === "recording") { console.log("Recorder state is 'recording', stopping..."); recorder.stop(); chrome.runtime.sendMessage({ type: "stop-camera" }, response => { if (response?.status === "camera-stopped") { console.log("Camera has been successfully stopped."); } else { console.log("Failed to stop the camera."); } }); chrome.tabs.query({}, (tabs) => { tabs.forEach((tab) => { chrome.tabs.sendMessage(tab.id, { type: "stop-camera" }, (response) => { if (response?.status === "camera-stopped") { console.log(`Camera stopped on tab ${tab.id}`); } else { console.log(`Failed to stop camera on tab ${tab.id}`); } }); }); }); } else { console.log("No active recording found or recorder is not in 'recording' state."); } } function stopAllMediaStreams(stream, microphone) { if (stream) { stream.getTracks().forEach((track) => { track.stop(); console.log("Media Track stopped:", track); }); } if (microphone) { microphone.getTracks().forEach((track) => { track.stop(); console.log("Microphone Track stopped", track); }); } } const startRecording = async (focusedTabId, quality) => { console.log("inside desktopRecord.js", quality); if (recorder) { await stopRecording(); // Wait for the previous recording to fully stop await new Promise(resolve => setTimeout(resolve, 100)); } // Reset recording data recordingData = []; chrome.desktopCapture.chooseDesktopMedia( ["screen", "window"], async function (streamId) { if (streamId === null) { return; } console.log("stream id from desktop capture", streamId); let videoConstraints; switch (quality) { case "low": videoConstraints = { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: streamId, maxWidth: 640, maxHeight: 480, minWidth: 640, minHeight: 480, maxFrameRate: 15, }, }; break; case "medium": videoConstraints = { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: streamId, maxWidth: 1280, maxHeight: 720, minWidth: 1280, minHeight: 720, maxFrameRate: 30, }, }; break; case "high": videoConstraints = { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: streamId, maxWidth: 1920, maxHeight: 1080, minWidth: 1920, minHeight: 1080, maxFrameRate: 60, }, }; break; default: videoConstraints = { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: streamId, }, }; } try { const stream = await navigator.mediaDevices.getUserMedia({ audio: { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: streamId, }, }, video: videoConstraints }); console.log("stream from desktop capture", stream); const microphone = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: false }, }); if (microphone.getAudioTracks().length !== 0) { const combinedStream = new MediaStream([ stream.getVideoTracks()[0], microphone.getAudioTracks()[0], ]); console.log("combined stream", combinedStream); recorder = new MediaRecorder(combinedStream, { mimeType: "video/webm", }); recorder.ondataavailable = (event) => { console.log("data available", event); if (event.data.size > 0) { recordingData.push(event.data); } }; recorder.onstop = async () => { console.log("recording stopped"); stopAllMediaStreams(stream, microphone); const currentData = recordingData; recorder = null; recordingData = null; if (currentData && currentData.length > 0) { const blobFile = new Blob(currentData, { type: "video/webm" }); const base64 = await fetchBlob(URL.createObjectURL(blobFile)); console.log("send message to open tab", base64); chrome.runtime.sendMessage({ type: "open-tab", base64 }); } }; recorder.start(); if (focusedTabId) { chrome.tabs.update(focusedTabId, { active: true }); } } } catch (error) { console.error("Error starting recording:", error); stopAllMediaStreams(null, null); recorder = null; recordingData = null; } } ); };