Skip to content

Instantly share code, notes, and snippets.

@hamzakaya
Created April 28, 2022 20:15
Show Gist options
  • Save hamzakaya/4fbad22f5cf2fbbd51a874b171a20dde to your computer and use it in GitHub Desktop.
Save hamzakaya/4fbad22f5cf2fbbd51a874b171a20dde to your computer and use it in GitHub Desktop.
const _defaultOptions = {
fileName: `${new Date().toLocaleString('tr-TR')}- screen record`,
recording: {
video: true,
audio: true,
},
callbackRecording: (s: boolean) => {},
};
const secure = location.protocol === 'https:' || location.hostname === 'localhost',
recordType = { mimeType: 'video/webm' };
let recording: string | null,
chunks: Blob[] = [],
mediaRecorder: MediaRecorder | null,
stream: MediaStream | null,
isRecording = false;
export const getScreenRecord = (userOptions: DeepPartial<typeof _defaultOptions>) => {
const options = Object.assign({}, _defaultOptions, userOptions);
async function startCapturing(type: IMediaType = 'video') {
isRecording = true;
options.callbackRecording(isRecording);
try {
if (!secure) return notSecureError();
if (recording) window.URL.revokeObjectURL(recording);
chunks.length = 0;
recording = null;
if (navigator.mediaDevices.getDisplayMedia)
stream = await navigator.mediaDevices.getDisplayMedia(options.recording);
else stream = await navigator.mediaDevices.getUserMedia(options.recording);
mediaRecorder = new window.MediaRecorder(stream, recordType);
mediaRecorder.addEventListener('dataavailable', (event) => {
if (event?.data && event?.data?.size > 0) {
chunks.push(event.data);
}
});
mediaRecorder.addEventListener('stop', () => isRecording && stopCapturing(type));
mediaRecorder.start(10);
if (type == 'screen') setTimeout(() => stopCapturing(type), 1000);
} catch (e) {
console.error('START ERROR: ', logError(e));
}
}
function stopCapturing(type: IMediaType = 'video') {
try {
if (!secure) return notSecureError();
if (mediaRecorder?.state === 'recording') {
mediaRecorder.stop();
stream!.getTracks().forEach((track) => track.stop());
}
mediaRecorder = null;
stream = null;
if (!!chunks.length && isRecording) {
recording = window.URL.createObjectURL(new Blob(chunks, { type: recordType.mimeType }));
if (type == 'video') {
const downloadLink = document.createElement('a');
downloadLink.setAttribute('type', recordType.mimeType);
downloadLink.setAttribute('href', recording);
downloadLink.setAttribute('download', options.fileName + '.webm');
downloadLink.click();
} else getPictureDownload(recording);
}
isRecording = false;
options.callbackRecording(isRecording);
} catch (e) {
console.error('STOP ERROR: ', logError(e));
}
}
function getPictureDownload(path: string) {
try {
const video = document.createElement('video');
video.addEventListener('loadedmetadata', (event) => {
const { videoHeight, videoWidth } = event.target as HTMLVideoElement,
canvas = document.createElement('canvas'),
ctx = canvas.getContext('2d');
ctx!.imageSmoothingEnabled = false;
canvas.setAttribute('width', String(videoWidth));
canvas.setAttribute('height', String(videoHeight));
video.addEventListener('ended', () => {
const link = document.createElement('a');
setTimeout(() => {
ctx!.drawImage(video, 0, 0, videoWidth, videoHeight);
link.setAttribute('download', options.fileName + '.png');
canvas.toBlob(function (blob) {
if (blob) {
link.setAttribute('href', URL.createObjectURL(blob));
link.click();
}
});
}, 200);
});
video.play();
});
video.src = path;
} catch (e) {
console.error('DOWNLOAD ERROR: ', logError(e));
}
}
return {
start: startCapturing,
stop: stopCapturing,
};
};
const logError = (e: unknown) => {
if (typeof e === 'string') {
return e.toUpperCase();
} else if (e instanceof Error) {
return e.message;
}
};
const notSecureError = () => console.error('SSL mevcut olmayan sayfada ekran kaydı yapılamaz');
type IMediaType = 'video' | 'screen';
type DeepPartial<T> = T extends object
? {
[P in keyof T]?: DeepPartial<T[P]>;
}
: T;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment