-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvideo.js
134 lines (121 loc) · 4.35 KB
/
video.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//can be removed if imgDir is removed
const electron = require('electron');
const app = electron.remote.app;
const path = require('path');
const fs = require('fs');
const {desktopCapturer} = require('electron');
var utils = require('./utils');
let videoExports = {initRecording: initRecording, toggleRecording: toggleRecording};
module.exports = videoExports;
let timerControlVar;
let directory;
let fileNamePrefix;
function toggleRecording(options) {
//If timer is active or recording is active, clear and stop recording
if (timerControlVar != null) {
clearTimeout(timerControlVar);
timerControlVar = null;
stopRecording();
} else if ((mediaRecorder != null && mediaRecorder.state == 'recording')) {
stopRecording();
} else {
startRecording(options);
//After starting, automatically stop recording after options.timeout ms
if(options.timeout > 0) {
timerControlVar = setTimeout(() => {
stopRecording();
utils.debug('Timer ended');
}, options.timeout);
}
}
}
var videoMimeType = 'video/webm';
var blobs = [];
var mediaRecorder;
async function initRecording() {
var title = document.title;
utils.debug('Initiated recording stream for title: "' + title + '"');
var sources = await desktopCapturer.getSources({types: ['window', 'screen']});
sources.forEach(async (src) => {
if (src.name == title) {
navigator.webkitGetUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: src.id,
minWidth: 1280*12,
minHeight: 720*12
}
}
}, handleStream, (err) => {utils.log(err);});
}
});
}
let continuePingingBlobs = false;
async function startRecording(options) {
blobs = [];
mediaRecorder.start();
utils.log('Started recording');
continuePingingBlobs = true;
pingDom();
utils.debug('Started pinging dom');
directory = options.directory;
fileNamePrefix = options.fileNamePrefix;
}
/*
* A function to ensure that blobs[] is written to correctly.
* Without this, file size is very small and only few secs are recorded,
* since without this mediaRecorder.ondataavailable exhibits unexpected behavior
* Refer: https://github.com/CatalanCabbage/electron-vlog/issues/4
*/
let pingDomFrequency = 10;
var dummyElem = document.createElement('div');
dummyElem.style.cssText = 'opacity: 0.01; position: fixed; font-size: 1px; z-index: 10000';
document.body.appendChild(dummyElem); //Won't work if element is not rendered in the DOM
async function pingDom() {
if(continuePingingBlobs == true) {
dummyElem.innerHTML = '.';
setTimeout(pingDom, pingDomFrequency);
} else {
utils.debug('Stopped pinging dom');
}
}
async function stopRecording() {
continuePingingBlobs = false;
mediaRecorder.requestData();
mediaRecorder.stop();
utils.log('Stopped recording');
setTimeout(()=> {
utils.debug('Total size from dataavailable events is: ' + (totalSize / 1000) + 'kb');
totalSize = 0;
saveVideo();
}, 1000); //Timeout to wait for last blob to be captured. Can be improved
}
let totalSize = 0;
async function handleStream(stream) {
mediaRecorder = new MediaRecorder(stream, {
mimeType: videoMimeType,
});
mediaRecorder.ondataavailable = e => {
totalSize += e.data.size;
if (e.data && e.data.size > 0) {
utils.debug('dataavailable event triggered with blob size ' + e.data.size/1000 + 'kb');
blobs.push(e.data);
}
};
}
// noinspection DuplicatedCode
async function saveVideo() {
var blob = new Blob(blobs, {type: videoMimeType});
var buffer = Buffer.from(await blob.arrayBuffer());
if (!fs.existsSync(directory)) {
fs.mkdirSync(directory, {recursive: true});
}
let d = new Date();
let dateTime = d.getDate() + '-' + (d.getMonth() + 1) + '_' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds();
let vidName = fileNamePrefix + '_' + dateTime + '.webm';
var vidPath = path.join(directory, vidName);
fs.writeFileSync(vidPath, buffer);
utils.log('Video of size ' + buffer.length/1000 + 'kb saved as ' + vidPath);
}