videomail-client 7.0.0 → 8.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.browserslistrc +1 -1
- package/.eslintrc.js +4 -12
- package/.nvmrc +1 -1
- package/.prettierrc.js +13 -0
- package/TODO.md +4 -4
- package/audit-ci.json +5 -2
- package/babel.config.js +38 -0
- package/package.json +28 -42
- package/prototype/index.html +29 -9
- package/prototype/js/videomail-client.js +982 -9293
- package/prototype/js/videomail-client.min.js +15 -15
- package/prototype/js/videomail-client.min.js.map +1 -1
- package/prototype/user_media_on_record.html +32 -0
- package/src/js/events.js +2 -1
- package/src/js/options.js +4 -2
- package/src/js/wrappers/buttons.js +25 -14
- package/src/js/wrappers/visuals/notifier.js +11 -4
- package/src/js/wrappers/visuals/recorder.js +41 -11
- package/src/js/wrappers/visuals.js +9 -3
- package/src/styles/css/main.min.css.js +1 -1
- package/src/styles/styl/main.styl +3 -0
- package/.prettierrc +0 -18
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<title>videomail-client examples</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
6
|
+
</head>
|
|
7
|
+
<body>
|
|
8
|
+
<h1>Only when clicking on record button, ask for webcam access</h1>
|
|
9
|
+
<p>
|
|
10
|
+
With the option loadUserMediaOnRecord, the user won't be asked for webcam access on
|
|
11
|
+
page load but later, only when the record button is being pressed.
|
|
12
|
+
</p>
|
|
13
|
+
<div id="videomail"></div>
|
|
14
|
+
<script src="/js/videomail-client.js"></script>
|
|
15
|
+
<script>
|
|
16
|
+
var videomailClient = new VideomailClient({
|
|
17
|
+
verbose: true,
|
|
18
|
+
disableSubmit: true,
|
|
19
|
+
audio: {
|
|
20
|
+
enabled: true
|
|
21
|
+
},
|
|
22
|
+
video: {
|
|
23
|
+
width: 320,
|
|
24
|
+
countdown: false
|
|
25
|
+
},
|
|
26
|
+
loadUserMediaOnRecord: true
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
videomailClient.show()
|
|
30
|
+
</script>
|
|
31
|
+
</body>
|
|
32
|
+
</html>
|
package/src/js/events.js
CHANGED
|
@@ -41,5 +41,6 @@ export default keymirror({
|
|
|
41
41
|
ASKING_WEBCAM_PERMISSION: null, // when about to ask for webcam permissions
|
|
42
42
|
VISIBLE: null, // document just became visible
|
|
43
43
|
INVISIBLE: null, // document just became INvisible
|
|
44
|
-
SWITCH_FACING_MODE: null // to switch camera on mobiles between fron and back
|
|
44
|
+
SWITCH_FACING_MODE: null, // to switch camera on mobiles between fron and back
|
|
45
|
+
SERVER_READY: null // Gets emitted when the ready command is sent through sockets from the server for recording
|
|
45
46
|
})
|
package/src/js/options.js
CHANGED
|
@@ -91,7 +91,7 @@ export default {
|
|
|
91
91
|
},
|
|
92
92
|
|
|
93
93
|
image: {
|
|
94
|
-
quality: 0.
|
|
94
|
+
quality: 0.42,
|
|
95
95
|
types: ['webp', 'jpeg'] // recommended settings to make most of all browsers
|
|
96
96
|
},
|
|
97
97
|
|
|
@@ -123,9 +123,11 @@ export default {
|
|
|
123
123
|
timeouts: {
|
|
124
124
|
userMedia: 20e3, // in milliseconds, increase if you want user give more time to enable webcam
|
|
125
125
|
connection: 1e4, // in seconds, increase if api is slow
|
|
126
|
-
pingInterval: 35e3 // in milliseconds, keeps
|
|
126
|
+
pingInterval: 35e3 // in milliseconds, keeps web stream (connection) alive when pausing
|
|
127
127
|
},
|
|
128
128
|
|
|
129
|
+
loadUserMediaOnRecord: false, // when true, user media is loaded only when record button is pressed
|
|
130
|
+
|
|
129
131
|
callbacks: {
|
|
130
132
|
// a custom callback to tweak form data before posting to server
|
|
131
133
|
// this is for advanced use only and shouldn't be used if possible
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import util from 'util'
|
|
2
|
-
import h from 'hyperscript'
|
|
3
|
-
import hidden from 'hidden'
|
|
4
1
|
import contains from 'contains'
|
|
2
|
+
import hidden from 'hidden'
|
|
3
|
+
import h from 'hyperscript'
|
|
4
|
+
import util from 'util'
|
|
5
5
|
|
|
6
|
-
import Events from '
|
|
7
|
-
import EventEmitter from '
|
|
6
|
+
import Events from '../events'
|
|
7
|
+
import EventEmitter from '../util/eventEmitter'
|
|
8
8
|
|
|
9
9
|
const Buttons = function (container, options) {
|
|
10
10
|
EventEmitter.call(this, options, 'Buttons')
|
|
@@ -326,6 +326,16 @@ const Buttons = function (container, options) {
|
|
|
326
326
|
if (!options.enableAutoValidation) {
|
|
327
327
|
enable(submitButton)
|
|
328
328
|
}
|
|
329
|
+
|
|
330
|
+
if (!params.recordWhenReady) {
|
|
331
|
+
if (isShown(audioOnRadioPair)) {
|
|
332
|
+
enable(audioOnRadioPair)
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (isShown(audioOffRadioPair)) {
|
|
336
|
+
enable(audioOffRadioPair)
|
|
337
|
+
}
|
|
338
|
+
}
|
|
329
339
|
}
|
|
330
340
|
|
|
331
341
|
function onGoingBack() {
|
|
@@ -341,18 +351,10 @@ const Buttons = function (container, options) {
|
|
|
341
351
|
function onUserMediaReady(params) {
|
|
342
352
|
onFormReady(params)
|
|
343
353
|
|
|
344
|
-
if (isShown(recordButton)) {
|
|
354
|
+
if (isShown(recordButton) && !params.recordWhenReady) {
|
|
345
355
|
enable(recordButton)
|
|
346
356
|
}
|
|
347
357
|
|
|
348
|
-
if (isShown(audioOnRadioPair)) {
|
|
349
|
-
enable(audioOnRadioPair)
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (isShown(audioOffRadioPair)) {
|
|
353
|
-
enable(audioOffRadioPair)
|
|
354
|
-
}
|
|
355
|
-
|
|
356
358
|
if (options.enableAutoValidation) {
|
|
357
359
|
disable(submitButton)
|
|
358
360
|
}
|
|
@@ -431,6 +433,8 @@ const Buttons = function (container, options) {
|
|
|
431
433
|
|
|
432
434
|
function onStopping() {
|
|
433
435
|
disable(previewButton)
|
|
436
|
+
disable(recordButton)
|
|
437
|
+
|
|
434
438
|
hide(pauseButton)
|
|
435
439
|
hide(resumeButton)
|
|
436
440
|
}
|
|
@@ -569,6 +573,13 @@ const Buttons = function (container, options) {
|
|
|
569
573
|
.on(Events.STARTING_OVER, function () {
|
|
570
574
|
onStartingOver()
|
|
571
575
|
})
|
|
576
|
+
.on(Events.CONNECTED, function () {
|
|
577
|
+
if (options.loadUserMediaOnRecord) {
|
|
578
|
+
if (isShown(recordButton)) {
|
|
579
|
+
enable(recordButton)
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
})
|
|
572
583
|
.on(Events.ERROR, function (err) {
|
|
573
584
|
// since https://github.com/binarykitchen/videomail-client/issues/60
|
|
574
585
|
// we hide areas to make it easier for the user
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import util from 'util'
|
|
2
|
-
import h from 'hyperscript'
|
|
3
1
|
import hidden from 'hidden'
|
|
2
|
+
import h from 'hyperscript'
|
|
3
|
+
import util from 'util'
|
|
4
4
|
|
|
5
|
-
import
|
|
6
|
-
import
|
|
5
|
+
import Events from '../../events'
|
|
6
|
+
import EventEmitter from '../../util/eventEmitter'
|
|
7
7
|
|
|
8
8
|
const Notifier = function (visuals, options) {
|
|
9
9
|
EventEmitter.call(this, options, 'Notifier')
|
|
@@ -101,6 +101,13 @@ const Notifier = function (visuals, options) {
|
|
|
101
101
|
.on(Events.BEGIN_VIDEO_ENCODING, function () {
|
|
102
102
|
onBeginVideoEncoding()
|
|
103
103
|
})
|
|
104
|
+
.on(Events.CONNECTED, function () {
|
|
105
|
+
self.notify('Connected.')
|
|
106
|
+
|
|
107
|
+
if (options.loadUserMediaOnRecord) {
|
|
108
|
+
self.hide()
|
|
109
|
+
}
|
|
110
|
+
})
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
function correctDimensions() {
|
|
@@ -166,9 +166,15 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
show()
|
|
169
|
+
|
|
170
|
+
if (params.recordWhenReady) {
|
|
171
|
+
self.record()
|
|
172
|
+
}
|
|
173
|
+
|
|
169
174
|
self.emit(Events.USER_MEDIA_READY, {
|
|
170
175
|
switchingFacingMode: params.switchingFacingMode,
|
|
171
|
-
paused: self.isPaused()
|
|
176
|
+
paused: self.isPaused(),
|
|
177
|
+
recordWhenReady: params.recordWhenReady
|
|
172
178
|
})
|
|
173
179
|
} catch (exc) {
|
|
174
180
|
self.emit(Events.ERROR, exc)
|
|
@@ -370,8 +376,6 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
370
376
|
|
|
371
377
|
self.emit(Events.CONNECTED)
|
|
372
378
|
|
|
373
|
-
debug('Going to ask for webcam permissons now ...')
|
|
374
|
-
|
|
375
379
|
cb && cb()
|
|
376
380
|
}
|
|
377
381
|
})
|
|
@@ -645,10 +649,10 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
645
649
|
}
|
|
646
650
|
}
|
|
647
651
|
|
|
648
|
-
function loadUserMedia() {
|
|
652
|
+
function loadUserMedia(params = {}) {
|
|
649
653
|
if (userMediaLoaded) {
|
|
650
654
|
debug('Recorder: skipping loadUserMedia() because it is already loaded')
|
|
651
|
-
onUserMediaReady()
|
|
655
|
+
onUserMediaReady(params)
|
|
652
656
|
return false
|
|
653
657
|
} else if (userMediaLoading) {
|
|
654
658
|
debug(
|
|
@@ -657,7 +661,7 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
657
661
|
return false
|
|
658
662
|
}
|
|
659
663
|
|
|
660
|
-
debug('Recorder: loadUserMedia()')
|
|
664
|
+
debug('Recorder: loadUserMedia()', params)
|
|
661
665
|
|
|
662
666
|
self.emit(Events.LOADING_USER_MEDIA)
|
|
663
667
|
|
|
@@ -670,7 +674,7 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
670
674
|
|
|
671
675
|
userMediaLoading = true
|
|
672
676
|
|
|
673
|
-
loadGenuineUserMedia()
|
|
677
|
+
loadGenuineUserMedia(params)
|
|
674
678
|
} catch (exc) {
|
|
675
679
|
debug('Recorder: failed to load genuine user media')
|
|
676
680
|
|
|
@@ -697,8 +701,15 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
697
701
|
|
|
698
702
|
switch (command.command) {
|
|
699
703
|
case 'ready':
|
|
704
|
+
this.emit(Events.SERVER_READY)
|
|
705
|
+
|
|
700
706
|
if (!userMediaTimeout) {
|
|
701
|
-
|
|
707
|
+
if (options.loadUserMediaOnRecord) {
|
|
708
|
+
// Still show it but have it blank
|
|
709
|
+
show()
|
|
710
|
+
} else {
|
|
711
|
+
loadUserMedia()
|
|
712
|
+
}
|
|
702
713
|
}
|
|
703
714
|
break
|
|
704
715
|
case 'preview':
|
|
@@ -933,7 +944,13 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
933
944
|
|
|
934
945
|
replay.reset()
|
|
935
946
|
|
|
936
|
-
userMediaLoaded =
|
|
947
|
+
userMediaLoaded =
|
|
948
|
+
key =
|
|
949
|
+
canvas =
|
|
950
|
+
ctx =
|
|
951
|
+
recordingBuffer =
|
|
952
|
+
recordingBufferLength =
|
|
953
|
+
null
|
|
937
954
|
}
|
|
938
955
|
}
|
|
939
956
|
|
|
@@ -1054,6 +1071,19 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
1054
1071
|
return false
|
|
1055
1072
|
}
|
|
1056
1073
|
|
|
1074
|
+
if (!userMediaLoaded) {
|
|
1075
|
+
if (options.loadUserMediaOnRecord) {
|
|
1076
|
+
loadUserMedia({ recordWhenReady: true })
|
|
1077
|
+
} else {
|
|
1078
|
+
self.emit(
|
|
1079
|
+
Events.ERROR,
|
|
1080
|
+
VideomailError.create('Load and enable your camera first', options)
|
|
1081
|
+
)
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
return false // do nothing further
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1057
1087
|
try {
|
|
1058
1088
|
canvas = userMedia.createCanvas()
|
|
1059
1089
|
} catch (exc) {
|
|
@@ -1267,10 +1297,10 @@ const Recorder = function (visuals, replay, defaultOptions = {}) {
|
|
|
1267
1297
|
|
|
1268
1298
|
if (!connected) {
|
|
1269
1299
|
initSocket()
|
|
1270
|
-
} else {
|
|
1300
|
+
} else if (!options.loadUserMediaOnRecord) {
|
|
1271
1301
|
loadUserMedia()
|
|
1272
1302
|
}
|
|
1273
|
-
} else {
|
|
1303
|
+
} else if (options.loadUserMediaOnRecord) {
|
|
1274
1304
|
loadUserMedia()
|
|
1275
1305
|
}
|
|
1276
1306
|
|
|
@@ -198,9 +198,15 @@ const Visuals = function (container, options) {
|
|
|
198
198
|
|
|
199
199
|
this.recordAgain = function () {
|
|
200
200
|
this.back(function () {
|
|
201
|
-
|
|
202
|
-
self.
|
|
203
|
-
|
|
201
|
+
if (options.loadUserMediaOnRecord) {
|
|
202
|
+
self.once(Events.SERVER_READY, function () {
|
|
203
|
+
self.record()
|
|
204
|
+
})
|
|
205
|
+
} else {
|
|
206
|
+
self.once(Events.USER_MEDIA_READY, function () {
|
|
207
|
+
self.record()
|
|
208
|
+
})
|
|
209
|
+
}
|
|
204
210
|
})
|
|
205
211
|
}
|
|
206
212
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
module.exports='@-webkit-keyframes blink{0%{opacity:.9}35%{opacity:.9}50%{opacity:.1}85%{opacity:.1}to{opacity:.9}}@keyframes blink{0%{opacity:.9}35%{opacity:.9}50%{opacity:.1}85%{opacity:.1}to{opacity:.9}}.IIV::-webkit-media-controls-play-button,.IIV::-webkit-media-controls-start-playback-button{opacity:0;pointer-events:none;width:5px}.videomail .visuals{position:relative}.videomail .visuals video.replay{height:100%;width:100%}.videomail .countdown,.videomail .pausedHeader,.videomail .pausedHint,.videomail .recordNote,.videomail .recordTimer{height:auto;margin:0}.videomail .countdown,.videomail .facingMode,.videomail .paused,.videomail .recordNote,.videomail .recordTimer,.videomail noscript{position:absolute;z-index:100}.videomail .countdown,.videomail .pausedHeader,.videomail .pausedHint,.videomail .recordNote,.videomail .recordTimer,.videomail noscript{font-weight:700}.videomail .countdown,.videomail .paused,.videomail noscript{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:100%}.videomail .countdown,.videomail .pausedHeader,.videomail .pausedHint{letter-spacing:4px;text-align:center;text-shadow:-2px 0 #fff,0 2px #fff,2px 0 #fff,0 -2px #fff}.videomail .countdown,.videomail .pausedHeader{font-size:460%;opacity:.9}.videomail .pausedHint{font-size:150%}.videomail .facingMode{background:rgba(30,30,30,.5);border:none;bottom:.6em;color:hsla(0,0%,96%,.9);font-family:monospace;font-size:1.2em;outline:none;padding:.1em .3em;right:.7em;-webkit-transition:all .2s ease;transition:all .2s ease;z-index:10}.videomail .facingMode:hover{background:rgba(50,50,50,.7);cursor:pointer}.videomail .recordNote,.videomail .recordTimer{background:hsla(0,0%,4%,.8);color:#00d814;font-family:monospace;opacity:.9;padding:.3em .4em;right:.7em;-webkit-transition:all 1s ease;transition:all 1s ease}.videomail .recordNote.near,.videomail .recordTimer.near{color:#eb9369}.videomail .recordNote.nigh,.videomail .recordTimer.nigh{color:#ea4b2a}.videomail .recordTimer{top:.7em}.videomail .recordNote{top:3.6em}.videomail .recordNote:before{-webkit-animation:blink 1s infinite;animation:blink 1s infinite;content:"REC"}.videomail .notifier{-webkit-box-sizing:border-box;box-sizing:border-box;height:100%;overflow:hidden}.videomail .radioGroup{display:block}.videomail video{margin-bottom:0}'
|
|
1
|
+
module.exports='@-webkit-keyframes blink{0%{opacity:.9}35%{opacity:.9}50%{opacity:.1}85%{opacity:.1}to{opacity:.9}}@keyframes blink{0%{opacity:.9}35%{opacity:.9}50%{opacity:.1}85%{opacity:.1}to{opacity:.9}}.IIV::-webkit-media-controls-play-button,.IIV::-webkit-media-controls-start-playback-button{opacity:0;pointer-events:none;width:5px}.videomail .visuals{position:relative}.videomail .visuals video.replay{height:100%;width:100%}.videomail .countdown,.videomail .pausedHeader,.videomail .pausedHint,.videomail .recordNote,.videomail .recordTimer{height:auto;margin:0}.videomail .countdown,.videomail .facingMode,.videomail .paused,.videomail .recordNote,.videomail .recordTimer,.videomail noscript{position:absolute;z-index:100}.videomail .countdown,.videomail .pausedHeader,.videomail .pausedHint,.videomail .recordNote,.videomail .recordTimer,.videomail noscript{font-weight:700}.videomail .countdown,.videomail .paused,.videomail noscript{top:50%;-webkit-transform:translateY(-50%);-ms-transform:translateY(-50%);transform:translateY(-50%);width:100%}.videomail .countdown,.videomail .pausedHeader,.videomail .pausedHint{letter-spacing:4px;text-align:center;text-shadow:-2px 0 #fff,0 2px #fff,2px 0 #fff,0 -2px #fff}.videomail .countdown,.videomail .pausedHeader{font-size:460%;opacity:.9}.videomail .pausedHint{font-size:150%}.videomail .facingMode{background:rgba(30,30,30,.5);border:none;bottom:.6em;color:hsla(0,0%,96%,.9);font-family:monospace;font-size:1.2em;outline:none;padding:.1em .3em;right:.7em;-webkit-transition:all .2s ease;transition:all .2s ease;z-index:10}.videomail .facingMode:hover{background:rgba(50,50,50,.7);cursor:pointer}.videomail .recordNote,.videomail .recordTimer{background:hsla(0,0%,4%,.8);color:#00d814;font-family:monospace;opacity:.9;padding:.3em .4em;right:.7em;-webkit-transition:all 1s ease;transition:all 1s ease}.videomail .recordNote.near,.videomail .recordTimer.near{color:#eb9369}.videomail .recordNote.nigh,.videomail .recordTimer.nigh{color:#ea4b2a}.videomail .recordTimer{top:.7em}.videomail .recordNote{top:3.6em}.videomail .recordNote:before{-webkit-animation:blink 1s infinite;animation:blink 1s infinite;content:"REC"}.videomail .notifier{-webkit-box-sizing:border-box;box-sizing:border-box;height:100%;overflow:hidden}.videomail .radioGroup{display:block}.videomail video{margin-bottom:0}.videomail video.userMedia{background-color:rgba(50,50,50,.1)}'
|
package/.prettierrc
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"arrowParens": "always",
|
|
3
|
-
"bracketSpacing": true,
|
|
4
|
-
"endOfLine": "lf",
|
|
5
|
-
"htmlWhitespaceSensitivity": "css",
|
|
6
|
-
"insertPragma": false,
|
|
7
|
-
"jsxSingleQuote": true,
|
|
8
|
-
"printWidth": 90,
|
|
9
|
-
"proseWrap": "preserve",
|
|
10
|
-
"quoteProps": "as-needed",
|
|
11
|
-
"requirePragma": false,
|
|
12
|
-
"semi": false,
|
|
13
|
-
"singleQuote": true,
|
|
14
|
-
"tabWidth": 2,
|
|
15
|
-
"trailingComma": "none",
|
|
16
|
-
"useTabs": false,
|
|
17
|
-
"vueIndentScriptAndStyle": true
|
|
18
|
-
}
|