Restore three-button capture interface: Share Entire Screen, Snip, Cancel
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Screen Record Tool
|
||||
* Records the user's screen using the Screen Capture API and MediaRecorder API
|
||||
*
|
||||
* @module ScreenRecord
|
||||
*/
|
||||
|
||||
(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');
|
||||
})();
|
||||
Reference in New Issue
Block a user