| |
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { |
| function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } |
| return new (P || (P = Promise))(function (resolve, reject) { |
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } |
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } |
| function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } |
| step((generator = generator.apply(thisArg, _arguments || [])).next()); |
| }); |
| }; |
| const BLOB_TYPE = "video/webm"; |
| class ScreenCastRecorder { |
| |
| static isSupportedBrowser() { |
| return (navigator.mediaDevices != null && |
| navigator.mediaDevices.getUserMedia != null && |
| navigator.mediaDevices.getDisplayMedia != null && |
| MediaRecorder.isTypeSupported(BLOB_TYPE)); |
| } |
| constructor({ recordAudio, onErrorOrStop }) { |
| this.recordAudio = recordAudio; |
| this.onErrorOrStopCallback = onErrorOrStop; |
| this.inputStream = null; |
| this.recordedChunks = []; |
| this.mediaRecorder = null; |
| } |
| |
| |
| |
| |
| initialize() { |
| return __awaiter(this, void 0, void 0, function* () { |
| const desktopStream = yield navigator.mediaDevices.getDisplayMedia({ |
| video: true, |
| }); |
| let tracks = desktopStream.getTracks(); |
| if (this.recordAudio) { |
| const voiceStream = yield navigator.mediaDevices.getUserMedia({ |
| video: false, |
| audio: true, |
| }); |
| tracks = tracks.concat(voiceStream.getAudioTracks()); |
| } |
| this.recordedChunks = []; |
| this.inputStream = new MediaStream(tracks); |
| this.mediaRecorder = new MediaRecorder(this.inputStream, { |
| mimeType: BLOB_TYPE, |
| }); |
| this.mediaRecorder.ondataavailable = e => this.recordedChunks.push(e.data); |
| }); |
| } |
| getState() { |
| if (this.mediaRecorder) { |
| return this.mediaRecorder.state; |
| } |
| return "inactive"; |
| } |
| |
| |
| |
| |
| |
| |
| start() { |
| if (!this.mediaRecorder) { |
| console.warn(`ScreenCastRecorder.start: mediaRecorder is null`); |
| return false; |
| } |
| const logRecorderError = (e) => { |
| console.warn(`mediaRecorder.start threw an error: ${e}`); |
| }; |
| this.mediaRecorder.onerror = (e) => { |
| logRecorderError(e); |
| this.onErrorOrStopCallback(); |
| }; |
| this.mediaRecorder.onstop = () => this.onErrorOrStopCallback(); |
| try { |
| this.mediaRecorder.start(); |
| } |
| catch (e) { |
| logRecorderError(e); |
| return false; |
| } |
| return true; |
| } |
| |
| |
| |
| |
| |
| |
| |
| stop() { |
| if (!this.mediaRecorder) { |
| return undefined; |
| } |
| let resolver; |
| const promise = new Promise(r => { |
| resolver = r; |
| }); |
| this.mediaRecorder.onstop = () => resolver(); |
| this.mediaRecorder.stop(); |
| if (this.inputStream) { |
| this.inputStream.getTracks().forEach(s => s.stop()); |
| this.inputStream = null; |
| } |
| return promise.then(() => this.buildOutputBlob()); |
| } |
| buildOutputBlob() { |
| return new Blob(this.recordedChunks, { type: BLOB_TYPE }); |
| } |
| } |