react-screen-recording
Version:
A simple React-friendly screen recorder package using MediaRecorder API
110 lines (94 loc) • 3 kB
JavaScript
import React, { useState, useRef } from 'react';
import styled from 'styled-components';
const Button = styled.button`
position: fixed;
top: 20px;
right: 20px;
background: #4caf50;
border-radius: 50%;
padding: 0;
width: 50px;
height: 50px;
border: none;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.3);
&.recording {
background: #ff3d00;
}
`;
const VideoElement = styled.video`
position: fixed;
top: 20px;
right: 20px;
width: 20%;
max-width: 300px;
margin-top: 50px;
display: none;
`;
const ScreenRecorderButton = () => {
const [isRecording, setIsRecording] = useState(false);
const [videoURL, setVideoURL] = useState(null);
const videoElementRef = useRef(null);
const mediaRecorderRef = useRef(null);
const recordedChunksRef = useRef([]);
const screenStreamRef = useRef(null);
const startRecording = async () => {
try {
recordedChunksRef.current = [];
screenStreamRef.current = await navigator.mediaDevices.getDisplayMedia({
video: { mediaSource: 'screen' },
audio: true
});
mediaRecorderRef.current = new MediaRecorder(screenStreamRef.current);
mediaRecorderRef.current.ondataavailable = (event) => {
if (event.data.size > 0) {
recordedChunksRef.current.push(event.data);
}
};
mediaRecorderRef.current.onstop = () => {
const blob = new Blob(recordedChunksRef.current, { type: 'video/webm' });
const videoURL = URL.createObjectURL(blob);
setVideoURL(videoURL);
videoElementRef.current.style.display = 'block';
const a = document.createElement('a');
a.href = videoURL;
a.download = 'screen-recording.webm';
document.body.appendChild(a);
a.click();
screenStreamRef.current.getTracks().forEach(track => track.stop());
};
mediaRecorderRef.current.start();
setIsRecording(true);
} catch (err) {
alert('Screen recording failed: ' + err.message);
}
};
const stopRecording = () => {
if (mediaRecorderRef.current) {
mediaRecorderRef.current.stop();
setIsRecording(false);
}
};
return (
<div>
<Button
className={isRecording ? 'recording' : ''}
onClick={() => isRecording ? stopRecording() : startRecording()}
>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
{isRecording ? (
<rect x="6" y="6" width="12" height="12" fill="white" />
) : (
<circle cx="12" cy="12" r="10" fill="white" />
)}
</svg>
</Button>
<VideoElement ref={videoElementRef} controls src={videoURL} />
</div>
);
};
export default ScreenRecorderButton;