Created
April 28, 2022 20:15
-
-
Save hamzakaya/4fbad22f5cf2fbbd51a874b171a20dde to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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