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) => {
audioElement.src = recordedAudioUrl;
playButton.disabled = false;
- stream.getTracks().forEach((track) => track.stop());
+ cleanupCaptureResources();
});
mediaRecorder.start();
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);
}
});