Skip to content

Instantly share code, notes, and snippets.

@danthareja
Created September 17, 2024 19:51
Show Gist options
  • Save danthareja/0119f20c64394bdeee832faad242e5a7 to your computer and use it in GitHub Desktop.
Save danthareja/0119f20c64394bdeee832faad242e5a7 to your computer and use it in GitHub Desktop.
Screen capture proof of concept
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Screen and Microphone Recorder</title>
<style>
body {
font-family: Arial, sans-serif;
line-height: 1.6;
padding: 20px;
}
button {
margin: 10px 0;
padding: 10px;
cursor: pointer;
}
#videoPreview {
max-width: 100%;
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Screen and Microphone Recorder</h1>
<button id="startBtn">Start Recording</button>
<button id="stopBtn" disabled>Stop Recording</button>
<button id="downloadBtn" disabled>Download Recording</button>
<video id="videoPreview" controls></video>
<script>
let mediaRecorder;
let recordedChunks = [];
const startBtn = document.getElementById("startBtn");
const stopBtn = document.getElementById("stopBtn");
const downloadBtn = document.getElementById("downloadBtn");
const videoPreview = document.getElementById("videoPreview");
startBtn.addEventListener("click", startRecording);
stopBtn.addEventListener("click", stopRecording);
downloadBtn.addEventListener("click", downloadRecording);
async function startRecording() {
recordedChunks = [];
try {
const screenStream = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true, // This captures system audio if available
});
const micStream = await navigator.mediaDevices.getUserMedia({
audio: true,
});
const combinedStream = new MediaStream([
...screenStream.getVideoTracks(),
...mergeAudioStreams(screenStream, micStream).getTracks(),
]);
mediaRecorder = new MediaRecorder(combinedStream);
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunks.push(event.data);
}
};
mediaRecorder.onstop = () => {
const blob = new Blob(recordedChunks, { type: "video/webm" });
videoPreview.src = URL.createObjectURL(blob);
downloadBtn.disabled = false;
};
mediaRecorder.start();
startBtn.disabled = true;
stopBtn.disabled = false;
} catch (error) {
console.error("Error starting recording:", error);
}
}
function stopRecording() {
mediaRecorder.stop();
startBtn.disabled = false;
stopBtn.disabled = true;
}
function downloadRecording() {
const blob = new Blob(recordedChunks, { type: "video/webm" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = url;
a.download = "screen-recording.webm";
a.click();
window.URL.revokeObjectURL(url);
}
function mergeAudioStreams(screenStream, micStream) {
const context = new AudioContext();
const destination = context.createMediaStreamDestination();
if (screenStream.getAudioTracks().length > 0) {
const sourceScreen = context.createMediaStreamSource(screenStream);
sourceScreen.connect(destination);
}
const sourceMic = context.createMediaStreamSource(micStream);
sourceMic.connect(destination);
return destination.stream;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment