Files

171 lines
5.3 KiB
JavaScript

/**
* Screen Record Tool
* Records the user's screen using the Screen Capture API and MediaRecorder API
*
* @module ScreenRecord
* @description Standalone utility for capturing screen recordings. Exposes window.recordScreen()
* function for use in frontend code. No external dependencies beyond browser APIs.
* @usage Call window.recordScreen() after page load. User will see browser's native
* screen selector dialog. Returns Promise resolving to recording controller.
* @dependencies None (browser APIs only: Screen Capture API, MediaRecorder, Web Audio API)
* @integration Used in index.html to provide screen recording UI controls
*/
(function() {
console.log('Loading Screen Record Tool...');
/**
* Starts recording the user's selected screen/window
* Opens native browser dialog for user to select what to record
*
* @async
* @param {Object} [options={}] - Recording options
* @param {number} [options.maxDuration=300000] - Maximum recording duration in milliseconds (default: 5 minutes)
* @param {string} [options.mimeType='video/webm'] - MIME type for recording
* @param {Function} [options.onStart] - Callback when recording starts
* @param {Function} [options.onStop] - Callback when recording stops
* @returns {Promise<Object>} Recording controller object with stop() method and events
*
* @example
* const recorder = await window.recordScreen();
* // User is recording...
*
* setTimeout(() => {
* const file = await recorder.stop();
* console.log('Recording saved:', file.name);
* }, 10000);
*/
window.recordScreen = async function(options = {}) {
const {
maxDuration = 5 * 60 * 1000, // 5 minutes
mimeType = 'video/webm',
onStart = null,
onStop = null
} = options;
try {
// Request screen capture from user
const mediaStream = await navigator.mediaDevices.getDisplayMedia({
video: { mediaSource: 'screen' },
audio: false
});
// Create MediaRecorder
const mediaRecorder = new MediaRecorder(mediaStream, { mimeType });
const chunks = [];
let isRecording = true;
let timeoutId = null;
// Collect recording data
mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) {
chunks.push(event.data);
}
};
// Handle recording stop
mediaRecorder.onstop = () => {
isRecording = false;
clearTimeout(timeoutId);
mediaStream.getTracks().forEach(track => track.stop());
if (onStop) onStop();
};
// Start recording
mediaRecorder.start();
if (onStart) onStart();
// Set max duration timeout
timeoutId = setTimeout(() => {
if (isRecording) {
mediaRecorder.stop();
}
}, maxDuration);
// Stop if user stops screen share
mediaStream.getVideoTracks()[0].onended = () => {
if (isRecording) {
mediaRecorder.stop();
}
};
// Return controller object
return {
/**
* Stops the recording and returns the recorded file
* @returns {Promise<File>} WebM File object with recorded video
*/
stop: async () => {
return new Promise((resolve) => {
if (!isRecording) {
resolve(null);
return;
}
const stopHandler = () => {
mediaRecorder.removeEventListener('stop', stopHandler);
const blob = new Blob(chunks, { type: mimeType });
const file = new File(
[blob],
`screen-recording-${Date.now()}.webm`,
{ type: mimeType }
);
resolve(file);
};
mediaRecorder.addEventListener('stop', stopHandler);
mediaRecorder.stop();
});
},
/**
* Checks if recording is currently active
* @returns {boolean} True if recording is in progress
*/
isRecording: () => isRecording,
/**
* Gets the current recording duration in milliseconds
* @returns {number} Duration since recording started
*/
getDuration: () => mediaRecorder.state === 'recording' ? mediaRecorder.state : 0,
/**
* The underlying MediaStream object
* @type {MediaStream}
*/
mediaStream
};
} catch (error) {
console.error('Screen recording failed:', error);
return null;
}
};
/**
* Simple helper to start recording and stop after specified duration
* Useful for quick recordings with automatic stop
*
* @async
* @param {number} duration - Recording duration in milliseconds
* @returns {Promise<File>} WebM File object with recorded video
*
* @example
* const file = await window.recordScreenFor(10000); // Record for 10 seconds
* console.log('Recording saved:', file.name);
*/
window.recordScreenFor = async function(duration) {
const recorder = await window.recordScreen();
if (!recorder) return null;
return new Promise((resolve) => {
setTimeout(async () => {
const file = await recorder.stop();
resolve(file);
}, duration);
});
};
console.log('Screen Record Tool loaded successfully');
})();