From: Taran Nathan Date: Tue, 21 Jul 2026 03:57:43 +0000 (-0700) Subject: screen recording X-Git-Url: https://git.taranathan.com/?a=commitdiff_plain;p=audio-stream.git screen recording --- diff --git a/script.js b/script.js index 5534818..ec65453 100644 --- a/script.js +++ b/script.js @@ -1,16 +1,63 @@ let mediaRecorder; let audioChunks = []; let recordedAudioUrl = ""; +let microphoneStream; +let systemStream; +let mixedAudioStream; +let audioContext; +let mixedDestination; const startButton = document.getElementById("btnStart"); const stopButton = document.getElementById("btnStop"); const playButton = document.getElementById("btnPlay"); const audioElement = document.getElementById("audioPlay"); +function cleanupCaptureResources() { + [microphoneStream, systemStream, mixedAudioStream].forEach((stream) => { + if (stream) { + stream.getTracks().forEach((track) => track.stop()); + } + }); + + if (audioContext) { + audioContext.close(); + } + + microphoneStream = null; + systemStream = null; + mixedAudioStream = null; + audioContext = null; + mixedDestination = null; +} + startButton.addEventListener("click", async () => { try { - const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - mediaRecorder = new MediaRecorder(stream); + microphoneStream = await navigator.mediaDevices.getUserMedia({ audio: true }); + systemStream = await navigator.mediaDevices.getDisplayMedia({ + video: true, + audio: true + }); + + console.log(systemStream.getTracks()); + + if (systemStream.getAudioTracks().length === 0) { + console.error( "No screen share audio track. Microphone only." ); + systemStream.getTracks().forEach((track) => track.stop()); + systemStream = null; + } + + audioContext = new AudioContext(); + mixedDestination = audioContext.createMediaStreamDestination(); + + const micSource = audioContext.createMediaStreamSource(microphoneStream); + micSource.connect(mixedDestination); + if (systemStream) { + const systemSource = audioContext.createMediaStreamSource(systemStream); + systemSource.connect(mixedDestination); + } + + mixedAudioStream = mixedDestination.stream; + mediaRecorder = new MediaRecorder(mixedAudioStream); audioChunks = []; mediaRecorder.addEventListener("dataavailable", (event) => { @@ -32,7 +79,7 @@ startButton.addEventListener("click", async () => { audioElement.src = recordedAudioUrl; playButton.disabled = false; - stream.getTracks().forEach((track) => track.stop()); + cleanupCaptureResources(); }); mediaRecorder.start(); @@ -40,7 +87,11 @@ startButton.addEventListener("click", async () => { stopButton.disabled = false; playButton.disabled = true; } catch (error) { - console.error("Microphone access failed:", error); + cleanupCaptureResources(); + startButton.disabled = false; + stopButton.disabled = true; + playButton.disabled = !recordedAudioUrl; + console.error("Audio capture setup failed:", error); } });