@lookit/record 3.0.1 → 4.0.0
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/dist/index.browser.js +68 -31
- package/dist/index.browser.js.map +1 -1
- package/dist/index.browser.min.js +12 -12
- package/dist/index.browser.min.js.map +1 -1
- package/dist/index.cjs +67 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +25 -3
- package/dist/index.js +67 -30
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/consentVideo.spec.ts +38 -11
- package/src/consentVideo.ts +75 -18
- package/src/errors.ts +7 -27
- package/src/recorder.spec.ts +120 -0
- package/src/recorder.ts +28 -4
package/dist/index.d.ts
CHANGED
|
@@ -272,6 +272,11 @@ declare class VideoConsentPlugin implements JsPsychPlugin<Info$3> {
|
|
|
272
272
|
};
|
|
273
273
|
private readonly recorder;
|
|
274
274
|
private readonly video_container_id;
|
|
275
|
+
private readonly msg_container_id;
|
|
276
|
+
private uploadingMsg;
|
|
277
|
+
private startingMsg;
|
|
278
|
+
private recordingMsg;
|
|
279
|
+
private notRecordingMsg;
|
|
275
280
|
/**
|
|
276
281
|
* Instantiate video consent plugin.
|
|
277
282
|
*
|
|
@@ -305,13 +310,30 @@ declare class VideoConsentPlugin implements JsPsychPlugin<Info$3> {
|
|
|
305
310
|
*/
|
|
306
311
|
private playbackFeed;
|
|
307
312
|
/**
|
|
308
|
-
*
|
|
309
|
-
*
|
|
313
|
+
* Get message container that appears alongside the video element.
|
|
314
|
+
*
|
|
315
|
+
* @param display - HTML element for experiment.
|
|
316
|
+
* @returns Message container div element.
|
|
317
|
+
*/
|
|
318
|
+
private getMessageContainer;
|
|
319
|
+
/**
|
|
320
|
+
* Add HTML-formatted message alongside the video feed, e.g. for waiting
|
|
321
|
+
* periods during webcam feed transitions (starting, stopping/uploading). This
|
|
322
|
+
* will also replace an existing message with the new one. To clear any
|
|
323
|
+
* existing messages, pass an empty string.
|
|
324
|
+
*
|
|
325
|
+
* @param display - HTML element for experiment.
|
|
326
|
+
* @param message - HTML content for message div.
|
|
327
|
+
*/
|
|
328
|
+
private addMessage;
|
|
329
|
+
/**
|
|
330
|
+
* Put back the webcam feed once the video recording playback has ended. This
|
|
331
|
+
* is used with the "ended" Event.
|
|
310
332
|
*
|
|
311
333
|
* @param display - JsPsych display HTML element.
|
|
312
334
|
* @returns Event function
|
|
313
335
|
*/
|
|
314
|
-
private
|
|
336
|
+
private onPlaybackEnded;
|
|
315
337
|
/**
|
|
316
338
|
* Retrieve button element from DOM.
|
|
317
339
|
*
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import Handlebars from 'handlebars';
|
|
|
6
6
|
|
|
7
7
|
var _package = {
|
|
8
8
|
name: "@lookit/record",
|
|
9
|
-
version: "
|
|
9
|
+
version: "4.0.0",
|
|
10
10
|
description: "Recording extensions and plugins for CHS studies.",
|
|
11
11
|
homepage: "https://github.com/lookit/lookit-jspsych#readme",
|
|
12
12
|
bugs: {
|
|
@@ -48,7 +48,7 @@ var _package = {
|
|
|
48
48
|
},
|
|
49
49
|
peerDependencies: {
|
|
50
50
|
"@lookit/data": "^0.2.0",
|
|
51
|
-
"@lookit/templates": "^2.
|
|
51
|
+
"@lookit/templates": "^2.1.0",
|
|
52
52
|
jspsych: "^8.0.3"
|
|
53
53
|
}
|
|
54
54
|
};
|
|
@@ -141,21 +141,10 @@ class CreateURLError extends Error {
|
|
|
141
141
|
this.name = "CreateURLError";
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
|
-
class
|
|
145
|
-
constructor() {
|
|
146
|
-
super("
|
|
147
|
-
this.name = "
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
class ButtonNotFoundError extends Error {
|
|
151
|
-
constructor(id) {
|
|
152
|
-
super(`"${id}" button not found.`);
|
|
153
|
-
this.name = "ButtonNotFoundError";
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
class ImageNotFoundError extends Error {
|
|
157
|
-
constructor(id) {
|
|
158
|
-
super(`"${id}" image not found.`);
|
|
144
|
+
class ElementNotFoundError extends Error {
|
|
145
|
+
constructor(id, tag) {
|
|
146
|
+
super(`"${id}" ${tag} not found.`);
|
|
147
|
+
this.name = "ElementNotFoundError";
|
|
159
148
|
}
|
|
160
149
|
}
|
|
161
150
|
|
|
@@ -268,9 +257,9 @@ class Recorder {
|
|
|
268
257
|
this.recorder.stop();
|
|
269
258
|
this.stream.getTracks().map((t) => t.stop());
|
|
270
259
|
}
|
|
271
|
-
stop() {
|
|
260
|
+
stop(maintain_container_size = false) {
|
|
261
|
+
this.clearWebcamFeed(maintain_container_size);
|
|
272
262
|
this.stopTracks();
|
|
273
|
-
this.clearWebcamFeed();
|
|
274
263
|
if (!this.stopPromise) {
|
|
275
264
|
throw new NoStopPromiseError();
|
|
276
265
|
}
|
|
@@ -315,11 +304,20 @@ class Recorder {
|
|
|
315
304
|
link.click();
|
|
316
305
|
}
|
|
317
306
|
}
|
|
318
|
-
clearWebcamFeed() {
|
|
307
|
+
clearWebcamFeed(maintain_container_size) {
|
|
319
308
|
const webcam_feed_element = document.querySelector(
|
|
320
309
|
`#${this.webcam_element_id}`
|
|
321
310
|
);
|
|
322
311
|
if (webcam_feed_element) {
|
|
312
|
+
if (maintain_container_size) {
|
|
313
|
+
const parent_div = webcam_feed_element.parentElement;
|
|
314
|
+
if (parent_div) {
|
|
315
|
+
const width = webcam_feed_element.offsetWidth;
|
|
316
|
+
const height = webcam_feed_element.offsetHeight;
|
|
317
|
+
parent_div.style.height = `${height}px`;
|
|
318
|
+
parent_div.style.width = `${width}px`;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
323
321
|
webcam_feed_element.remove();
|
|
324
322
|
}
|
|
325
323
|
}
|
|
@@ -389,6 +387,11 @@ const _VideoConsentPlugin = class {
|
|
|
389
387
|
constructor(jsPsych) {
|
|
390
388
|
this.jsPsych = jsPsych;
|
|
391
389
|
this.video_container_id = "lookit-jspsych-video-container";
|
|
390
|
+
this.msg_container_id = "lookit-jspsych-video-msg-container";
|
|
391
|
+
this.uploadingMsg = null;
|
|
392
|
+
this.startingMsg = null;
|
|
393
|
+
this.recordingMsg = null;
|
|
394
|
+
this.notRecordingMsg = null;
|
|
392
395
|
this.jsPsych = jsPsych;
|
|
393
396
|
this.recorder = new Recorder(this.jsPsych);
|
|
394
397
|
}
|
|
@@ -400,13 +403,25 @@ const _VideoConsentPlugin = class {
|
|
|
400
403
|
this.stopButton(display);
|
|
401
404
|
this.playButton(display);
|
|
402
405
|
this.nextButton(display);
|
|
406
|
+
this.uploadingMsg = chsTemplates.translateString(
|
|
407
|
+
"exp-lookit-video-consent.Stopping-and-uploading"
|
|
408
|
+
);
|
|
409
|
+
this.startingMsg = chsTemplates.translateString(
|
|
410
|
+
"exp-lookit-video-consent.Starting-recorder"
|
|
411
|
+
);
|
|
412
|
+
this.recordingMsg = chsTemplates.translateString(
|
|
413
|
+
"exp-lookit-video-consent.Recording"
|
|
414
|
+
);
|
|
415
|
+
this.notRecordingMsg = chsTemplates.translateString(
|
|
416
|
+
"exp-lookit-video-consent.Not-recording"
|
|
417
|
+
);
|
|
403
418
|
}
|
|
404
419
|
getVideoContainer(display) {
|
|
405
420
|
const videoContainer = display.querySelector(
|
|
406
421
|
`div#${this.video_container_id}`
|
|
407
422
|
);
|
|
408
423
|
if (!videoContainer) {
|
|
409
|
-
throw new
|
|
424
|
+
throw new ElementNotFoundError(this.video_container_id, "div");
|
|
410
425
|
}
|
|
411
426
|
return videoContainer;
|
|
412
427
|
}
|
|
@@ -417,14 +432,31 @@ const _VideoConsentPlugin = class {
|
|
|
417
432
|
}
|
|
418
433
|
playbackFeed(display) {
|
|
419
434
|
const videoContainer = this.getVideoContainer(display);
|
|
420
|
-
this.recorder.insertPlaybackFeed(
|
|
435
|
+
this.recorder.insertPlaybackFeed(
|
|
436
|
+
videoContainer,
|
|
437
|
+
this.onPlaybackEnded(display)
|
|
438
|
+
);
|
|
421
439
|
}
|
|
422
|
-
|
|
440
|
+
getMessageContainer(display) {
|
|
441
|
+
const msgContainer = display.querySelector(
|
|
442
|
+
`div#${this.msg_container_id}`
|
|
443
|
+
);
|
|
444
|
+
if (!msgContainer) {
|
|
445
|
+
throw new ElementNotFoundError(this.msg_container_id, "div");
|
|
446
|
+
}
|
|
447
|
+
return msgContainer;
|
|
448
|
+
}
|
|
449
|
+
addMessage(display, message) {
|
|
450
|
+
const msgContainer = this.getMessageContainer(display);
|
|
451
|
+
msgContainer.innerHTML = message;
|
|
452
|
+
}
|
|
453
|
+
onPlaybackEnded(display) {
|
|
423
454
|
return () => {
|
|
424
455
|
const next = this.getButton(display, "next");
|
|
425
456
|
const play = this.getButton(display, "play");
|
|
426
457
|
const record = this.getButton(display, "record");
|
|
427
458
|
this.recordFeed(display);
|
|
459
|
+
this.addMessage(display, this.notRecordingMsg);
|
|
428
460
|
next.disabled = false;
|
|
429
461
|
play.disabled = false;
|
|
430
462
|
record.disabled = false;
|
|
@@ -433,14 +465,14 @@ const _VideoConsentPlugin = class {
|
|
|
433
465
|
getButton(display, id) {
|
|
434
466
|
const btn = display.querySelector(`button#${id}`);
|
|
435
467
|
if (!btn) {
|
|
436
|
-
throw new
|
|
468
|
+
throw new ElementNotFoundError(id, "button");
|
|
437
469
|
}
|
|
438
470
|
return btn;
|
|
439
471
|
}
|
|
440
472
|
getImg(display, id) {
|
|
441
473
|
const img = display.querySelector(`img#${id}`);
|
|
442
474
|
if (!img) {
|
|
443
|
-
throw new
|
|
475
|
+
throw new ElementNotFoundError(id, "img");
|
|
444
476
|
}
|
|
445
477
|
return img;
|
|
446
478
|
}
|
|
@@ -450,12 +482,14 @@ const _VideoConsentPlugin = class {
|
|
|
450
482
|
const play = this.getButton(display, "play");
|
|
451
483
|
const next = this.getButton(display, "next");
|
|
452
484
|
record.addEventListener("click", async () => {
|
|
485
|
+
this.addMessage(display, this.startingMsg);
|
|
453
486
|
record.disabled = true;
|
|
454
|
-
stop.disabled = false;
|
|
455
487
|
play.disabled = true;
|
|
456
488
|
next.disabled = true;
|
|
457
|
-
this.getImg(display, "record-icon").style.visibility = "visible";
|
|
458
489
|
await this.recorder.start(true, _VideoConsentPlugin.info.name);
|
|
490
|
+
this.getImg(display, "record-icon").style.visibility = "visible";
|
|
491
|
+
this.addMessage(display, this.recordingMsg);
|
|
492
|
+
stop.disabled = false;
|
|
459
493
|
});
|
|
460
494
|
}
|
|
461
495
|
playButton(display) {
|
|
@@ -473,11 +507,14 @@ const _VideoConsentPlugin = class {
|
|
|
473
507
|
const play = this.getButton(display, "play");
|
|
474
508
|
stop.addEventListener("click", async () => {
|
|
475
509
|
stop.disabled = true;
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
await this.recorder.stop();
|
|
510
|
+
this.addMessage(display, this.uploadingMsg);
|
|
511
|
+
await this.recorder.stop(true);
|
|
479
512
|
this.recorder.reset();
|
|
480
513
|
this.recordFeed(display);
|
|
514
|
+
this.getImg(display, "record-icon").style.visibility = "hidden";
|
|
515
|
+
this.addMessage(display, this.notRecordingMsg);
|
|
516
|
+
play.disabled = false;
|
|
517
|
+
record.disabled = false;
|
|
481
518
|
});
|
|
482
519
|
}
|
|
483
520
|
nextButton(display) {
|