UNPKG

react-screen-recording

Version:

A simple React-friendly screen recorder package using MediaRecorder API

110 lines (94 loc) 3 kB
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;