171 lines
5.3 KiB
JavaScript
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');
|
|
})();
|