easyproctor 0.0.67 → 0.0.68

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/index.js CHANGED
@@ -23,6 +23,3634 @@ var __copyProps = (to, from, except, desc) => {
23
23
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
24
24
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
25
 
26
+ // node_modules/recordrtc/RecordRTC.js
27
+ var require_RecordRTC = __commonJS({
28
+ "node_modules/recordrtc/RecordRTC.js"(exports, module2) {
29
+ "use strict";
30
+ function RecordRTC(mediaStream, config2) {
31
+ if (!mediaStream) {
32
+ throw "First parameter is required.";
33
+ }
34
+ config2 = config2 || {
35
+ type: "video"
36
+ };
37
+ config2 = new RecordRTCConfiguration(mediaStream, config2);
38
+ var self2 = this;
39
+ function startRecording(config22) {
40
+ if (!config2.disableLogs) {
41
+ console.log("RecordRTC version: ", self2.version);
42
+ }
43
+ if (!!config22) {
44
+ config2 = new RecordRTCConfiguration(mediaStream, config22);
45
+ }
46
+ if (!config2.disableLogs) {
47
+ console.log("started recording " + config2.type + " stream.");
48
+ }
49
+ if (mediaRecorder) {
50
+ mediaRecorder.clearRecordedData();
51
+ mediaRecorder.record();
52
+ setState("recording");
53
+ if (self2.recordingDuration) {
54
+ handleRecordingDuration();
55
+ }
56
+ return self2;
57
+ }
58
+ initRecorder(function() {
59
+ if (self2.recordingDuration) {
60
+ handleRecordingDuration();
61
+ }
62
+ });
63
+ return self2;
64
+ }
65
+ function initRecorder(initCallback) {
66
+ if (initCallback) {
67
+ config2.initCallback = function() {
68
+ initCallback();
69
+ initCallback = config2.initCallback = null;
70
+ };
71
+ }
72
+ var Recorder = new GetRecorderType(mediaStream, config2);
73
+ mediaRecorder = new Recorder(mediaStream, config2);
74
+ mediaRecorder.record();
75
+ setState("recording");
76
+ if (!config2.disableLogs) {
77
+ console.log("Initialized recorderType:", mediaRecorder.constructor.name, "for output-type:", config2.type);
78
+ }
79
+ }
80
+ function stopRecording(callback) {
81
+ callback = callback || function() {
82
+ };
83
+ if (!mediaRecorder) {
84
+ warningLog();
85
+ return;
86
+ }
87
+ if (self2.state === "paused") {
88
+ self2.resumeRecording();
89
+ setTimeout(function() {
90
+ stopRecording(callback);
91
+ }, 1);
92
+ return;
93
+ }
94
+ if (self2.state !== "recording" && !config2.disableLogs) {
95
+ console.warn('Recording state should be: "recording", however current state is: ', self2.state);
96
+ }
97
+ if (!config2.disableLogs) {
98
+ console.log("Stopped recording " + config2.type + " stream.");
99
+ }
100
+ if (config2.type !== "gif") {
101
+ mediaRecorder.stop(_callback);
102
+ } else {
103
+ mediaRecorder.stop();
104
+ _callback();
105
+ }
106
+ setState("stopped");
107
+ function _callback(__blob) {
108
+ if (!mediaRecorder) {
109
+ if (typeof callback.call === "function") {
110
+ callback.call(self2, "");
111
+ } else {
112
+ callback("");
113
+ }
114
+ return;
115
+ }
116
+ Object.keys(mediaRecorder).forEach(function(key) {
117
+ if (typeof mediaRecorder[key] === "function") {
118
+ return;
119
+ }
120
+ self2[key] = mediaRecorder[key];
121
+ });
122
+ var blob = mediaRecorder.blob;
123
+ if (!blob) {
124
+ if (__blob) {
125
+ mediaRecorder.blob = blob = __blob;
126
+ } else {
127
+ throw "Recording failed.";
128
+ }
129
+ }
130
+ if (blob && !config2.disableLogs) {
131
+ console.log(blob.type, "->", bytesToSize(blob.size));
132
+ }
133
+ if (callback) {
134
+ var url;
135
+ try {
136
+ url = URL2.createObjectURL(blob);
137
+ } catch (e) {
138
+ }
139
+ if (typeof callback.call === "function") {
140
+ callback.call(self2, url);
141
+ } else {
142
+ callback(url);
143
+ }
144
+ }
145
+ if (!config2.autoWriteToDisk) {
146
+ return;
147
+ }
148
+ getDataURL(function(dataURL) {
149
+ var parameter = {};
150
+ parameter[config2.type + "Blob"] = dataURL;
151
+ DiskStorage.Store(parameter);
152
+ });
153
+ }
154
+ }
155
+ function pauseRecording() {
156
+ if (!mediaRecorder) {
157
+ warningLog();
158
+ return;
159
+ }
160
+ if (self2.state !== "recording") {
161
+ if (!config2.disableLogs) {
162
+ console.warn("Unable to pause the recording. Recording state: ", self2.state);
163
+ }
164
+ return;
165
+ }
166
+ setState("paused");
167
+ mediaRecorder.pause();
168
+ if (!config2.disableLogs) {
169
+ console.log("Paused recording.");
170
+ }
171
+ }
172
+ function resumeRecording() {
173
+ if (!mediaRecorder) {
174
+ warningLog();
175
+ return;
176
+ }
177
+ if (self2.state !== "paused") {
178
+ if (!config2.disableLogs) {
179
+ console.warn("Unable to resume the recording. Recording state: ", self2.state);
180
+ }
181
+ return;
182
+ }
183
+ setState("recording");
184
+ mediaRecorder.resume();
185
+ if (!config2.disableLogs) {
186
+ console.log("Resumed recording.");
187
+ }
188
+ }
189
+ function readFile(_blob) {
190
+ postMessage(new FileReaderSync().readAsDataURL(_blob));
191
+ }
192
+ function getDataURL(callback, _mediaRecorder) {
193
+ if (!callback) {
194
+ throw "Pass a callback function over getDataURL.";
195
+ }
196
+ var blob = _mediaRecorder ? _mediaRecorder.blob : (mediaRecorder || {}).blob;
197
+ if (!blob) {
198
+ if (!config2.disableLogs) {
199
+ console.warn("Blob encoder did not finish its job yet.");
200
+ }
201
+ setTimeout(function() {
202
+ getDataURL(callback, _mediaRecorder);
203
+ }, 1e3);
204
+ return;
205
+ }
206
+ if (typeof Worker !== "undefined" && !navigator.mozGetUserMedia) {
207
+ var webWorker = processInWebWorker(readFile);
208
+ webWorker.onmessage = function(event) {
209
+ callback(event.data);
210
+ };
211
+ webWorker.postMessage(blob);
212
+ } else {
213
+ var reader = new FileReader();
214
+ reader.readAsDataURL(blob);
215
+ reader.onload = function(event) {
216
+ callback(event.target.result);
217
+ };
218
+ }
219
+ function processInWebWorker(_function) {
220
+ try {
221
+ var blob2 = URL2.createObjectURL(new Blob([
222
+ _function.toString(),
223
+ "this.onmessage = function (eee) {" + _function.name + "(eee.data);}"
224
+ ], {
225
+ type: "application/javascript"
226
+ }));
227
+ var worker = new Worker(blob2);
228
+ URL2.revokeObjectURL(blob2);
229
+ return worker;
230
+ } catch (e) {
231
+ }
232
+ }
233
+ }
234
+ function handleRecordingDuration(counter) {
235
+ counter = counter || 0;
236
+ if (self2.state === "paused") {
237
+ setTimeout(function() {
238
+ handleRecordingDuration(counter);
239
+ }, 1e3);
240
+ return;
241
+ }
242
+ if (self2.state === "stopped") {
243
+ return;
244
+ }
245
+ if (counter >= self2.recordingDuration) {
246
+ stopRecording(self2.onRecordingStopped);
247
+ return;
248
+ }
249
+ counter += 1e3;
250
+ setTimeout(function() {
251
+ handleRecordingDuration(counter);
252
+ }, 1e3);
253
+ }
254
+ function setState(state) {
255
+ if (!self2) {
256
+ return;
257
+ }
258
+ self2.state = state;
259
+ if (typeof self2.onStateChanged.call === "function") {
260
+ self2.onStateChanged.call(self2, state);
261
+ } else {
262
+ self2.onStateChanged(state);
263
+ }
264
+ }
265
+ var WARNING = 'It seems that recorder is destroyed or "startRecording" is not invoked for ' + config2.type + " recorder.";
266
+ function warningLog() {
267
+ if (config2.disableLogs === true) {
268
+ return;
269
+ }
270
+ console.warn(WARNING);
271
+ }
272
+ var mediaRecorder;
273
+ var returnObject = {
274
+ startRecording,
275
+ stopRecording,
276
+ pauseRecording,
277
+ resumeRecording,
278
+ initRecorder,
279
+ setRecordingDuration: function(recordingDuration, callback) {
280
+ if (typeof recordingDuration === "undefined") {
281
+ throw "recordingDuration is required.";
282
+ }
283
+ if (typeof recordingDuration !== "number") {
284
+ throw "recordingDuration must be a number.";
285
+ }
286
+ self2.recordingDuration = recordingDuration;
287
+ self2.onRecordingStopped = callback || function() {
288
+ };
289
+ return {
290
+ onRecordingStopped: function(callback2) {
291
+ self2.onRecordingStopped = callback2;
292
+ }
293
+ };
294
+ },
295
+ clearRecordedData: function() {
296
+ if (!mediaRecorder) {
297
+ warningLog();
298
+ return;
299
+ }
300
+ mediaRecorder.clearRecordedData();
301
+ if (!config2.disableLogs) {
302
+ console.log("Cleared old recorded data.");
303
+ }
304
+ },
305
+ getBlob: function() {
306
+ if (!mediaRecorder) {
307
+ warningLog();
308
+ return;
309
+ }
310
+ return mediaRecorder.blob;
311
+ },
312
+ getDataURL,
313
+ toURL: function() {
314
+ if (!mediaRecorder) {
315
+ warningLog();
316
+ return;
317
+ }
318
+ return URL2.createObjectURL(mediaRecorder.blob);
319
+ },
320
+ getInternalRecorder: function() {
321
+ return mediaRecorder;
322
+ },
323
+ save: function(fileName) {
324
+ if (!mediaRecorder) {
325
+ warningLog();
326
+ return;
327
+ }
328
+ invokeSaveAsDialog2(mediaRecorder.blob, fileName);
329
+ },
330
+ getFromDisk: function(callback) {
331
+ if (!mediaRecorder) {
332
+ warningLog();
333
+ return;
334
+ }
335
+ RecordRTC.getFromDisk(config2.type, callback);
336
+ },
337
+ setAdvertisementArray: function(arrayOfWebPImages) {
338
+ config2.advertisement = [];
339
+ var length = arrayOfWebPImages.length;
340
+ for (var i = 0; i < length; i++) {
341
+ config2.advertisement.push({
342
+ duration: i,
343
+ image: arrayOfWebPImages[i]
344
+ });
345
+ }
346
+ },
347
+ blob: null,
348
+ bufferSize: 0,
349
+ sampleRate: 0,
350
+ buffer: null,
351
+ reset: function() {
352
+ if (self2.state === "recording" && !config2.disableLogs) {
353
+ console.warn("Stop an active recorder.");
354
+ }
355
+ if (mediaRecorder && typeof mediaRecorder.clearRecordedData === "function") {
356
+ mediaRecorder.clearRecordedData();
357
+ }
358
+ mediaRecorder = null;
359
+ setState("inactive");
360
+ self2.blob = null;
361
+ },
362
+ onStateChanged: function(state) {
363
+ if (!config2.disableLogs) {
364
+ console.log("Recorder state changed:", state);
365
+ }
366
+ },
367
+ state: "inactive",
368
+ getState: function() {
369
+ return self2.state;
370
+ },
371
+ destroy: function() {
372
+ var disableLogsCache = config2.disableLogs;
373
+ config2 = {
374
+ disableLogs: true
375
+ };
376
+ self2.reset();
377
+ setState("destroyed");
378
+ returnObject = self2 = null;
379
+ if (Storage.AudioContextConstructor) {
380
+ Storage.AudioContextConstructor.close();
381
+ Storage.AudioContextConstructor = null;
382
+ }
383
+ config2.disableLogs = disableLogsCache;
384
+ if (!config2.disableLogs) {
385
+ console.log("RecordRTC is destroyed.");
386
+ }
387
+ },
388
+ version: "5.6.2"
389
+ };
390
+ if (!this) {
391
+ self2 = returnObject;
392
+ return returnObject;
393
+ }
394
+ for (var prop in returnObject) {
395
+ this[prop] = returnObject[prop];
396
+ }
397
+ self2 = this;
398
+ return returnObject;
399
+ }
400
+ RecordRTC.version = "5.6.2";
401
+ if (typeof module2 !== "undefined") {
402
+ module2.exports = RecordRTC;
403
+ }
404
+ if (typeof define === "function" && define.amd) {
405
+ define("RecordRTC", [], function() {
406
+ return RecordRTC;
407
+ });
408
+ }
409
+ RecordRTC.getFromDisk = function(type, callback) {
410
+ if (!callback) {
411
+ throw "callback is mandatory.";
412
+ }
413
+ console.log("Getting recorded " + (type === "all" ? "blobs" : type + " blob ") + " from disk!");
414
+ DiskStorage.Fetch(function(dataURL, _type) {
415
+ if (type !== "all" && _type === type + "Blob" && callback) {
416
+ callback(dataURL);
417
+ }
418
+ if (type === "all" && callback) {
419
+ callback(dataURL, _type.replace("Blob", ""));
420
+ }
421
+ });
422
+ };
423
+ RecordRTC.writeToDisk = function(options) {
424
+ console.log("Writing recorded blob(s) to disk!");
425
+ options = options || {};
426
+ if (options.audio && options.video && options.gif) {
427
+ options.audio.getDataURL(function(audioDataURL) {
428
+ options.video.getDataURL(function(videoDataURL) {
429
+ options.gif.getDataURL(function(gifDataURL) {
430
+ DiskStorage.Store({
431
+ audioBlob: audioDataURL,
432
+ videoBlob: videoDataURL,
433
+ gifBlob: gifDataURL
434
+ });
435
+ });
436
+ });
437
+ });
438
+ } else if (options.audio && options.video) {
439
+ options.audio.getDataURL(function(audioDataURL) {
440
+ options.video.getDataURL(function(videoDataURL) {
441
+ DiskStorage.Store({
442
+ audioBlob: audioDataURL,
443
+ videoBlob: videoDataURL
444
+ });
445
+ });
446
+ });
447
+ } else if (options.audio && options.gif) {
448
+ options.audio.getDataURL(function(audioDataURL) {
449
+ options.gif.getDataURL(function(gifDataURL) {
450
+ DiskStorage.Store({
451
+ audioBlob: audioDataURL,
452
+ gifBlob: gifDataURL
453
+ });
454
+ });
455
+ });
456
+ } else if (options.video && options.gif) {
457
+ options.video.getDataURL(function(videoDataURL) {
458
+ options.gif.getDataURL(function(gifDataURL) {
459
+ DiskStorage.Store({
460
+ videoBlob: videoDataURL,
461
+ gifBlob: gifDataURL
462
+ });
463
+ });
464
+ });
465
+ } else if (options.audio) {
466
+ options.audio.getDataURL(function(audioDataURL) {
467
+ DiskStorage.Store({
468
+ audioBlob: audioDataURL
469
+ });
470
+ });
471
+ } else if (options.video) {
472
+ options.video.getDataURL(function(videoDataURL) {
473
+ DiskStorage.Store({
474
+ videoBlob: videoDataURL
475
+ });
476
+ });
477
+ } else if (options.gif) {
478
+ options.gif.getDataURL(function(gifDataURL) {
479
+ DiskStorage.Store({
480
+ gifBlob: gifDataURL
481
+ });
482
+ });
483
+ }
484
+ };
485
+ function RecordRTCConfiguration(mediaStream, config2) {
486
+ if (!config2.recorderType && !config2.type) {
487
+ if (!!config2.audio && !!config2.video) {
488
+ config2.type = "video";
489
+ } else if (!!config2.audio && !config2.video) {
490
+ config2.type = "audio";
491
+ }
492
+ }
493
+ if (config2.recorderType && !config2.type) {
494
+ if (config2.recorderType === WhammyRecorder || config2.recorderType === CanvasRecorder || typeof WebAssemblyRecorder !== "undefined" && config2.recorderType === WebAssemblyRecorder) {
495
+ config2.type = "video";
496
+ } else if (config2.recorderType === GifRecorder) {
497
+ config2.type = "gif";
498
+ } else if (config2.recorderType === StereoAudioRecorder) {
499
+ config2.type = "audio";
500
+ } else if (config2.recorderType === MediaStreamRecorder) {
501
+ if (getTracks(mediaStream, "audio").length && getTracks(mediaStream, "video").length) {
502
+ config2.type = "video";
503
+ } else if (!getTracks(mediaStream, "audio").length && getTracks(mediaStream, "video").length) {
504
+ config2.type = "video";
505
+ } else if (getTracks(mediaStream, "audio").length && !getTracks(mediaStream, "video").length) {
506
+ config2.type = "audio";
507
+ } else {
508
+ }
509
+ }
510
+ }
511
+ if (typeof MediaStreamRecorder !== "undefined" && typeof MediaRecorder !== "undefined" && "requestData" in MediaRecorder.prototype) {
512
+ if (!config2.mimeType) {
513
+ config2.mimeType = "video/webm";
514
+ }
515
+ if (!config2.type) {
516
+ config2.type = config2.mimeType.split("/")[0];
517
+ }
518
+ if (!config2.bitsPerSecond) {
519
+ }
520
+ }
521
+ if (!config2.type) {
522
+ if (config2.mimeType) {
523
+ config2.type = config2.mimeType.split("/")[0];
524
+ }
525
+ if (!config2.type) {
526
+ config2.type = "audio";
527
+ }
528
+ }
529
+ return config2;
530
+ }
531
+ function GetRecorderType(mediaStream, config2) {
532
+ var recorder;
533
+ if (isChrome || isEdge || isOpera) {
534
+ recorder = StereoAudioRecorder;
535
+ }
536
+ if (typeof MediaRecorder !== "undefined" && "requestData" in MediaRecorder.prototype && !isChrome) {
537
+ recorder = MediaStreamRecorder;
538
+ }
539
+ if (config2.type === "video" && (isChrome || isOpera)) {
540
+ recorder = WhammyRecorder;
541
+ if (typeof WebAssemblyRecorder !== "undefined" && typeof ReadableStream !== "undefined") {
542
+ recorder = WebAssemblyRecorder;
543
+ }
544
+ }
545
+ if (config2.type === "gif") {
546
+ recorder = GifRecorder;
547
+ }
548
+ if (config2.type === "canvas") {
549
+ recorder = CanvasRecorder;
550
+ }
551
+ if (isMediaRecorderCompatible() && recorder !== CanvasRecorder && recorder !== GifRecorder && typeof MediaRecorder !== "undefined" && "requestData" in MediaRecorder.prototype) {
552
+ if (getTracks(mediaStream, "video").length || getTracks(mediaStream, "audio").length) {
553
+ if (config2.type === "audio") {
554
+ if (typeof MediaRecorder.isTypeSupported === "function" && MediaRecorder.isTypeSupported("audio/webm")) {
555
+ recorder = MediaStreamRecorder;
556
+ }
557
+ } else {
558
+ if (typeof MediaRecorder.isTypeSupported === "function" && MediaRecorder.isTypeSupported("video/webm")) {
559
+ recorder = MediaStreamRecorder;
560
+ }
561
+ }
562
+ }
563
+ }
564
+ if (mediaStream instanceof Array && mediaStream.length) {
565
+ recorder = MultiStreamRecorder;
566
+ }
567
+ if (config2.recorderType) {
568
+ recorder = config2.recorderType;
569
+ }
570
+ if (!config2.disableLogs && !!recorder && !!recorder.name) {
571
+ console.log("Using recorderType:", recorder.name || recorder.constructor.name);
572
+ }
573
+ if (!recorder && isSafari) {
574
+ recorder = MediaStreamRecorder;
575
+ }
576
+ return recorder;
577
+ }
578
+ function MRecordRTC(mediaStream) {
579
+ this.addStream = function(_mediaStream) {
580
+ if (_mediaStream) {
581
+ mediaStream = _mediaStream;
582
+ }
583
+ };
584
+ this.mediaType = {
585
+ audio: true,
586
+ video: true
587
+ };
588
+ this.startRecording = function() {
589
+ var mediaType = this.mediaType;
590
+ var recorderType;
591
+ var mimeType = this.mimeType || {
592
+ audio: null,
593
+ video: null,
594
+ gif: null
595
+ };
596
+ if (typeof mediaType.audio !== "function" && isMediaRecorderCompatible() && !getTracks(mediaStream, "audio").length) {
597
+ mediaType.audio = false;
598
+ }
599
+ if (typeof mediaType.video !== "function" && isMediaRecorderCompatible() && !getTracks(mediaStream, "video").length) {
600
+ mediaType.video = false;
601
+ }
602
+ if (typeof mediaType.gif !== "function" && isMediaRecorderCompatible() && !getTracks(mediaStream, "video").length) {
603
+ mediaType.gif = false;
604
+ }
605
+ if (!mediaType.audio && !mediaType.video && !mediaType.gif) {
606
+ throw "MediaStream must have either audio or video tracks.";
607
+ }
608
+ if (!!mediaType.audio) {
609
+ recorderType = null;
610
+ if (typeof mediaType.audio === "function") {
611
+ recorderType = mediaType.audio;
612
+ }
613
+ this.audioRecorder = new RecordRTC(mediaStream, {
614
+ type: "audio",
615
+ bufferSize: this.bufferSize,
616
+ sampleRate: this.sampleRate,
617
+ numberOfAudioChannels: this.numberOfAudioChannels || 2,
618
+ disableLogs: this.disableLogs,
619
+ recorderType,
620
+ mimeType: mimeType.audio,
621
+ timeSlice: this.timeSlice,
622
+ onTimeStamp: this.onTimeStamp
623
+ });
624
+ if (!mediaType.video) {
625
+ this.audioRecorder.startRecording();
626
+ }
627
+ }
628
+ if (!!mediaType.video) {
629
+ recorderType = null;
630
+ if (typeof mediaType.video === "function") {
631
+ recorderType = mediaType.video;
632
+ }
633
+ var newStream = mediaStream;
634
+ if (isMediaRecorderCompatible() && !!mediaType.audio && typeof mediaType.audio === "function") {
635
+ var videoTrack = getTracks(mediaStream, "video")[0];
636
+ if (isFirefox) {
637
+ newStream = new MediaStream();
638
+ newStream.addTrack(videoTrack);
639
+ if (recorderType && recorderType === WhammyRecorder) {
640
+ recorderType = MediaStreamRecorder;
641
+ }
642
+ } else {
643
+ newStream = new MediaStream();
644
+ newStream.addTrack(videoTrack);
645
+ }
646
+ }
647
+ this.videoRecorder = new RecordRTC(newStream, {
648
+ type: "video",
649
+ video: this.video,
650
+ canvas: this.canvas,
651
+ frameInterval: this.frameInterval || 10,
652
+ disableLogs: this.disableLogs,
653
+ recorderType,
654
+ mimeType: mimeType.video,
655
+ timeSlice: this.timeSlice,
656
+ onTimeStamp: this.onTimeStamp,
657
+ workerPath: this.workerPath,
658
+ webAssemblyPath: this.webAssemblyPath,
659
+ frameRate: this.frameRate,
660
+ bitrate: this.bitrate
661
+ });
662
+ if (!mediaType.audio) {
663
+ this.videoRecorder.startRecording();
664
+ }
665
+ }
666
+ if (!!mediaType.audio && !!mediaType.video) {
667
+ var self2 = this;
668
+ var isSingleRecorder = isMediaRecorderCompatible() === true;
669
+ if (mediaType.audio instanceof StereoAudioRecorder && !!mediaType.video) {
670
+ isSingleRecorder = false;
671
+ } else if (mediaType.audio !== true && mediaType.video !== true && mediaType.audio !== mediaType.video) {
672
+ isSingleRecorder = false;
673
+ }
674
+ if (isSingleRecorder === true) {
675
+ self2.audioRecorder = null;
676
+ self2.videoRecorder.startRecording();
677
+ } else {
678
+ self2.videoRecorder.initRecorder(function() {
679
+ self2.audioRecorder.initRecorder(function() {
680
+ self2.videoRecorder.startRecording();
681
+ self2.audioRecorder.startRecording();
682
+ });
683
+ });
684
+ }
685
+ }
686
+ if (!!mediaType.gif) {
687
+ recorderType = null;
688
+ if (typeof mediaType.gif === "function") {
689
+ recorderType = mediaType.gif;
690
+ }
691
+ this.gifRecorder = new RecordRTC(mediaStream, {
692
+ type: "gif",
693
+ frameRate: this.frameRate || 200,
694
+ quality: this.quality || 10,
695
+ disableLogs: this.disableLogs,
696
+ recorderType,
697
+ mimeType: mimeType.gif
698
+ });
699
+ this.gifRecorder.startRecording();
700
+ }
701
+ };
702
+ this.stopRecording = function(callback) {
703
+ callback = callback || function() {
704
+ };
705
+ if (this.audioRecorder) {
706
+ this.audioRecorder.stopRecording(function(blobURL) {
707
+ callback(blobURL, "audio");
708
+ });
709
+ }
710
+ if (this.videoRecorder) {
711
+ this.videoRecorder.stopRecording(function(blobURL) {
712
+ callback(blobURL, "video");
713
+ });
714
+ }
715
+ if (this.gifRecorder) {
716
+ this.gifRecorder.stopRecording(function(blobURL) {
717
+ callback(blobURL, "gif");
718
+ });
719
+ }
720
+ };
721
+ this.pauseRecording = function() {
722
+ if (this.audioRecorder) {
723
+ this.audioRecorder.pauseRecording();
724
+ }
725
+ if (this.videoRecorder) {
726
+ this.videoRecorder.pauseRecording();
727
+ }
728
+ if (this.gifRecorder) {
729
+ this.gifRecorder.pauseRecording();
730
+ }
731
+ };
732
+ this.resumeRecording = function() {
733
+ if (this.audioRecorder) {
734
+ this.audioRecorder.resumeRecording();
735
+ }
736
+ if (this.videoRecorder) {
737
+ this.videoRecorder.resumeRecording();
738
+ }
739
+ if (this.gifRecorder) {
740
+ this.gifRecorder.resumeRecording();
741
+ }
742
+ };
743
+ this.getBlob = function(callback) {
744
+ var output = {};
745
+ if (this.audioRecorder) {
746
+ output.audio = this.audioRecorder.getBlob();
747
+ }
748
+ if (this.videoRecorder) {
749
+ output.video = this.videoRecorder.getBlob();
750
+ }
751
+ if (this.gifRecorder) {
752
+ output.gif = this.gifRecorder.getBlob();
753
+ }
754
+ if (callback) {
755
+ callback(output);
756
+ }
757
+ return output;
758
+ };
759
+ this.destroy = function() {
760
+ if (this.audioRecorder) {
761
+ this.audioRecorder.destroy();
762
+ this.audioRecorder = null;
763
+ }
764
+ if (this.videoRecorder) {
765
+ this.videoRecorder.destroy();
766
+ this.videoRecorder = null;
767
+ }
768
+ if (this.gifRecorder) {
769
+ this.gifRecorder.destroy();
770
+ this.gifRecorder = null;
771
+ }
772
+ };
773
+ this.getDataURL = function(callback) {
774
+ this.getBlob(function(blob) {
775
+ if (blob.audio && blob.video) {
776
+ getDataURL(blob.audio, function(_audioDataURL) {
777
+ getDataURL(blob.video, function(_videoDataURL) {
778
+ callback({
779
+ audio: _audioDataURL,
780
+ video: _videoDataURL
781
+ });
782
+ });
783
+ });
784
+ } else if (blob.audio) {
785
+ getDataURL(blob.audio, function(_audioDataURL) {
786
+ callback({
787
+ audio: _audioDataURL
788
+ });
789
+ });
790
+ } else if (blob.video) {
791
+ getDataURL(blob.video, function(_videoDataURL) {
792
+ callback({
793
+ video: _videoDataURL
794
+ });
795
+ });
796
+ }
797
+ });
798
+ function getDataURL(blob, callback00) {
799
+ if (typeof Worker !== "undefined") {
800
+ var webWorker = processInWebWorker(function readFile(_blob) {
801
+ postMessage(new FileReaderSync().readAsDataURL(_blob));
802
+ });
803
+ webWorker.onmessage = function(event) {
804
+ callback00(event.data);
805
+ };
806
+ webWorker.postMessage(blob);
807
+ } else {
808
+ var reader = new FileReader();
809
+ reader.readAsDataURL(blob);
810
+ reader.onload = function(event) {
811
+ callback00(event.target.result);
812
+ };
813
+ }
814
+ }
815
+ function processInWebWorker(_function) {
816
+ var blob = URL2.createObjectURL(new Blob([
817
+ _function.toString(),
818
+ "this.onmessage = function (eee) {" + _function.name + "(eee.data);}"
819
+ ], {
820
+ type: "application/javascript"
821
+ }));
822
+ var worker = new Worker(blob);
823
+ var url;
824
+ if (typeof URL2 !== "undefined") {
825
+ url = URL2;
826
+ } else if (typeof webkitURL !== "undefined") {
827
+ url = webkitURL;
828
+ } else {
829
+ throw "Neither URL nor webkitURL detected.";
830
+ }
831
+ url.revokeObjectURL(blob);
832
+ return worker;
833
+ }
834
+ };
835
+ this.writeToDisk = function() {
836
+ RecordRTC.writeToDisk({
837
+ audio: this.audioRecorder,
838
+ video: this.videoRecorder,
839
+ gif: this.gifRecorder
840
+ });
841
+ };
842
+ this.save = function(args) {
843
+ args = args || {
844
+ audio: true,
845
+ video: true,
846
+ gif: true
847
+ };
848
+ if (!!args.audio && this.audioRecorder) {
849
+ this.audioRecorder.save(typeof args.audio === "string" ? args.audio : "");
850
+ }
851
+ if (!!args.video && this.videoRecorder) {
852
+ this.videoRecorder.save(typeof args.video === "string" ? args.video : "");
853
+ }
854
+ if (!!args.gif && this.gifRecorder) {
855
+ this.gifRecorder.save(typeof args.gif === "string" ? args.gif : "");
856
+ }
857
+ };
858
+ }
859
+ MRecordRTC.getFromDisk = RecordRTC.getFromDisk;
860
+ MRecordRTC.writeToDisk = RecordRTC.writeToDisk;
861
+ if (typeof RecordRTC !== "undefined") {
862
+ RecordRTC.MRecordRTC = MRecordRTC;
863
+ }
864
+ var browserFakeUserAgent = "Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45";
865
+ (function(that) {
866
+ if (!that) {
867
+ return;
868
+ }
869
+ if (typeof window !== "undefined") {
870
+ return;
871
+ }
872
+ if (typeof global === "undefined") {
873
+ return;
874
+ }
875
+ global.navigator = {
876
+ userAgent: browserFakeUserAgent,
877
+ getUserMedia: function() {
878
+ }
879
+ };
880
+ if (!global.console) {
881
+ global.console = {};
882
+ }
883
+ if (typeof global.console.log === "undefined" || typeof global.console.error === "undefined") {
884
+ global.console.error = global.console.log = global.console.log || function() {
885
+ console.log(arguments);
886
+ };
887
+ }
888
+ if (typeof document === "undefined") {
889
+ that.document = {
890
+ documentElement: {
891
+ appendChild: function() {
892
+ return "";
893
+ }
894
+ }
895
+ };
896
+ document.createElement = document.captureStream = document.mozCaptureStream = function() {
897
+ var obj = {
898
+ getContext: function() {
899
+ return obj;
900
+ },
901
+ play: function() {
902
+ },
903
+ pause: function() {
904
+ },
905
+ drawImage: function() {
906
+ },
907
+ toDataURL: function() {
908
+ return "";
909
+ },
910
+ style: {}
911
+ };
912
+ return obj;
913
+ };
914
+ that.HTMLVideoElement = function() {
915
+ };
916
+ }
917
+ if (typeof location === "undefined") {
918
+ that.location = {
919
+ protocol: "file:",
920
+ href: "",
921
+ hash: ""
922
+ };
923
+ }
924
+ if (typeof screen === "undefined") {
925
+ that.screen = {
926
+ width: 0,
927
+ height: 0
928
+ };
929
+ }
930
+ if (typeof URL2 === "undefined") {
931
+ that.URL = {
932
+ createObjectURL: function() {
933
+ return "";
934
+ },
935
+ revokeObjectURL: function() {
936
+ return "";
937
+ }
938
+ };
939
+ }
940
+ that.window = global;
941
+ })(typeof global !== "undefined" ? global : null);
942
+ var requestAnimationFrame = window.requestAnimationFrame;
943
+ if (typeof requestAnimationFrame === "undefined") {
944
+ if (typeof webkitRequestAnimationFrame !== "undefined") {
945
+ requestAnimationFrame = webkitRequestAnimationFrame;
946
+ } else if (typeof mozRequestAnimationFrame !== "undefined") {
947
+ requestAnimationFrame = mozRequestAnimationFrame;
948
+ } else if (typeof msRequestAnimationFrame !== "undefined") {
949
+ requestAnimationFrame = msRequestAnimationFrame;
950
+ } else if (typeof requestAnimationFrame === "undefined") {
951
+ lastTime = 0;
952
+ requestAnimationFrame = function(callback, element) {
953
+ var currTime = new Date().getTime();
954
+ var timeToCall = Math.max(0, 16 - (currTime - lastTime));
955
+ var id = setTimeout(function() {
956
+ callback(currTime + timeToCall);
957
+ }, timeToCall);
958
+ lastTime = currTime + timeToCall;
959
+ return id;
960
+ };
961
+ }
962
+ }
963
+ var lastTime;
964
+ var cancelAnimationFrame = window.cancelAnimationFrame;
965
+ if (typeof cancelAnimationFrame === "undefined") {
966
+ if (typeof webkitCancelAnimationFrame !== "undefined") {
967
+ cancelAnimationFrame = webkitCancelAnimationFrame;
968
+ } else if (typeof mozCancelAnimationFrame !== "undefined") {
969
+ cancelAnimationFrame = mozCancelAnimationFrame;
970
+ } else if (typeof msCancelAnimationFrame !== "undefined") {
971
+ cancelAnimationFrame = msCancelAnimationFrame;
972
+ } else if (typeof cancelAnimationFrame === "undefined") {
973
+ cancelAnimationFrame = function(id) {
974
+ clearTimeout(id);
975
+ };
976
+ }
977
+ }
978
+ var AudioContext = window.AudioContext;
979
+ if (typeof AudioContext === "undefined") {
980
+ if (typeof webkitAudioContext !== "undefined") {
981
+ AudioContext = webkitAudioContext;
982
+ }
983
+ if (typeof mozAudioContext !== "undefined") {
984
+ AudioContext = mozAudioContext;
985
+ }
986
+ }
987
+ var URL2 = window.URL;
988
+ if (typeof URL2 === "undefined" && typeof webkitURL !== "undefined") {
989
+ URL2 = webkitURL;
990
+ }
991
+ if (typeof navigator !== "undefined" && typeof navigator.getUserMedia === "undefined") {
992
+ if (typeof navigator.webkitGetUserMedia !== "undefined") {
993
+ navigator.getUserMedia = navigator.webkitGetUserMedia;
994
+ }
995
+ if (typeof navigator.mozGetUserMedia !== "undefined") {
996
+ navigator.getUserMedia = navigator.mozGetUserMedia;
997
+ }
998
+ }
999
+ var isEdge = navigator.userAgent.indexOf("Edge") !== -1 && (!!navigator.msSaveBlob || !!navigator.msSaveOrOpenBlob);
1000
+ var isOpera = !!window.opera || navigator.userAgent.indexOf("OPR/") !== -1;
1001
+ var isFirefox = navigator.userAgent.toLowerCase().indexOf("firefox") > -1 && "netscape" in window && / rv:/.test(navigator.userAgent);
1002
+ var isChrome = !isOpera && !isEdge && !!navigator.webkitGetUserMedia || isElectron() || navigator.userAgent.toLowerCase().indexOf("chrome/") !== -1;
1003
+ var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
1004
+ if (isSafari && !isChrome && navigator.userAgent.indexOf("CriOS") !== -1) {
1005
+ isSafari = false;
1006
+ isChrome = true;
1007
+ }
1008
+ var MediaStream = window.MediaStream;
1009
+ if (typeof MediaStream === "undefined" && typeof webkitMediaStream !== "undefined") {
1010
+ MediaStream = webkitMediaStream;
1011
+ }
1012
+ if (typeof MediaStream !== "undefined") {
1013
+ if (typeof MediaStream.prototype.stop === "undefined") {
1014
+ MediaStream.prototype.stop = function() {
1015
+ this.getTracks().forEach(function(track) {
1016
+ track.stop();
1017
+ });
1018
+ };
1019
+ }
1020
+ }
1021
+ function bytesToSize(bytes) {
1022
+ var k = 1e3;
1023
+ var sizes = ["Bytes", "KB", "MB", "GB", "TB"];
1024
+ if (bytes === 0) {
1025
+ return "0 Bytes";
1026
+ }
1027
+ var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
1028
+ return (bytes / Math.pow(k, i)).toPrecision(3) + " " + sizes[i];
1029
+ }
1030
+ function invokeSaveAsDialog2(file, fileName) {
1031
+ if (!file) {
1032
+ throw "Blob object is required.";
1033
+ }
1034
+ if (!file.type) {
1035
+ try {
1036
+ file.type = "video/webm";
1037
+ } catch (e) {
1038
+ }
1039
+ }
1040
+ var fileExtension = (file.type || "video/webm").split("/")[1];
1041
+ if (fileExtension.indexOf(";") !== -1) {
1042
+ fileExtension = fileExtension.split(";")[0];
1043
+ }
1044
+ if (fileName && fileName.indexOf(".") !== -1) {
1045
+ var splitted = fileName.split(".");
1046
+ fileName = splitted[0];
1047
+ fileExtension = splitted[1];
1048
+ }
1049
+ var fileFullName = (fileName || Math.round(Math.random() * 9999999999) + 888888888) + "." + fileExtension;
1050
+ if (typeof navigator.msSaveOrOpenBlob !== "undefined") {
1051
+ return navigator.msSaveOrOpenBlob(file, fileFullName);
1052
+ } else if (typeof navigator.msSaveBlob !== "undefined") {
1053
+ return navigator.msSaveBlob(file, fileFullName);
1054
+ }
1055
+ var hyperlink = document.createElement("a");
1056
+ hyperlink.href = URL2.createObjectURL(file);
1057
+ hyperlink.download = fileFullName;
1058
+ hyperlink.style = "display:none;opacity:0;color:transparent;";
1059
+ (document.body || document.documentElement).appendChild(hyperlink);
1060
+ if (typeof hyperlink.click === "function") {
1061
+ hyperlink.click();
1062
+ } else {
1063
+ hyperlink.target = "_blank";
1064
+ hyperlink.dispatchEvent(new MouseEvent("click", {
1065
+ view: window,
1066
+ bubbles: true,
1067
+ cancelable: true
1068
+ }));
1069
+ }
1070
+ URL2.revokeObjectURL(hyperlink.href);
1071
+ }
1072
+ function isElectron() {
1073
+ if (typeof window !== "undefined" && typeof window.process === "object" && window.process.type === "renderer") {
1074
+ return true;
1075
+ }
1076
+ if (typeof process !== "undefined" && typeof process.versions === "object" && !!process.versions.electron) {
1077
+ return true;
1078
+ }
1079
+ if (typeof navigator === "object" && typeof navigator.userAgent === "string" && navigator.userAgent.indexOf("Electron") >= 0) {
1080
+ return true;
1081
+ }
1082
+ return false;
1083
+ }
1084
+ function getTracks(stream, kind) {
1085
+ if (!stream || !stream.getTracks) {
1086
+ return [];
1087
+ }
1088
+ return stream.getTracks().filter(function(t) {
1089
+ return t.kind === (kind || "audio");
1090
+ });
1091
+ }
1092
+ function setSrcObject(stream, element) {
1093
+ if ("srcObject" in element) {
1094
+ element.srcObject = stream;
1095
+ } else if ("mozSrcObject" in element) {
1096
+ element.mozSrcObject = stream;
1097
+ } else {
1098
+ element.srcObject = stream;
1099
+ }
1100
+ }
1101
+ function getSeekableBlob3(inputBlob, callback) {
1102
+ if (typeof EBML === "undefined") {
1103
+ throw new Error("Please link: https://www.webrtc-experiment.com/EBML.js");
1104
+ }
1105
+ var reader = new EBML.Reader();
1106
+ var decoder = new EBML.Decoder();
1107
+ var tools = EBML.tools;
1108
+ var fileReader = new FileReader();
1109
+ fileReader.onload = function(e) {
1110
+ var ebmlElms = decoder.decode(this.result);
1111
+ ebmlElms.forEach(function(element) {
1112
+ reader.read(element);
1113
+ });
1114
+ reader.stop();
1115
+ var refinedMetadataBuf = tools.makeMetadataSeekable(reader.metadatas, reader.duration, reader.cues);
1116
+ var body = this.result.slice(reader.metadataSize);
1117
+ var newBlob = new Blob([refinedMetadataBuf, body], {
1118
+ type: "video/webm"
1119
+ });
1120
+ callback(newBlob);
1121
+ };
1122
+ fileReader.readAsArrayBuffer(inputBlob);
1123
+ }
1124
+ if (typeof RecordRTC !== "undefined") {
1125
+ RecordRTC.invokeSaveAsDialog = invokeSaveAsDialog2;
1126
+ RecordRTC.getTracks = getTracks;
1127
+ RecordRTC.getSeekableBlob = getSeekableBlob3;
1128
+ RecordRTC.bytesToSize = bytesToSize;
1129
+ RecordRTC.isElectron = isElectron;
1130
+ }
1131
+ var Storage = {};
1132
+ if (typeof AudioContext !== "undefined") {
1133
+ Storage.AudioContext = AudioContext;
1134
+ } else if (typeof webkitAudioContext !== "undefined") {
1135
+ Storage.AudioContext = webkitAudioContext;
1136
+ }
1137
+ if (typeof RecordRTC !== "undefined") {
1138
+ RecordRTC.Storage = Storage;
1139
+ }
1140
+ function isMediaRecorderCompatible() {
1141
+ if (isFirefox || isSafari || isEdge) {
1142
+ return true;
1143
+ }
1144
+ var nVer = navigator.appVersion;
1145
+ var nAgt = navigator.userAgent;
1146
+ var fullVersion = "" + parseFloat(navigator.appVersion);
1147
+ var majorVersion = parseInt(navigator.appVersion, 10);
1148
+ var nameOffset, verOffset, ix;
1149
+ if (isChrome || isOpera) {
1150
+ verOffset = nAgt.indexOf("Chrome");
1151
+ fullVersion = nAgt.substring(verOffset + 7);
1152
+ }
1153
+ if ((ix = fullVersion.indexOf(";")) !== -1) {
1154
+ fullVersion = fullVersion.substring(0, ix);
1155
+ }
1156
+ if ((ix = fullVersion.indexOf(" ")) !== -1) {
1157
+ fullVersion = fullVersion.substring(0, ix);
1158
+ }
1159
+ majorVersion = parseInt("" + fullVersion, 10);
1160
+ if (isNaN(majorVersion)) {
1161
+ fullVersion = "" + parseFloat(navigator.appVersion);
1162
+ majorVersion = parseInt(navigator.appVersion, 10);
1163
+ }
1164
+ return majorVersion >= 49;
1165
+ }
1166
+ function MediaStreamRecorder(mediaStream, config2) {
1167
+ var self2 = this;
1168
+ if (typeof mediaStream === "undefined") {
1169
+ throw 'First argument "MediaStream" is required.';
1170
+ }
1171
+ if (typeof MediaRecorder === "undefined") {
1172
+ throw "Your browser does not support the Media Recorder API. Please try other modules e.g. WhammyRecorder or StereoAudioRecorder.";
1173
+ }
1174
+ config2 = config2 || {
1175
+ mimeType: "video/webm"
1176
+ };
1177
+ if (config2.type === "audio") {
1178
+ if (getTracks(mediaStream, "video").length && getTracks(mediaStream, "audio").length) {
1179
+ var stream;
1180
+ if (!!navigator.mozGetUserMedia) {
1181
+ stream = new MediaStream();
1182
+ stream.addTrack(getTracks(mediaStream, "audio")[0]);
1183
+ } else {
1184
+ stream = new MediaStream(getTracks(mediaStream, "audio"));
1185
+ }
1186
+ mediaStream = stream;
1187
+ }
1188
+ if (!config2.mimeType || config2.mimeType.toString().toLowerCase().indexOf("audio") === -1) {
1189
+ config2.mimeType = isChrome ? "audio/webm" : "audio/ogg";
1190
+ }
1191
+ if (config2.mimeType && config2.mimeType.toString().toLowerCase() !== "audio/ogg" && !!navigator.mozGetUserMedia) {
1192
+ config2.mimeType = "audio/ogg";
1193
+ }
1194
+ }
1195
+ var arrayOfBlobs = [];
1196
+ this.getArrayOfBlobs = function() {
1197
+ return arrayOfBlobs;
1198
+ };
1199
+ this.record = function() {
1200
+ self2.blob = null;
1201
+ self2.clearRecordedData();
1202
+ self2.timestamps = [];
1203
+ allStates = [];
1204
+ arrayOfBlobs = [];
1205
+ var recorderHints = config2;
1206
+ if (!config2.disableLogs) {
1207
+ console.log("Passing following config over MediaRecorder API.", recorderHints);
1208
+ }
1209
+ if (mediaRecorder) {
1210
+ mediaRecorder = null;
1211
+ }
1212
+ if (isChrome && !isMediaRecorderCompatible()) {
1213
+ recorderHints = "video/vp8";
1214
+ }
1215
+ if (typeof MediaRecorder.isTypeSupported === "function" && recorderHints.mimeType) {
1216
+ if (!MediaRecorder.isTypeSupported(recorderHints.mimeType)) {
1217
+ if (!config2.disableLogs) {
1218
+ console.warn("MediaRecorder API seems unable to record mimeType:", recorderHints.mimeType);
1219
+ }
1220
+ recorderHints.mimeType = config2.type === "audio" ? "audio/webm" : "video/webm";
1221
+ }
1222
+ }
1223
+ try {
1224
+ mediaRecorder = new MediaRecorder(mediaStream, recorderHints);
1225
+ config2.mimeType = recorderHints.mimeType;
1226
+ } catch (e) {
1227
+ mediaRecorder = new MediaRecorder(mediaStream);
1228
+ }
1229
+ if (recorderHints.mimeType && !MediaRecorder.isTypeSupported && "canRecordMimeType" in mediaRecorder && mediaRecorder.canRecordMimeType(recorderHints.mimeType) === false) {
1230
+ if (!config2.disableLogs) {
1231
+ console.warn("MediaRecorder API seems unable to record mimeType:", recorderHints.mimeType);
1232
+ }
1233
+ }
1234
+ mediaRecorder.ondataavailable = function(e) {
1235
+ if (e.data) {
1236
+ allStates.push("ondataavailable: " + bytesToSize(e.data.size));
1237
+ }
1238
+ if (typeof config2.timeSlice === "number") {
1239
+ if (e.data && e.data.size) {
1240
+ arrayOfBlobs.push(e.data);
1241
+ updateTimeStamp();
1242
+ if (typeof config2.ondataavailable === "function") {
1243
+ var blob = config2.getNativeBlob ? e.data : new Blob([e.data], {
1244
+ type: getMimeType(recorderHints)
1245
+ });
1246
+ config2.ondataavailable(blob);
1247
+ }
1248
+ }
1249
+ return;
1250
+ }
1251
+ if (!e.data || !e.data.size || e.data.size < 100 || self2.blob) {
1252
+ if (self2.recordingCallback) {
1253
+ self2.recordingCallback(new Blob([], {
1254
+ type: getMimeType(recorderHints)
1255
+ }));
1256
+ self2.recordingCallback = null;
1257
+ }
1258
+ return;
1259
+ }
1260
+ self2.blob = config2.getNativeBlob ? e.data : new Blob([e.data], {
1261
+ type: getMimeType(recorderHints)
1262
+ });
1263
+ if (self2.recordingCallback) {
1264
+ self2.recordingCallback(self2.blob);
1265
+ self2.recordingCallback = null;
1266
+ }
1267
+ };
1268
+ mediaRecorder.onstart = function() {
1269
+ allStates.push("started");
1270
+ };
1271
+ mediaRecorder.onpause = function() {
1272
+ allStates.push("paused");
1273
+ };
1274
+ mediaRecorder.onresume = function() {
1275
+ allStates.push("resumed");
1276
+ };
1277
+ mediaRecorder.onstop = function() {
1278
+ allStates.push("stopped");
1279
+ };
1280
+ mediaRecorder.onerror = function(error) {
1281
+ if (!error) {
1282
+ return;
1283
+ }
1284
+ if (!error.name) {
1285
+ error.name = "UnknownError";
1286
+ }
1287
+ allStates.push("error: " + error);
1288
+ if (!config2.disableLogs) {
1289
+ if (error.name.toString().toLowerCase().indexOf("invalidstate") !== -1) {
1290
+ console.error("The MediaRecorder is not in a state in which the proposed operation is allowed to be executed.", error);
1291
+ } else if (error.name.toString().toLowerCase().indexOf("notsupported") !== -1) {
1292
+ console.error("MIME type (", recorderHints.mimeType, ") is not supported.", error);
1293
+ } else if (error.name.toString().toLowerCase().indexOf("security") !== -1) {
1294
+ console.error("MediaRecorder security error", error);
1295
+ } else if (error.name === "OutOfMemory") {
1296
+ console.error("The UA has exhaused the available memory. User agents SHOULD provide as much additional information as possible in the message attribute.", error);
1297
+ } else if (error.name === "IllegalStreamModification") {
1298
+ console.error("A modification to the stream has occurred that makes it impossible to continue recording. An example would be the addition of a Track while recording is occurring. User agents SHOULD provide as much additional information as possible in the message attribute.", error);
1299
+ } else if (error.name === "OtherRecordingError") {
1300
+ console.error("Used for an fatal error other than those listed above. User agents SHOULD provide as much additional information as possible in the message attribute.", error);
1301
+ } else if (error.name === "GenericError") {
1302
+ console.error("The UA cannot provide the codec or recording option that has been requested.", error);
1303
+ } else {
1304
+ console.error("MediaRecorder Error", error);
1305
+ }
1306
+ }
1307
+ (function(looper) {
1308
+ if (!self2.manuallyStopped && mediaRecorder && mediaRecorder.state === "inactive") {
1309
+ delete config2.timeslice;
1310
+ mediaRecorder.start(10 * 60 * 1e3);
1311
+ return;
1312
+ }
1313
+ setTimeout(looper, 1e3);
1314
+ })();
1315
+ if (mediaRecorder.state !== "inactive" && mediaRecorder.state !== "stopped") {
1316
+ mediaRecorder.stop();
1317
+ }
1318
+ };
1319
+ if (typeof config2.timeSlice === "number") {
1320
+ updateTimeStamp();
1321
+ mediaRecorder.start(config2.timeSlice);
1322
+ } else {
1323
+ mediaRecorder.start(36e5);
1324
+ }
1325
+ if (config2.initCallback) {
1326
+ config2.initCallback();
1327
+ }
1328
+ };
1329
+ this.timestamps = [];
1330
+ function updateTimeStamp() {
1331
+ self2.timestamps.push(new Date().getTime());
1332
+ if (typeof config2.onTimeStamp === "function") {
1333
+ config2.onTimeStamp(self2.timestamps[self2.timestamps.length - 1], self2.timestamps);
1334
+ }
1335
+ }
1336
+ function getMimeType(secondObject) {
1337
+ if (mediaRecorder && mediaRecorder.mimeType) {
1338
+ return mediaRecorder.mimeType;
1339
+ }
1340
+ return secondObject.mimeType || "video/webm";
1341
+ }
1342
+ this.stop = function(callback) {
1343
+ callback = callback || function() {
1344
+ };
1345
+ self2.manuallyStopped = true;
1346
+ if (!mediaRecorder) {
1347
+ return;
1348
+ }
1349
+ this.recordingCallback = callback;
1350
+ if (mediaRecorder.state === "recording") {
1351
+ mediaRecorder.stop();
1352
+ }
1353
+ if (typeof config2.timeSlice === "number") {
1354
+ setTimeout(function() {
1355
+ self2.blob = new Blob(arrayOfBlobs, {
1356
+ type: getMimeType(config2)
1357
+ });
1358
+ self2.recordingCallback(self2.blob);
1359
+ }, 100);
1360
+ }
1361
+ };
1362
+ this.pause = function() {
1363
+ if (!mediaRecorder) {
1364
+ return;
1365
+ }
1366
+ if (mediaRecorder.state === "recording") {
1367
+ mediaRecorder.pause();
1368
+ }
1369
+ };
1370
+ this.resume = function() {
1371
+ if (!mediaRecorder) {
1372
+ return;
1373
+ }
1374
+ if (mediaRecorder.state === "paused") {
1375
+ mediaRecorder.resume();
1376
+ }
1377
+ };
1378
+ this.clearRecordedData = function() {
1379
+ if (mediaRecorder && mediaRecorder.state === "recording") {
1380
+ self2.stop(clearRecordedDataCB);
1381
+ }
1382
+ clearRecordedDataCB();
1383
+ };
1384
+ function clearRecordedDataCB() {
1385
+ arrayOfBlobs = [];
1386
+ mediaRecorder = null;
1387
+ self2.timestamps = [];
1388
+ }
1389
+ var mediaRecorder;
1390
+ this.getInternalRecorder = function() {
1391
+ return mediaRecorder;
1392
+ };
1393
+ function isMediaStreamActive() {
1394
+ if ("active" in mediaStream) {
1395
+ if (!mediaStream.active) {
1396
+ return false;
1397
+ }
1398
+ } else if ("ended" in mediaStream) {
1399
+ if (mediaStream.ended) {
1400
+ return false;
1401
+ }
1402
+ }
1403
+ return true;
1404
+ }
1405
+ this.blob = null;
1406
+ this.getState = function() {
1407
+ if (!mediaRecorder) {
1408
+ return "inactive";
1409
+ }
1410
+ return mediaRecorder.state || "inactive";
1411
+ };
1412
+ var allStates = [];
1413
+ this.getAllStates = function() {
1414
+ return allStates;
1415
+ };
1416
+ if (typeof config2.checkForInactiveTracks === "undefined") {
1417
+ config2.checkForInactiveTracks = false;
1418
+ }
1419
+ var self2 = this;
1420
+ (function looper() {
1421
+ if (!mediaRecorder || config2.checkForInactiveTracks === false) {
1422
+ return;
1423
+ }
1424
+ if (isMediaStreamActive() === false) {
1425
+ if (!config2.disableLogs) {
1426
+ console.log("MediaStream seems stopped.");
1427
+ }
1428
+ self2.stop();
1429
+ return;
1430
+ }
1431
+ setTimeout(looper, 1e3);
1432
+ })();
1433
+ this.name = "MediaStreamRecorder";
1434
+ this.toString = function() {
1435
+ return this.name;
1436
+ };
1437
+ }
1438
+ if (typeof RecordRTC !== "undefined") {
1439
+ RecordRTC.MediaStreamRecorder = MediaStreamRecorder;
1440
+ }
1441
+ function StereoAudioRecorder(mediaStream, config2) {
1442
+ if (!getTracks(mediaStream, "audio").length) {
1443
+ throw "Your stream has no audio tracks.";
1444
+ }
1445
+ config2 = config2 || {};
1446
+ var self2 = this;
1447
+ var leftchannel = [];
1448
+ var rightchannel = [];
1449
+ var recording = false;
1450
+ var recordingLength = 0;
1451
+ var jsAudioNode;
1452
+ var numberOfAudioChannels = 2;
1453
+ var desiredSampRate = config2.desiredSampRate;
1454
+ if (config2.leftChannel === true) {
1455
+ numberOfAudioChannels = 1;
1456
+ }
1457
+ if (config2.numberOfAudioChannels === 1) {
1458
+ numberOfAudioChannels = 1;
1459
+ }
1460
+ if (!numberOfAudioChannels || numberOfAudioChannels < 1) {
1461
+ numberOfAudioChannels = 2;
1462
+ }
1463
+ if (!config2.disableLogs) {
1464
+ console.log("StereoAudioRecorder is set to record number of channels: " + numberOfAudioChannels);
1465
+ }
1466
+ if (typeof config2.checkForInactiveTracks === "undefined") {
1467
+ config2.checkForInactiveTracks = true;
1468
+ }
1469
+ function isMediaStreamActive() {
1470
+ if (config2.checkForInactiveTracks === false) {
1471
+ return true;
1472
+ }
1473
+ if ("active" in mediaStream) {
1474
+ if (!mediaStream.active) {
1475
+ return false;
1476
+ }
1477
+ } else if ("ended" in mediaStream) {
1478
+ if (mediaStream.ended) {
1479
+ return false;
1480
+ }
1481
+ }
1482
+ return true;
1483
+ }
1484
+ this.record = function() {
1485
+ if (isMediaStreamActive() === false) {
1486
+ throw "Please make sure MediaStream is active.";
1487
+ }
1488
+ resetVariables();
1489
+ isAudioProcessStarted = isPaused = false;
1490
+ recording = true;
1491
+ if (typeof config2.timeSlice !== "undefined") {
1492
+ looper();
1493
+ }
1494
+ };
1495
+ function mergeLeftRightBuffers(config3, callback) {
1496
+ function mergeAudioBuffers(config4, cb) {
1497
+ var numberOfAudioChannels2 = config4.numberOfAudioChannels;
1498
+ var leftBuffers = config4.leftBuffers.slice(0);
1499
+ var rightBuffers = config4.rightBuffers.slice(0);
1500
+ var sampleRate2 = config4.sampleRate;
1501
+ var internalInterleavedLength = config4.internalInterleavedLength;
1502
+ var desiredSampRate2 = config4.desiredSampRate;
1503
+ if (numberOfAudioChannels2 === 2) {
1504
+ leftBuffers = mergeBuffers(leftBuffers, internalInterleavedLength);
1505
+ rightBuffers = mergeBuffers(rightBuffers, internalInterleavedLength);
1506
+ if (desiredSampRate2) {
1507
+ leftBuffers = interpolateArray(leftBuffers, desiredSampRate2, sampleRate2);
1508
+ rightBuffers = interpolateArray(rightBuffers, desiredSampRate2, sampleRate2);
1509
+ }
1510
+ }
1511
+ if (numberOfAudioChannels2 === 1) {
1512
+ leftBuffers = mergeBuffers(leftBuffers, internalInterleavedLength);
1513
+ if (desiredSampRate2) {
1514
+ leftBuffers = interpolateArray(leftBuffers, desiredSampRate2, sampleRate2);
1515
+ }
1516
+ }
1517
+ if (desiredSampRate2) {
1518
+ sampleRate2 = desiredSampRate2;
1519
+ }
1520
+ function interpolateArray(data, newSampleRate, oldSampleRate) {
1521
+ var fitCount = Math.round(data.length * (newSampleRate / oldSampleRate));
1522
+ var newData = [];
1523
+ var springFactor = Number((data.length - 1) / (fitCount - 1));
1524
+ newData[0] = data[0];
1525
+ for (var i2 = 1; i2 < fitCount - 1; i2++) {
1526
+ var tmp = i2 * springFactor;
1527
+ var before = Number(Math.floor(tmp)).toFixed();
1528
+ var after = Number(Math.ceil(tmp)).toFixed();
1529
+ var atPoint = tmp - before;
1530
+ newData[i2] = linearInterpolate(data[before], data[after], atPoint);
1531
+ }
1532
+ newData[fitCount - 1] = data[data.length - 1];
1533
+ return newData;
1534
+ }
1535
+ function linearInterpolate(before, after, atPoint) {
1536
+ return before + (after - before) * atPoint;
1537
+ }
1538
+ function mergeBuffers(channelBuffer, rLength) {
1539
+ var result = new Float64Array(rLength);
1540
+ var offset = 0;
1541
+ var lng2 = channelBuffer.length;
1542
+ for (var i2 = 0; i2 < lng2; i2++) {
1543
+ var buffer2 = channelBuffer[i2];
1544
+ result.set(buffer2, offset);
1545
+ offset += buffer2.length;
1546
+ }
1547
+ return result;
1548
+ }
1549
+ function interleave(leftChannel, rightChannel) {
1550
+ var length = leftChannel.length + rightChannel.length;
1551
+ var result = new Float64Array(length);
1552
+ var inputIndex = 0;
1553
+ for (var index2 = 0; index2 < length; ) {
1554
+ result[index2++] = leftChannel[inputIndex];
1555
+ result[index2++] = rightChannel[inputIndex];
1556
+ inputIndex++;
1557
+ }
1558
+ return result;
1559
+ }
1560
+ function writeUTFBytes(view2, offset, string) {
1561
+ var lng2 = string.length;
1562
+ for (var i2 = 0; i2 < lng2; i2++) {
1563
+ view2.setUint8(offset + i2, string.charCodeAt(i2));
1564
+ }
1565
+ }
1566
+ var interleaved;
1567
+ if (numberOfAudioChannels2 === 2) {
1568
+ interleaved = interleave(leftBuffers, rightBuffers);
1569
+ }
1570
+ if (numberOfAudioChannels2 === 1) {
1571
+ interleaved = leftBuffers;
1572
+ }
1573
+ var interleavedLength = interleaved.length;
1574
+ var resultingBufferLength = 44 + interleavedLength * 2;
1575
+ var buffer = new ArrayBuffer(resultingBufferLength);
1576
+ var view = new DataView(buffer);
1577
+ writeUTFBytes(view, 0, "RIFF");
1578
+ view.setUint32(4, 36 + interleavedLength * 2, true);
1579
+ writeUTFBytes(view, 8, "WAVE");
1580
+ writeUTFBytes(view, 12, "fmt ");
1581
+ view.setUint32(16, 16, true);
1582
+ view.setUint16(20, 1, true);
1583
+ view.setUint16(22, numberOfAudioChannels2, true);
1584
+ view.setUint32(24, sampleRate2, true);
1585
+ view.setUint32(28, sampleRate2 * numberOfAudioChannels2 * 2, true);
1586
+ view.setUint16(32, numberOfAudioChannels2 * 2, true);
1587
+ view.setUint16(34, 16, true);
1588
+ writeUTFBytes(view, 36, "data");
1589
+ view.setUint32(40, interleavedLength * 2, true);
1590
+ var lng = interleavedLength;
1591
+ var index = 44;
1592
+ var volume = 1;
1593
+ for (var i = 0; i < lng; i++) {
1594
+ view.setInt16(index, interleaved[i] * (32767 * volume), true);
1595
+ index += 2;
1596
+ }
1597
+ if (cb) {
1598
+ return cb({
1599
+ buffer,
1600
+ view
1601
+ });
1602
+ }
1603
+ postMessage({
1604
+ buffer,
1605
+ view
1606
+ });
1607
+ }
1608
+ if (config3.noWorker) {
1609
+ mergeAudioBuffers(config3, function(data) {
1610
+ callback(data.buffer, data.view);
1611
+ });
1612
+ return;
1613
+ }
1614
+ var webWorker = processInWebWorker(mergeAudioBuffers);
1615
+ webWorker.onmessage = function(event) {
1616
+ callback(event.data.buffer, event.data.view);
1617
+ URL2.revokeObjectURL(webWorker.workerURL);
1618
+ webWorker.terminate();
1619
+ };
1620
+ webWorker.postMessage(config3);
1621
+ }
1622
+ function processInWebWorker(_function) {
1623
+ var workerURL = URL2.createObjectURL(new Blob([
1624
+ _function.toString(),
1625
+ ";this.onmessage = function (eee) {" + _function.name + "(eee.data);}"
1626
+ ], {
1627
+ type: "application/javascript"
1628
+ }));
1629
+ var worker = new Worker(workerURL);
1630
+ worker.workerURL = workerURL;
1631
+ return worker;
1632
+ }
1633
+ this.stop = function(callback) {
1634
+ callback = callback || function() {
1635
+ };
1636
+ recording = false;
1637
+ mergeLeftRightBuffers({
1638
+ desiredSampRate,
1639
+ sampleRate,
1640
+ numberOfAudioChannels,
1641
+ internalInterleavedLength: recordingLength,
1642
+ leftBuffers: leftchannel,
1643
+ rightBuffers: numberOfAudioChannels === 1 ? [] : rightchannel,
1644
+ noWorker: config2.noWorker
1645
+ }, function(buffer, view) {
1646
+ self2.blob = new Blob([view], {
1647
+ type: "audio/wav"
1648
+ });
1649
+ self2.buffer = new ArrayBuffer(view.buffer.byteLength);
1650
+ self2.view = view;
1651
+ self2.sampleRate = desiredSampRate || sampleRate;
1652
+ self2.bufferSize = bufferSize;
1653
+ self2.length = recordingLength;
1654
+ isAudioProcessStarted = false;
1655
+ if (callback) {
1656
+ callback(self2.blob);
1657
+ }
1658
+ });
1659
+ };
1660
+ if (typeof RecordRTC.Storage === "undefined") {
1661
+ RecordRTC.Storage = {
1662
+ AudioContextConstructor: null,
1663
+ AudioContext: window.AudioContext || window.webkitAudioContext
1664
+ };
1665
+ }
1666
+ if (!RecordRTC.Storage.AudioContextConstructor || RecordRTC.Storage.AudioContextConstructor.state === "closed") {
1667
+ RecordRTC.Storage.AudioContextConstructor = new RecordRTC.Storage.AudioContext();
1668
+ }
1669
+ var context = RecordRTC.Storage.AudioContextConstructor;
1670
+ var audioInput = context.createMediaStreamSource(mediaStream);
1671
+ var legalBufferValues = [0, 256, 512, 1024, 2048, 4096, 8192, 16384];
1672
+ var bufferSize = typeof config2.bufferSize === "undefined" ? 4096 : config2.bufferSize;
1673
+ if (legalBufferValues.indexOf(bufferSize) === -1) {
1674
+ if (!config2.disableLogs) {
1675
+ console.log("Legal values for buffer-size are " + JSON.stringify(legalBufferValues, null, " "));
1676
+ }
1677
+ }
1678
+ if (context.createJavaScriptNode) {
1679
+ jsAudioNode = context.createJavaScriptNode(bufferSize, numberOfAudioChannels, numberOfAudioChannels);
1680
+ } else if (context.createScriptProcessor) {
1681
+ jsAudioNode = context.createScriptProcessor(bufferSize, numberOfAudioChannels, numberOfAudioChannels);
1682
+ } else {
1683
+ throw "WebAudio API has no support on this browser.";
1684
+ }
1685
+ audioInput.connect(jsAudioNode);
1686
+ if (!config2.bufferSize) {
1687
+ bufferSize = jsAudioNode.bufferSize;
1688
+ }
1689
+ var sampleRate = typeof config2.sampleRate !== "undefined" ? config2.sampleRate : context.sampleRate || 44100;
1690
+ if (sampleRate < 22050 || sampleRate > 96e3) {
1691
+ if (!config2.disableLogs) {
1692
+ console.log("sample-rate must be under range 22050 and 96000.");
1693
+ }
1694
+ }
1695
+ if (!config2.disableLogs) {
1696
+ if (config2.desiredSampRate) {
1697
+ console.log("Desired sample-rate: " + config2.desiredSampRate);
1698
+ }
1699
+ }
1700
+ var isPaused = false;
1701
+ this.pause = function() {
1702
+ isPaused = true;
1703
+ };
1704
+ this.resume = function() {
1705
+ if (isMediaStreamActive() === false) {
1706
+ throw "Please make sure MediaStream is active.";
1707
+ }
1708
+ if (!recording) {
1709
+ if (!config2.disableLogs) {
1710
+ console.log("Seems recording has been restarted.");
1711
+ }
1712
+ this.record();
1713
+ return;
1714
+ }
1715
+ isPaused = false;
1716
+ };
1717
+ this.clearRecordedData = function() {
1718
+ config2.checkForInactiveTracks = false;
1719
+ if (recording) {
1720
+ this.stop(clearRecordedDataCB);
1721
+ }
1722
+ clearRecordedDataCB();
1723
+ };
1724
+ function resetVariables() {
1725
+ leftchannel = [];
1726
+ rightchannel = [];
1727
+ recordingLength = 0;
1728
+ isAudioProcessStarted = false;
1729
+ recording = false;
1730
+ isPaused = false;
1731
+ context = null;
1732
+ self2.leftchannel = leftchannel;
1733
+ self2.rightchannel = rightchannel;
1734
+ self2.numberOfAudioChannels = numberOfAudioChannels;
1735
+ self2.desiredSampRate = desiredSampRate;
1736
+ self2.sampleRate = sampleRate;
1737
+ self2.recordingLength = recordingLength;
1738
+ intervalsBasedBuffers = {
1739
+ left: [],
1740
+ right: [],
1741
+ recordingLength: 0
1742
+ };
1743
+ }
1744
+ function clearRecordedDataCB() {
1745
+ if (jsAudioNode) {
1746
+ jsAudioNode.onaudioprocess = null;
1747
+ jsAudioNode.disconnect();
1748
+ jsAudioNode = null;
1749
+ }
1750
+ if (audioInput) {
1751
+ audioInput.disconnect();
1752
+ audioInput = null;
1753
+ }
1754
+ resetVariables();
1755
+ }
1756
+ this.name = "StereoAudioRecorder";
1757
+ this.toString = function() {
1758
+ return this.name;
1759
+ };
1760
+ var isAudioProcessStarted = false;
1761
+ function onAudioProcessDataAvailable(e) {
1762
+ if (isPaused) {
1763
+ return;
1764
+ }
1765
+ if (isMediaStreamActive() === false) {
1766
+ if (!config2.disableLogs) {
1767
+ console.log("MediaStream seems stopped.");
1768
+ }
1769
+ jsAudioNode.disconnect();
1770
+ recording = false;
1771
+ }
1772
+ if (!recording) {
1773
+ if (audioInput) {
1774
+ audioInput.disconnect();
1775
+ audioInput = null;
1776
+ }
1777
+ return;
1778
+ }
1779
+ if (!isAudioProcessStarted) {
1780
+ isAudioProcessStarted = true;
1781
+ if (config2.onAudioProcessStarted) {
1782
+ config2.onAudioProcessStarted();
1783
+ }
1784
+ if (config2.initCallback) {
1785
+ config2.initCallback();
1786
+ }
1787
+ }
1788
+ var left = e.inputBuffer.getChannelData(0);
1789
+ var chLeft = new Float32Array(left);
1790
+ leftchannel.push(chLeft);
1791
+ if (numberOfAudioChannels === 2) {
1792
+ var right = e.inputBuffer.getChannelData(1);
1793
+ var chRight = new Float32Array(right);
1794
+ rightchannel.push(chRight);
1795
+ }
1796
+ recordingLength += bufferSize;
1797
+ self2.recordingLength = recordingLength;
1798
+ if (typeof config2.timeSlice !== "undefined") {
1799
+ intervalsBasedBuffers.recordingLength += bufferSize;
1800
+ intervalsBasedBuffers.left.push(chLeft);
1801
+ if (numberOfAudioChannels === 2) {
1802
+ intervalsBasedBuffers.right.push(chRight);
1803
+ }
1804
+ }
1805
+ }
1806
+ jsAudioNode.onaudioprocess = onAudioProcessDataAvailable;
1807
+ if (context.createMediaStreamDestination) {
1808
+ jsAudioNode.connect(context.createMediaStreamDestination());
1809
+ } else {
1810
+ jsAudioNode.connect(context.destination);
1811
+ }
1812
+ this.leftchannel = leftchannel;
1813
+ this.rightchannel = rightchannel;
1814
+ this.numberOfAudioChannels = numberOfAudioChannels;
1815
+ this.desiredSampRate = desiredSampRate;
1816
+ this.sampleRate = sampleRate;
1817
+ self2.recordingLength = recordingLength;
1818
+ var intervalsBasedBuffers = {
1819
+ left: [],
1820
+ right: [],
1821
+ recordingLength: 0
1822
+ };
1823
+ function looper() {
1824
+ if (!recording || typeof config2.ondataavailable !== "function" || typeof config2.timeSlice === "undefined") {
1825
+ return;
1826
+ }
1827
+ if (intervalsBasedBuffers.left.length) {
1828
+ mergeLeftRightBuffers({
1829
+ desiredSampRate,
1830
+ sampleRate,
1831
+ numberOfAudioChannels,
1832
+ internalInterleavedLength: intervalsBasedBuffers.recordingLength,
1833
+ leftBuffers: intervalsBasedBuffers.left,
1834
+ rightBuffers: numberOfAudioChannels === 1 ? [] : intervalsBasedBuffers.right
1835
+ }, function(buffer, view) {
1836
+ var blob = new Blob([view], {
1837
+ type: "audio/wav"
1838
+ });
1839
+ config2.ondataavailable(blob);
1840
+ setTimeout(looper, config2.timeSlice);
1841
+ });
1842
+ intervalsBasedBuffers = {
1843
+ left: [],
1844
+ right: [],
1845
+ recordingLength: 0
1846
+ };
1847
+ } else {
1848
+ setTimeout(looper, config2.timeSlice);
1849
+ }
1850
+ }
1851
+ }
1852
+ if (typeof RecordRTC !== "undefined") {
1853
+ RecordRTC.StereoAudioRecorder = StereoAudioRecorder;
1854
+ }
1855
+ function CanvasRecorder(htmlElement, config2) {
1856
+ if (typeof html2canvas === "undefined") {
1857
+ throw "Please link: https://www.webrtc-experiment.com/screenshot.js";
1858
+ }
1859
+ config2 = config2 || {};
1860
+ if (!config2.frameInterval) {
1861
+ config2.frameInterval = 10;
1862
+ }
1863
+ var isCanvasSupportsStreamCapturing = false;
1864
+ ["captureStream", "mozCaptureStream", "webkitCaptureStream"].forEach(function(item) {
1865
+ if (item in document.createElement("canvas")) {
1866
+ isCanvasSupportsStreamCapturing = true;
1867
+ }
1868
+ });
1869
+ var _isChrome = (!!window.webkitRTCPeerConnection || !!window.webkitGetUserMedia) && !!window.chrome;
1870
+ var chromeVersion = 50;
1871
+ var matchArray = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
1872
+ if (_isChrome && matchArray && matchArray[2]) {
1873
+ chromeVersion = parseInt(matchArray[2], 10);
1874
+ }
1875
+ if (_isChrome && chromeVersion < 52) {
1876
+ isCanvasSupportsStreamCapturing = false;
1877
+ }
1878
+ if (config2.useWhammyRecorder) {
1879
+ isCanvasSupportsStreamCapturing = false;
1880
+ }
1881
+ var globalCanvas, mediaStreamRecorder;
1882
+ if (isCanvasSupportsStreamCapturing) {
1883
+ if (!config2.disableLogs) {
1884
+ console.log("Your browser supports both MediRecorder API and canvas.captureStream!");
1885
+ }
1886
+ if (htmlElement instanceof HTMLCanvasElement) {
1887
+ globalCanvas = htmlElement;
1888
+ } else if (htmlElement instanceof CanvasRenderingContext2D) {
1889
+ globalCanvas = htmlElement.canvas;
1890
+ } else {
1891
+ throw "Please pass either HTMLCanvasElement or CanvasRenderingContext2D.";
1892
+ }
1893
+ } else if (!!navigator.mozGetUserMedia) {
1894
+ if (!config2.disableLogs) {
1895
+ console.error("Canvas recording is NOT supported in Firefox.");
1896
+ }
1897
+ }
1898
+ var isRecording;
1899
+ this.record = function() {
1900
+ isRecording = true;
1901
+ if (isCanvasSupportsStreamCapturing && !config2.useWhammyRecorder) {
1902
+ var canvasMediaStream;
1903
+ if ("captureStream" in globalCanvas) {
1904
+ canvasMediaStream = globalCanvas.captureStream(25);
1905
+ } else if ("mozCaptureStream" in globalCanvas) {
1906
+ canvasMediaStream = globalCanvas.mozCaptureStream(25);
1907
+ } else if ("webkitCaptureStream" in globalCanvas) {
1908
+ canvasMediaStream = globalCanvas.webkitCaptureStream(25);
1909
+ }
1910
+ try {
1911
+ var mdStream = new MediaStream();
1912
+ mdStream.addTrack(getTracks(canvasMediaStream, "video")[0]);
1913
+ canvasMediaStream = mdStream;
1914
+ } catch (e) {
1915
+ }
1916
+ if (!canvasMediaStream) {
1917
+ throw "captureStream API are NOT available.";
1918
+ }
1919
+ mediaStreamRecorder = new MediaStreamRecorder(canvasMediaStream, {
1920
+ mimeType: config2.mimeType || "video/webm"
1921
+ });
1922
+ mediaStreamRecorder.record();
1923
+ } else {
1924
+ whammy.frames = [];
1925
+ lastTime2 = new Date().getTime();
1926
+ drawCanvasFrame();
1927
+ }
1928
+ if (config2.initCallback) {
1929
+ config2.initCallback();
1930
+ }
1931
+ };
1932
+ this.getWebPImages = function(callback) {
1933
+ if (htmlElement.nodeName.toLowerCase() !== "canvas") {
1934
+ callback();
1935
+ return;
1936
+ }
1937
+ var framesLength = whammy.frames.length;
1938
+ whammy.frames.forEach(function(frame, idx) {
1939
+ var framesRemaining = framesLength - idx;
1940
+ if (!config2.disableLogs) {
1941
+ console.log(framesRemaining + "/" + framesLength + " frames remaining");
1942
+ }
1943
+ if (config2.onEncodingCallback) {
1944
+ config2.onEncodingCallback(framesRemaining, framesLength);
1945
+ }
1946
+ var webp = frame.image.toDataURL("image/webp", 1);
1947
+ whammy.frames[idx].image = webp;
1948
+ });
1949
+ if (!config2.disableLogs) {
1950
+ console.log("Generating WebM");
1951
+ }
1952
+ callback();
1953
+ };
1954
+ this.stop = function(callback) {
1955
+ isRecording = false;
1956
+ var that = this;
1957
+ if (isCanvasSupportsStreamCapturing && mediaStreamRecorder) {
1958
+ mediaStreamRecorder.stop(callback);
1959
+ return;
1960
+ }
1961
+ this.getWebPImages(function() {
1962
+ whammy.compile(function(blob) {
1963
+ if (!config2.disableLogs) {
1964
+ console.log("Recording finished!");
1965
+ }
1966
+ that.blob = blob;
1967
+ if (that.blob.forEach) {
1968
+ that.blob = new Blob([], {
1969
+ type: "video/webm"
1970
+ });
1971
+ }
1972
+ if (callback) {
1973
+ callback(that.blob);
1974
+ }
1975
+ whammy.frames = [];
1976
+ });
1977
+ });
1978
+ };
1979
+ var isPausedRecording = false;
1980
+ this.pause = function() {
1981
+ isPausedRecording = true;
1982
+ if (mediaStreamRecorder instanceof MediaStreamRecorder) {
1983
+ mediaStreamRecorder.pause();
1984
+ return;
1985
+ }
1986
+ };
1987
+ this.resume = function() {
1988
+ isPausedRecording = false;
1989
+ if (mediaStreamRecorder instanceof MediaStreamRecorder) {
1990
+ mediaStreamRecorder.resume();
1991
+ return;
1992
+ }
1993
+ if (!isRecording) {
1994
+ this.record();
1995
+ }
1996
+ };
1997
+ this.clearRecordedData = function() {
1998
+ if (isRecording) {
1999
+ this.stop(clearRecordedDataCB);
2000
+ }
2001
+ clearRecordedDataCB();
2002
+ };
2003
+ function clearRecordedDataCB() {
2004
+ whammy.frames = [];
2005
+ isRecording = false;
2006
+ isPausedRecording = false;
2007
+ }
2008
+ this.name = "CanvasRecorder";
2009
+ this.toString = function() {
2010
+ return this.name;
2011
+ };
2012
+ function cloneCanvas() {
2013
+ var newCanvas = document.createElement("canvas");
2014
+ var context = newCanvas.getContext("2d");
2015
+ newCanvas.width = htmlElement.width;
2016
+ newCanvas.height = htmlElement.height;
2017
+ context.drawImage(htmlElement, 0, 0);
2018
+ return newCanvas;
2019
+ }
2020
+ function drawCanvasFrame() {
2021
+ if (isPausedRecording) {
2022
+ lastTime2 = new Date().getTime();
2023
+ return setTimeout(drawCanvasFrame, 500);
2024
+ }
2025
+ if (htmlElement.nodeName.toLowerCase() === "canvas") {
2026
+ var duration = new Date().getTime() - lastTime2;
2027
+ lastTime2 = new Date().getTime();
2028
+ whammy.frames.push({
2029
+ image: cloneCanvas(),
2030
+ duration
2031
+ });
2032
+ if (isRecording) {
2033
+ setTimeout(drawCanvasFrame, config2.frameInterval);
2034
+ }
2035
+ return;
2036
+ }
2037
+ html2canvas(htmlElement, {
2038
+ grabMouse: typeof config2.showMousePointer === "undefined" || config2.showMousePointer,
2039
+ onrendered: function(canvas) {
2040
+ var duration2 = new Date().getTime() - lastTime2;
2041
+ if (!duration2) {
2042
+ return setTimeout(drawCanvasFrame, config2.frameInterval);
2043
+ }
2044
+ lastTime2 = new Date().getTime();
2045
+ whammy.frames.push({
2046
+ image: canvas.toDataURL("image/webp", 1),
2047
+ duration: duration2
2048
+ });
2049
+ if (isRecording) {
2050
+ setTimeout(drawCanvasFrame, config2.frameInterval);
2051
+ }
2052
+ }
2053
+ });
2054
+ }
2055
+ var lastTime2 = new Date().getTime();
2056
+ var whammy = new Whammy.Video(100);
2057
+ }
2058
+ if (typeof RecordRTC !== "undefined") {
2059
+ RecordRTC.CanvasRecorder = CanvasRecorder;
2060
+ }
2061
+ function WhammyRecorder(mediaStream, config2) {
2062
+ config2 = config2 || {};
2063
+ if (!config2.frameInterval) {
2064
+ config2.frameInterval = 10;
2065
+ }
2066
+ if (!config2.disableLogs) {
2067
+ console.log("Using frames-interval:", config2.frameInterval);
2068
+ }
2069
+ this.record = function() {
2070
+ if (!config2.width) {
2071
+ config2.width = 320;
2072
+ }
2073
+ if (!config2.height) {
2074
+ config2.height = 240;
2075
+ }
2076
+ if (!config2.video) {
2077
+ config2.video = {
2078
+ width: config2.width,
2079
+ height: config2.height
2080
+ };
2081
+ }
2082
+ if (!config2.canvas) {
2083
+ config2.canvas = {
2084
+ width: config2.width,
2085
+ height: config2.height
2086
+ };
2087
+ }
2088
+ canvas.width = config2.canvas.width || 320;
2089
+ canvas.height = config2.canvas.height || 240;
2090
+ context = canvas.getContext("2d");
2091
+ if (config2.video && config2.video instanceof HTMLVideoElement) {
2092
+ video = config2.video.cloneNode();
2093
+ if (config2.initCallback) {
2094
+ config2.initCallback();
2095
+ }
2096
+ } else {
2097
+ video = document.createElement("video");
2098
+ setSrcObject(mediaStream, video);
2099
+ video.onloadedmetadata = function() {
2100
+ if (config2.initCallback) {
2101
+ config2.initCallback();
2102
+ }
2103
+ };
2104
+ video.width = config2.video.width;
2105
+ video.height = config2.video.height;
2106
+ }
2107
+ video.muted = true;
2108
+ video.play();
2109
+ lastTime2 = new Date().getTime();
2110
+ whammy = new Whammy.Video();
2111
+ if (!config2.disableLogs) {
2112
+ console.log("canvas resolutions", canvas.width, "*", canvas.height);
2113
+ console.log("video width/height", video.width || canvas.width, "*", video.height || canvas.height);
2114
+ }
2115
+ drawFrames(config2.frameInterval);
2116
+ };
2117
+ function drawFrames(frameInterval) {
2118
+ frameInterval = typeof frameInterval !== "undefined" ? frameInterval : 10;
2119
+ var duration = new Date().getTime() - lastTime2;
2120
+ if (!duration) {
2121
+ return setTimeout(drawFrames, frameInterval, frameInterval);
2122
+ }
2123
+ if (isPausedRecording) {
2124
+ lastTime2 = new Date().getTime();
2125
+ return setTimeout(drawFrames, 100);
2126
+ }
2127
+ lastTime2 = new Date().getTime();
2128
+ if (video.paused) {
2129
+ video.play();
2130
+ }
2131
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
2132
+ whammy.frames.push({
2133
+ duration,
2134
+ image: canvas.toDataURL("image/webp")
2135
+ });
2136
+ if (!isStopDrawing) {
2137
+ setTimeout(drawFrames, frameInterval, frameInterval);
2138
+ }
2139
+ }
2140
+ function asyncLoop(o) {
2141
+ var i = -1, length = o.length;
2142
+ (function loop() {
2143
+ i++;
2144
+ if (i === length) {
2145
+ o.callback();
2146
+ return;
2147
+ }
2148
+ setTimeout(function() {
2149
+ o.functionToLoop(loop, i);
2150
+ }, 1);
2151
+ })();
2152
+ }
2153
+ function dropBlackFrames(_frames, _framesToCheck, _pixTolerance, _frameTolerance, callback) {
2154
+ var localCanvas = document.createElement("canvas");
2155
+ localCanvas.width = canvas.width;
2156
+ localCanvas.height = canvas.height;
2157
+ var context2d = localCanvas.getContext("2d");
2158
+ var resultFrames = [];
2159
+ var checkUntilNotBlack = _framesToCheck === -1;
2160
+ var endCheckFrame = _framesToCheck && _framesToCheck > 0 && _framesToCheck <= _frames.length ? _framesToCheck : _frames.length;
2161
+ var sampleColor = {
2162
+ r: 0,
2163
+ g: 0,
2164
+ b: 0
2165
+ };
2166
+ var maxColorDifference = Math.sqrt(Math.pow(255, 2) + Math.pow(255, 2) + Math.pow(255, 2));
2167
+ var pixTolerance = _pixTolerance && _pixTolerance >= 0 && _pixTolerance <= 1 ? _pixTolerance : 0;
2168
+ var frameTolerance = _frameTolerance && _frameTolerance >= 0 && _frameTolerance <= 1 ? _frameTolerance : 0;
2169
+ var doNotCheckNext = false;
2170
+ asyncLoop({
2171
+ length: endCheckFrame,
2172
+ functionToLoop: function(loop, f) {
2173
+ var matchPixCount, endPixCheck, maxPixCount;
2174
+ var finishImage = function() {
2175
+ if (!doNotCheckNext && maxPixCount - matchPixCount <= maxPixCount * frameTolerance) {
2176
+ } else {
2177
+ if (checkUntilNotBlack) {
2178
+ doNotCheckNext = true;
2179
+ }
2180
+ resultFrames.push(_frames[f]);
2181
+ }
2182
+ loop();
2183
+ };
2184
+ if (!doNotCheckNext) {
2185
+ var image = new Image();
2186
+ image.onload = function() {
2187
+ context2d.drawImage(image, 0, 0, canvas.width, canvas.height);
2188
+ var imageData = context2d.getImageData(0, 0, canvas.width, canvas.height);
2189
+ matchPixCount = 0;
2190
+ endPixCheck = imageData.data.length;
2191
+ maxPixCount = imageData.data.length / 4;
2192
+ for (var pix = 0; pix < endPixCheck; pix += 4) {
2193
+ var currentColor = {
2194
+ r: imageData.data[pix],
2195
+ g: imageData.data[pix + 1],
2196
+ b: imageData.data[pix + 2]
2197
+ };
2198
+ var colorDifference = Math.sqrt(Math.pow(currentColor.r - sampleColor.r, 2) + Math.pow(currentColor.g - sampleColor.g, 2) + Math.pow(currentColor.b - sampleColor.b, 2));
2199
+ if (colorDifference <= maxColorDifference * pixTolerance) {
2200
+ matchPixCount++;
2201
+ }
2202
+ }
2203
+ finishImage();
2204
+ };
2205
+ image.src = _frames[f].image;
2206
+ } else {
2207
+ finishImage();
2208
+ }
2209
+ },
2210
+ callback: function() {
2211
+ resultFrames = resultFrames.concat(_frames.slice(endCheckFrame));
2212
+ if (resultFrames.length <= 0) {
2213
+ resultFrames.push(_frames[_frames.length - 1]);
2214
+ }
2215
+ callback(resultFrames);
2216
+ }
2217
+ });
2218
+ }
2219
+ var isStopDrawing = false;
2220
+ this.stop = function(callback) {
2221
+ callback = callback || function() {
2222
+ };
2223
+ isStopDrawing = true;
2224
+ var _this = this;
2225
+ setTimeout(function() {
2226
+ dropBlackFrames(whammy.frames, -1, null, null, function(frames) {
2227
+ whammy.frames = frames;
2228
+ if (config2.advertisement && config2.advertisement.length) {
2229
+ whammy.frames = config2.advertisement.concat(whammy.frames);
2230
+ }
2231
+ whammy.compile(function(blob) {
2232
+ _this.blob = blob;
2233
+ if (_this.blob.forEach) {
2234
+ _this.blob = new Blob([], {
2235
+ type: "video/webm"
2236
+ });
2237
+ }
2238
+ if (callback) {
2239
+ callback(_this.blob);
2240
+ }
2241
+ });
2242
+ });
2243
+ }, 10);
2244
+ };
2245
+ var isPausedRecording = false;
2246
+ this.pause = function() {
2247
+ isPausedRecording = true;
2248
+ };
2249
+ this.resume = function() {
2250
+ isPausedRecording = false;
2251
+ if (isStopDrawing) {
2252
+ this.record();
2253
+ }
2254
+ };
2255
+ this.clearRecordedData = function() {
2256
+ if (!isStopDrawing) {
2257
+ this.stop(clearRecordedDataCB);
2258
+ }
2259
+ clearRecordedDataCB();
2260
+ };
2261
+ function clearRecordedDataCB() {
2262
+ whammy.frames = [];
2263
+ isStopDrawing = true;
2264
+ isPausedRecording = false;
2265
+ }
2266
+ this.name = "WhammyRecorder";
2267
+ this.toString = function() {
2268
+ return this.name;
2269
+ };
2270
+ var canvas = document.createElement("canvas");
2271
+ var context = canvas.getContext("2d");
2272
+ var video;
2273
+ var lastTime2;
2274
+ var whammy;
2275
+ }
2276
+ if (typeof RecordRTC !== "undefined") {
2277
+ RecordRTC.WhammyRecorder = WhammyRecorder;
2278
+ }
2279
+ var Whammy = function() {
2280
+ function WhammyVideo(duration) {
2281
+ this.frames = [];
2282
+ this.duration = duration || 1;
2283
+ this.quality = 0.8;
2284
+ }
2285
+ WhammyVideo.prototype.add = function(frame, duration) {
2286
+ if ("canvas" in frame) {
2287
+ frame = frame.canvas;
2288
+ }
2289
+ if ("toDataURL" in frame) {
2290
+ frame = frame.toDataURL("image/webp", this.quality);
2291
+ }
2292
+ if (!/^data:image\/webp;base64,/ig.test(frame)) {
2293
+ throw "Input must be formatted properly as a base64 encoded DataURI of type image/webp";
2294
+ }
2295
+ this.frames.push({
2296
+ image: frame,
2297
+ duration: duration || this.duration
2298
+ });
2299
+ };
2300
+ function processInWebWorker(_function) {
2301
+ var blob = URL2.createObjectURL(new Blob([
2302
+ _function.toString(),
2303
+ "this.onmessage = function (eee) {" + _function.name + "(eee.data);}"
2304
+ ], {
2305
+ type: "application/javascript"
2306
+ }));
2307
+ var worker = new Worker(blob);
2308
+ URL2.revokeObjectURL(blob);
2309
+ return worker;
2310
+ }
2311
+ function whammyInWebWorker(frames) {
2312
+ function ArrayToWebM(frames2) {
2313
+ var info = checkFrames(frames2);
2314
+ if (!info) {
2315
+ return [];
2316
+ }
2317
+ var clusterMaxDuration = 3e4;
2318
+ var EBML2 = [{
2319
+ "id": 440786851,
2320
+ "data": [{
2321
+ "data": 1,
2322
+ "id": 17030
2323
+ }, {
2324
+ "data": 1,
2325
+ "id": 17143
2326
+ }, {
2327
+ "data": 4,
2328
+ "id": 17138
2329
+ }, {
2330
+ "data": 8,
2331
+ "id": 17139
2332
+ }, {
2333
+ "data": "webm",
2334
+ "id": 17026
2335
+ }, {
2336
+ "data": 2,
2337
+ "id": 17031
2338
+ }, {
2339
+ "data": 2,
2340
+ "id": 17029
2341
+ }]
2342
+ }, {
2343
+ "id": 408125543,
2344
+ "data": [{
2345
+ "id": 357149030,
2346
+ "data": [{
2347
+ "data": 1e6,
2348
+ "id": 2807729
2349
+ }, {
2350
+ "data": "whammy",
2351
+ "id": 19840
2352
+ }, {
2353
+ "data": "whammy",
2354
+ "id": 22337
2355
+ }, {
2356
+ "data": doubleToString(info.duration),
2357
+ "id": 17545
2358
+ }]
2359
+ }, {
2360
+ "id": 374648427,
2361
+ "data": [{
2362
+ "id": 174,
2363
+ "data": [{
2364
+ "data": 1,
2365
+ "id": 215
2366
+ }, {
2367
+ "data": 1,
2368
+ "id": 29637
2369
+ }, {
2370
+ "data": 0,
2371
+ "id": 156
2372
+ }, {
2373
+ "data": "und",
2374
+ "id": 2274716
2375
+ }, {
2376
+ "data": "V_VP8",
2377
+ "id": 134
2378
+ }, {
2379
+ "data": "VP8",
2380
+ "id": 2459272
2381
+ }, {
2382
+ "data": 1,
2383
+ "id": 131
2384
+ }, {
2385
+ "id": 224,
2386
+ "data": [{
2387
+ "data": info.width,
2388
+ "id": 176
2389
+ }, {
2390
+ "data": info.height,
2391
+ "id": 186
2392
+ }]
2393
+ }]
2394
+ }]
2395
+ }]
2396
+ }];
2397
+ var frameNumber = 0;
2398
+ var clusterTimecode = 0;
2399
+ while (frameNumber < frames2.length) {
2400
+ var clusterFrames = [];
2401
+ var clusterDuration = 0;
2402
+ do {
2403
+ clusterFrames.push(frames2[frameNumber]);
2404
+ clusterDuration += frames2[frameNumber].duration;
2405
+ frameNumber++;
2406
+ } while (frameNumber < frames2.length && clusterDuration < clusterMaxDuration);
2407
+ var clusterCounter = 0;
2408
+ var cluster = {
2409
+ "id": 524531317,
2410
+ "data": getClusterData(clusterTimecode, clusterCounter, clusterFrames)
2411
+ };
2412
+ EBML2[1].data.push(cluster);
2413
+ clusterTimecode += clusterDuration;
2414
+ }
2415
+ return generateEBML(EBML2);
2416
+ }
2417
+ function getClusterData(clusterTimecode, clusterCounter, clusterFrames) {
2418
+ return [{
2419
+ "data": clusterTimecode,
2420
+ "id": 231
2421
+ }].concat(clusterFrames.map(function(webp) {
2422
+ var block = makeSimpleBlock({
2423
+ discardable: 0,
2424
+ frame: webp.data.slice(4),
2425
+ invisible: 0,
2426
+ keyframe: 1,
2427
+ lacing: 0,
2428
+ trackNum: 1,
2429
+ timecode: Math.round(clusterCounter)
2430
+ });
2431
+ clusterCounter += webp.duration;
2432
+ return {
2433
+ data: block,
2434
+ id: 163
2435
+ };
2436
+ }));
2437
+ }
2438
+ function checkFrames(frames2) {
2439
+ if (!frames2[0]) {
2440
+ postMessage({
2441
+ error: "Something went wrong. Maybe WebP format is not supported in the current browser."
2442
+ });
2443
+ return;
2444
+ }
2445
+ var width = frames2[0].width, height = frames2[0].height, duration = frames2[0].duration;
2446
+ for (var i = 1; i < frames2.length; i++) {
2447
+ duration += frames2[i].duration;
2448
+ }
2449
+ return {
2450
+ duration,
2451
+ width,
2452
+ height
2453
+ };
2454
+ }
2455
+ function numToBuffer(num) {
2456
+ var parts = [];
2457
+ while (num > 0) {
2458
+ parts.push(num & 255);
2459
+ num = num >> 8;
2460
+ }
2461
+ return new Uint8Array(parts.reverse());
2462
+ }
2463
+ function strToBuffer(str) {
2464
+ return new Uint8Array(str.split("").map(function(e) {
2465
+ return e.charCodeAt(0);
2466
+ }));
2467
+ }
2468
+ function bitsToBuffer(bits) {
2469
+ var data = [];
2470
+ var pad = bits.length % 8 ? new Array(1 + 8 - bits.length % 8).join("0") : "";
2471
+ bits = pad + bits;
2472
+ for (var i = 0; i < bits.length; i += 8) {
2473
+ data.push(parseInt(bits.substr(i, 8), 2));
2474
+ }
2475
+ return new Uint8Array(data);
2476
+ }
2477
+ function generateEBML(json) {
2478
+ var ebml = [];
2479
+ for (var i = 0; i < json.length; i++) {
2480
+ var data = json[i].data;
2481
+ if (typeof data === "object") {
2482
+ data = generateEBML(data);
2483
+ }
2484
+ if (typeof data === "number") {
2485
+ data = bitsToBuffer(data.toString(2));
2486
+ }
2487
+ if (typeof data === "string") {
2488
+ data = strToBuffer(data);
2489
+ }
2490
+ var len = data.size || data.byteLength || data.length;
2491
+ var zeroes = Math.ceil(Math.ceil(Math.log(len) / Math.log(2)) / 8);
2492
+ var sizeToString = len.toString(2);
2493
+ var padded = new Array(zeroes * 7 + 7 + 1 - sizeToString.length).join("0") + sizeToString;
2494
+ var size = new Array(zeroes).join("0") + "1" + padded;
2495
+ ebml.push(numToBuffer(json[i].id));
2496
+ ebml.push(bitsToBuffer(size));
2497
+ ebml.push(data);
2498
+ }
2499
+ return new Blob(ebml, {
2500
+ type: "video/webm"
2501
+ });
2502
+ }
2503
+ function toBinStrOld(bits) {
2504
+ var data = "";
2505
+ var pad = bits.length % 8 ? new Array(1 + 8 - bits.length % 8).join("0") : "";
2506
+ bits = pad + bits;
2507
+ for (var i = 0; i < bits.length; i += 8) {
2508
+ data += String.fromCharCode(parseInt(bits.substr(i, 8), 2));
2509
+ }
2510
+ return data;
2511
+ }
2512
+ function makeSimpleBlock(data) {
2513
+ var flags = 0;
2514
+ if (data.keyframe) {
2515
+ flags |= 128;
2516
+ }
2517
+ if (data.invisible) {
2518
+ flags |= 8;
2519
+ }
2520
+ if (data.lacing) {
2521
+ flags |= data.lacing << 1;
2522
+ }
2523
+ if (data.discardable) {
2524
+ flags |= 1;
2525
+ }
2526
+ if (data.trackNum > 127) {
2527
+ throw "TrackNumber > 127 not supported";
2528
+ }
2529
+ var out = [data.trackNum | 128, data.timecode >> 8, data.timecode & 255, flags].map(function(e) {
2530
+ return String.fromCharCode(e);
2531
+ }).join("") + data.frame;
2532
+ return out;
2533
+ }
2534
+ function parseWebP(riff) {
2535
+ var VP8 = riff.RIFF[0].WEBP[0];
2536
+ var frameStart = VP8.indexOf("\x9D*");
2537
+ for (var i = 0, c = []; i < 4; i++) {
2538
+ c[i] = VP8.charCodeAt(frameStart + 3 + i);
2539
+ }
2540
+ var width, height, tmp;
2541
+ tmp = c[1] << 8 | c[0];
2542
+ width = tmp & 16383;
2543
+ tmp = c[3] << 8 | c[2];
2544
+ height = tmp & 16383;
2545
+ return {
2546
+ width,
2547
+ height,
2548
+ data: VP8,
2549
+ riff
2550
+ };
2551
+ }
2552
+ function getStrLength(string, offset) {
2553
+ return parseInt(string.substr(offset + 4, 4).split("").map(function(i) {
2554
+ var unpadded = i.charCodeAt(0).toString(2);
2555
+ return new Array(8 - unpadded.length + 1).join("0") + unpadded;
2556
+ }).join(""), 2);
2557
+ }
2558
+ function parseRIFF(string) {
2559
+ var offset = 0;
2560
+ var chunks = {};
2561
+ while (offset < string.length) {
2562
+ var id = string.substr(offset, 4);
2563
+ var len = getStrLength(string, offset);
2564
+ var data = string.substr(offset + 4 + 4, len);
2565
+ offset += 4 + 4 + len;
2566
+ chunks[id] = chunks[id] || [];
2567
+ if (id === "RIFF" || id === "LIST") {
2568
+ chunks[id].push(parseRIFF(data));
2569
+ } else {
2570
+ chunks[id].push(data);
2571
+ }
2572
+ }
2573
+ return chunks;
2574
+ }
2575
+ function doubleToString(num) {
2576
+ return [].slice.call(new Uint8Array(new Float64Array([num]).buffer), 0).map(function(e) {
2577
+ return String.fromCharCode(e);
2578
+ }).reverse().join("");
2579
+ }
2580
+ var webm = new ArrayToWebM(frames.map(function(frame) {
2581
+ var webp = parseWebP(parseRIFF(atob(frame.image.slice(23))));
2582
+ webp.duration = frame.duration;
2583
+ return webp;
2584
+ }));
2585
+ postMessage(webm);
2586
+ }
2587
+ WhammyVideo.prototype.compile = function(callback) {
2588
+ var webWorker = processInWebWorker(whammyInWebWorker);
2589
+ webWorker.onmessage = function(event) {
2590
+ if (event.data.error) {
2591
+ console.error(event.data.error);
2592
+ return;
2593
+ }
2594
+ callback(event.data);
2595
+ };
2596
+ webWorker.postMessage(this.frames);
2597
+ };
2598
+ return {
2599
+ Video: WhammyVideo
2600
+ };
2601
+ }();
2602
+ if (typeof RecordRTC !== "undefined") {
2603
+ RecordRTC.Whammy = Whammy;
2604
+ }
2605
+ var DiskStorage = {
2606
+ init: function() {
2607
+ var self2 = this;
2608
+ if (typeof indexedDB === "undefined" || typeof indexedDB.open === "undefined") {
2609
+ console.error("IndexedDB API are not available in this browser.");
2610
+ return;
2611
+ }
2612
+ var dbVersion = 1;
2613
+ var dbName = this.dbName || location.href.replace(/\/|:|#|%|\.|\[|\]/g, ""), db;
2614
+ var request = indexedDB.open(dbName, dbVersion);
2615
+ function createObjectStore(dataBase) {
2616
+ dataBase.createObjectStore(self2.dataStoreName);
2617
+ }
2618
+ function putInDB() {
2619
+ var transaction = db.transaction([self2.dataStoreName], "readwrite");
2620
+ if (self2.videoBlob) {
2621
+ transaction.objectStore(self2.dataStoreName).put(self2.videoBlob, "videoBlob");
2622
+ }
2623
+ if (self2.gifBlob) {
2624
+ transaction.objectStore(self2.dataStoreName).put(self2.gifBlob, "gifBlob");
2625
+ }
2626
+ if (self2.audioBlob) {
2627
+ transaction.objectStore(self2.dataStoreName).put(self2.audioBlob, "audioBlob");
2628
+ }
2629
+ function getFromStore(portionName) {
2630
+ transaction.objectStore(self2.dataStoreName).get(portionName).onsuccess = function(event) {
2631
+ if (self2.callback) {
2632
+ self2.callback(event.target.result, portionName);
2633
+ }
2634
+ };
2635
+ }
2636
+ getFromStore("audioBlob");
2637
+ getFromStore("videoBlob");
2638
+ getFromStore("gifBlob");
2639
+ }
2640
+ request.onerror = self2.onError;
2641
+ request.onsuccess = function() {
2642
+ db = request.result;
2643
+ db.onerror = self2.onError;
2644
+ if (db.setVersion) {
2645
+ if (db.version !== dbVersion) {
2646
+ var setVersion = db.setVersion(dbVersion);
2647
+ setVersion.onsuccess = function() {
2648
+ createObjectStore(db);
2649
+ putInDB();
2650
+ };
2651
+ } else {
2652
+ putInDB();
2653
+ }
2654
+ } else {
2655
+ putInDB();
2656
+ }
2657
+ };
2658
+ request.onupgradeneeded = function(event) {
2659
+ createObjectStore(event.target.result);
2660
+ };
2661
+ },
2662
+ Fetch: function(callback) {
2663
+ this.callback = callback;
2664
+ this.init();
2665
+ return this;
2666
+ },
2667
+ Store: function(config2) {
2668
+ this.audioBlob = config2.audioBlob;
2669
+ this.videoBlob = config2.videoBlob;
2670
+ this.gifBlob = config2.gifBlob;
2671
+ this.init();
2672
+ return this;
2673
+ },
2674
+ onError: function(error) {
2675
+ console.error(JSON.stringify(error, null, " "));
2676
+ },
2677
+ dataStoreName: "recordRTC",
2678
+ dbName: null
2679
+ };
2680
+ if (typeof RecordRTC !== "undefined") {
2681
+ RecordRTC.DiskStorage = DiskStorage;
2682
+ }
2683
+ function GifRecorder(mediaStream, config2) {
2684
+ if (typeof GIFEncoder === "undefined") {
2685
+ var script = document.createElement("script");
2686
+ script.src = "https://www.webrtc-experiment.com/gif-recorder.js";
2687
+ (document.body || document.documentElement).appendChild(script);
2688
+ }
2689
+ config2 = config2 || {};
2690
+ var isHTMLObject = mediaStream instanceof CanvasRenderingContext2D || mediaStream instanceof HTMLCanvasElement;
2691
+ this.record = function() {
2692
+ if (typeof GIFEncoder === "undefined") {
2693
+ setTimeout(self2.record, 1e3);
2694
+ return;
2695
+ }
2696
+ if (!isLoadedMetaData) {
2697
+ setTimeout(self2.record, 1e3);
2698
+ return;
2699
+ }
2700
+ if (!isHTMLObject) {
2701
+ if (!config2.width) {
2702
+ config2.width = video.offsetWidth || 320;
2703
+ }
2704
+ if (!config2.height) {
2705
+ config2.height = video.offsetHeight || 240;
2706
+ }
2707
+ if (!config2.video) {
2708
+ config2.video = {
2709
+ width: config2.width,
2710
+ height: config2.height
2711
+ };
2712
+ }
2713
+ if (!config2.canvas) {
2714
+ config2.canvas = {
2715
+ width: config2.width,
2716
+ height: config2.height
2717
+ };
2718
+ }
2719
+ canvas.width = config2.canvas.width || 320;
2720
+ canvas.height = config2.canvas.height || 240;
2721
+ video.width = config2.video.width || 320;
2722
+ video.height = config2.video.height || 240;
2723
+ }
2724
+ gifEncoder = new GIFEncoder();
2725
+ gifEncoder.setRepeat(0);
2726
+ gifEncoder.setDelay(config2.frameRate || 200);
2727
+ gifEncoder.setQuality(config2.quality || 10);
2728
+ gifEncoder.start();
2729
+ if (typeof config2.onGifRecordingStarted === "function") {
2730
+ config2.onGifRecordingStarted();
2731
+ }
2732
+ startTime = Date.now();
2733
+ function drawVideoFrame(time) {
2734
+ if (self2.clearedRecordedData === true) {
2735
+ return;
2736
+ }
2737
+ if (isPausedRecording) {
2738
+ return setTimeout(function() {
2739
+ drawVideoFrame(time);
2740
+ }, 100);
2741
+ }
2742
+ lastAnimationFrame = requestAnimationFrame(drawVideoFrame);
2743
+ if (typeof lastFrameTime === void 0) {
2744
+ lastFrameTime = time;
2745
+ }
2746
+ if (time - lastFrameTime < 90) {
2747
+ return;
2748
+ }
2749
+ if (!isHTMLObject && video.paused) {
2750
+ video.play();
2751
+ }
2752
+ if (!isHTMLObject) {
2753
+ context.drawImage(video, 0, 0, canvas.width, canvas.height);
2754
+ }
2755
+ if (config2.onGifPreview) {
2756
+ config2.onGifPreview(canvas.toDataURL("image/png"));
2757
+ }
2758
+ gifEncoder.addFrame(context);
2759
+ lastFrameTime = time;
2760
+ }
2761
+ lastAnimationFrame = requestAnimationFrame(drawVideoFrame);
2762
+ if (config2.initCallback) {
2763
+ config2.initCallback();
2764
+ }
2765
+ };
2766
+ this.stop = function(callback) {
2767
+ callback = callback || function() {
2768
+ };
2769
+ if (lastAnimationFrame) {
2770
+ cancelAnimationFrame(lastAnimationFrame);
2771
+ }
2772
+ endTime = Date.now();
2773
+ this.blob = new Blob([new Uint8Array(gifEncoder.stream().bin)], {
2774
+ type: "image/gif"
2775
+ });
2776
+ callback(this.blob);
2777
+ gifEncoder.stream().bin = [];
2778
+ };
2779
+ var isPausedRecording = false;
2780
+ this.pause = function() {
2781
+ isPausedRecording = true;
2782
+ };
2783
+ this.resume = function() {
2784
+ isPausedRecording = false;
2785
+ };
2786
+ this.clearRecordedData = function() {
2787
+ self2.clearedRecordedData = true;
2788
+ clearRecordedDataCB();
2789
+ };
2790
+ function clearRecordedDataCB() {
2791
+ if (gifEncoder) {
2792
+ gifEncoder.stream().bin = [];
2793
+ }
2794
+ }
2795
+ this.name = "GifRecorder";
2796
+ this.toString = function() {
2797
+ return this.name;
2798
+ };
2799
+ var canvas = document.createElement("canvas");
2800
+ var context = canvas.getContext("2d");
2801
+ if (isHTMLObject) {
2802
+ if (mediaStream instanceof CanvasRenderingContext2D) {
2803
+ context = mediaStream;
2804
+ canvas = context.canvas;
2805
+ } else if (mediaStream instanceof HTMLCanvasElement) {
2806
+ context = mediaStream.getContext("2d");
2807
+ canvas = mediaStream;
2808
+ }
2809
+ }
2810
+ var isLoadedMetaData = true;
2811
+ if (!isHTMLObject) {
2812
+ var video = document.createElement("video");
2813
+ video.muted = true;
2814
+ video.autoplay = true;
2815
+ video.playsInline = true;
2816
+ isLoadedMetaData = false;
2817
+ video.onloadedmetadata = function() {
2818
+ isLoadedMetaData = true;
2819
+ };
2820
+ setSrcObject(mediaStream, video);
2821
+ video.play();
2822
+ }
2823
+ var lastAnimationFrame = null;
2824
+ var startTime, endTime, lastFrameTime;
2825
+ var gifEncoder;
2826
+ var self2 = this;
2827
+ }
2828
+ if (typeof RecordRTC !== "undefined") {
2829
+ RecordRTC.GifRecorder = GifRecorder;
2830
+ }
2831
+ function MultiStreamsMixer(arrayOfMediaStreams, elementClass) {
2832
+ var browserFakeUserAgent2 = "Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45";
2833
+ (function(that) {
2834
+ if (typeof RecordRTC !== "undefined") {
2835
+ return;
2836
+ }
2837
+ if (!that) {
2838
+ return;
2839
+ }
2840
+ if (typeof window !== "undefined") {
2841
+ return;
2842
+ }
2843
+ if (typeof global === "undefined") {
2844
+ return;
2845
+ }
2846
+ global.navigator = {
2847
+ userAgent: browserFakeUserAgent2,
2848
+ getUserMedia: function() {
2849
+ }
2850
+ };
2851
+ if (!global.console) {
2852
+ global.console = {};
2853
+ }
2854
+ if (typeof global.console.log === "undefined" || typeof global.console.error === "undefined") {
2855
+ global.console.error = global.console.log = global.console.log || function() {
2856
+ console.log(arguments);
2857
+ };
2858
+ }
2859
+ if (typeof document === "undefined") {
2860
+ that.document = {
2861
+ documentElement: {
2862
+ appendChild: function() {
2863
+ return "";
2864
+ }
2865
+ }
2866
+ };
2867
+ document.createElement = document.captureStream = document.mozCaptureStream = function() {
2868
+ var obj = {
2869
+ getContext: function() {
2870
+ return obj;
2871
+ },
2872
+ play: function() {
2873
+ },
2874
+ pause: function() {
2875
+ },
2876
+ drawImage: function() {
2877
+ },
2878
+ toDataURL: function() {
2879
+ return "";
2880
+ },
2881
+ style: {}
2882
+ };
2883
+ return obj;
2884
+ };
2885
+ that.HTMLVideoElement = function() {
2886
+ };
2887
+ }
2888
+ if (typeof location === "undefined") {
2889
+ that.location = {
2890
+ protocol: "file:",
2891
+ href: "",
2892
+ hash: ""
2893
+ };
2894
+ }
2895
+ if (typeof screen === "undefined") {
2896
+ that.screen = {
2897
+ width: 0,
2898
+ height: 0
2899
+ };
2900
+ }
2901
+ if (typeof URL3 === "undefined") {
2902
+ that.URL = {
2903
+ createObjectURL: function() {
2904
+ return "";
2905
+ },
2906
+ revokeObjectURL: function() {
2907
+ return "";
2908
+ }
2909
+ };
2910
+ }
2911
+ that.window = global;
2912
+ })(typeof global !== "undefined" ? global : null);
2913
+ elementClass = elementClass || "multi-streams-mixer";
2914
+ var videos = [];
2915
+ var isStopDrawingFrames = false;
2916
+ var canvas = document.createElement("canvas");
2917
+ var context = canvas.getContext("2d");
2918
+ canvas.style.opacity = 0;
2919
+ canvas.style.position = "absolute";
2920
+ canvas.style.zIndex = -1;
2921
+ canvas.style.top = "-1000em";
2922
+ canvas.style.left = "-1000em";
2923
+ canvas.className = elementClass;
2924
+ (document.body || document.documentElement).appendChild(canvas);
2925
+ this.disableLogs = false;
2926
+ this.frameInterval = 10;
2927
+ this.width = 360;
2928
+ this.height = 240;
2929
+ this.useGainNode = true;
2930
+ var self2 = this;
2931
+ var AudioContext2 = window.AudioContext;
2932
+ if (typeof AudioContext2 === "undefined") {
2933
+ if (typeof webkitAudioContext !== "undefined") {
2934
+ AudioContext2 = webkitAudioContext;
2935
+ }
2936
+ if (typeof mozAudioContext !== "undefined") {
2937
+ AudioContext2 = mozAudioContext;
2938
+ }
2939
+ }
2940
+ var URL3 = window.URL;
2941
+ if (typeof URL3 === "undefined" && typeof webkitURL !== "undefined") {
2942
+ URL3 = webkitURL;
2943
+ }
2944
+ if (typeof navigator !== "undefined" && typeof navigator.getUserMedia === "undefined") {
2945
+ if (typeof navigator.webkitGetUserMedia !== "undefined") {
2946
+ navigator.getUserMedia = navigator.webkitGetUserMedia;
2947
+ }
2948
+ if (typeof navigator.mozGetUserMedia !== "undefined") {
2949
+ navigator.getUserMedia = navigator.mozGetUserMedia;
2950
+ }
2951
+ }
2952
+ var MediaStream2 = window.MediaStream;
2953
+ if (typeof MediaStream2 === "undefined" && typeof webkitMediaStream !== "undefined") {
2954
+ MediaStream2 = webkitMediaStream;
2955
+ }
2956
+ if (typeof MediaStream2 !== "undefined") {
2957
+ if (typeof MediaStream2.prototype.stop === "undefined") {
2958
+ MediaStream2.prototype.stop = function() {
2959
+ this.getTracks().forEach(function(track) {
2960
+ track.stop();
2961
+ });
2962
+ };
2963
+ }
2964
+ }
2965
+ var Storage2 = {};
2966
+ if (typeof AudioContext2 !== "undefined") {
2967
+ Storage2.AudioContext = AudioContext2;
2968
+ } else if (typeof webkitAudioContext !== "undefined") {
2969
+ Storage2.AudioContext = webkitAudioContext;
2970
+ }
2971
+ function setSrcObject2(stream, element) {
2972
+ if ("srcObject" in element) {
2973
+ element.srcObject = stream;
2974
+ } else if ("mozSrcObject" in element) {
2975
+ element.mozSrcObject = stream;
2976
+ } else {
2977
+ element.srcObject = stream;
2978
+ }
2979
+ }
2980
+ this.startDrawingFrames = function() {
2981
+ drawVideosToCanvas();
2982
+ };
2983
+ function drawVideosToCanvas() {
2984
+ if (isStopDrawingFrames) {
2985
+ return;
2986
+ }
2987
+ var videosLength = videos.length;
2988
+ var fullcanvas = false;
2989
+ var remaining = [];
2990
+ videos.forEach(function(video) {
2991
+ if (!video.stream) {
2992
+ video.stream = {};
2993
+ }
2994
+ if (video.stream.fullcanvas) {
2995
+ fullcanvas = video;
2996
+ } else {
2997
+ remaining.push(video);
2998
+ }
2999
+ });
3000
+ if (fullcanvas) {
3001
+ canvas.width = fullcanvas.stream.width;
3002
+ canvas.height = fullcanvas.stream.height;
3003
+ } else if (remaining.length) {
3004
+ canvas.width = videosLength > 1 ? remaining[0].width * 2 : remaining[0].width;
3005
+ var height = 1;
3006
+ if (videosLength === 3 || videosLength === 4) {
3007
+ height = 2;
3008
+ }
3009
+ if (videosLength === 5 || videosLength === 6) {
3010
+ height = 3;
3011
+ }
3012
+ if (videosLength === 7 || videosLength === 8) {
3013
+ height = 4;
3014
+ }
3015
+ if (videosLength === 9 || videosLength === 10) {
3016
+ height = 5;
3017
+ }
3018
+ canvas.height = remaining[0].height * height;
3019
+ } else {
3020
+ canvas.width = self2.width || 360;
3021
+ canvas.height = self2.height || 240;
3022
+ }
3023
+ if (fullcanvas && fullcanvas instanceof HTMLVideoElement) {
3024
+ drawImage(fullcanvas);
3025
+ }
3026
+ remaining.forEach(function(video, idx) {
3027
+ drawImage(video, idx);
3028
+ });
3029
+ setTimeout(drawVideosToCanvas, self2.frameInterval);
3030
+ }
3031
+ function drawImage(video, idx) {
3032
+ if (isStopDrawingFrames) {
3033
+ return;
3034
+ }
3035
+ var x = 0;
3036
+ var y = 0;
3037
+ var width = video.width;
3038
+ var height = video.height;
3039
+ if (idx === 1) {
3040
+ x = video.width;
3041
+ }
3042
+ if (idx === 2) {
3043
+ y = video.height;
3044
+ }
3045
+ if (idx === 3) {
3046
+ x = video.width;
3047
+ y = video.height;
3048
+ }
3049
+ if (idx === 4) {
3050
+ y = video.height * 2;
3051
+ }
3052
+ if (idx === 5) {
3053
+ x = video.width;
3054
+ y = video.height * 2;
3055
+ }
3056
+ if (idx === 6) {
3057
+ y = video.height * 3;
3058
+ }
3059
+ if (idx === 7) {
3060
+ x = video.width;
3061
+ y = video.height * 3;
3062
+ }
3063
+ if (typeof video.stream.left !== "undefined") {
3064
+ x = video.stream.left;
3065
+ }
3066
+ if (typeof video.stream.top !== "undefined") {
3067
+ y = video.stream.top;
3068
+ }
3069
+ if (typeof video.stream.width !== "undefined") {
3070
+ width = video.stream.width;
3071
+ }
3072
+ if (typeof video.stream.height !== "undefined") {
3073
+ height = video.stream.height;
3074
+ }
3075
+ context.drawImage(video, x, y, width, height);
3076
+ if (typeof video.stream.onRender === "function") {
3077
+ video.stream.onRender(context, x, y, width, height, idx);
3078
+ }
3079
+ }
3080
+ function getMixedStream() {
3081
+ isStopDrawingFrames = false;
3082
+ var mixedVideoStream = getMixedVideoStream();
3083
+ var mixedAudioStream = getMixedAudioStream();
3084
+ if (mixedAudioStream) {
3085
+ mixedAudioStream.getTracks().filter(function(t) {
3086
+ return t.kind === "audio";
3087
+ }).forEach(function(track) {
3088
+ mixedVideoStream.addTrack(track);
3089
+ });
3090
+ }
3091
+ var fullcanvas;
3092
+ arrayOfMediaStreams.forEach(function(stream) {
3093
+ if (stream.fullcanvas) {
3094
+ fullcanvas = true;
3095
+ }
3096
+ });
3097
+ return mixedVideoStream;
3098
+ }
3099
+ function getMixedVideoStream() {
3100
+ resetVideoStreams();
3101
+ var capturedStream;
3102
+ if ("captureStream" in canvas) {
3103
+ capturedStream = canvas.captureStream();
3104
+ } else if ("mozCaptureStream" in canvas) {
3105
+ capturedStream = canvas.mozCaptureStream();
3106
+ } else if (!self2.disableLogs) {
3107
+ console.error("Upgrade to latest Chrome or otherwise enable this flag: chrome://flags/#enable-experimental-web-platform-features");
3108
+ }
3109
+ var videoStream = new MediaStream2();
3110
+ capturedStream.getTracks().filter(function(t) {
3111
+ return t.kind === "video";
3112
+ }).forEach(function(track) {
3113
+ videoStream.addTrack(track);
3114
+ });
3115
+ canvas.stream = videoStream;
3116
+ return videoStream;
3117
+ }
3118
+ function getMixedAudioStream() {
3119
+ if (!Storage2.AudioContextConstructor) {
3120
+ Storage2.AudioContextConstructor = new Storage2.AudioContext();
3121
+ }
3122
+ self2.audioContext = Storage2.AudioContextConstructor;
3123
+ self2.audioSources = [];
3124
+ if (self2.useGainNode === true) {
3125
+ self2.gainNode = self2.audioContext.createGain();
3126
+ self2.gainNode.connect(self2.audioContext.destination);
3127
+ self2.gainNode.gain.value = 0;
3128
+ }
3129
+ var audioTracksLength = 0;
3130
+ arrayOfMediaStreams.forEach(function(stream) {
3131
+ if (!stream.getTracks().filter(function(t) {
3132
+ return t.kind === "audio";
3133
+ }).length) {
3134
+ return;
3135
+ }
3136
+ audioTracksLength++;
3137
+ var audioSource = self2.audioContext.createMediaStreamSource(stream);
3138
+ if (self2.useGainNode === true) {
3139
+ audioSource.connect(self2.gainNode);
3140
+ }
3141
+ self2.audioSources.push(audioSource);
3142
+ });
3143
+ if (!audioTracksLength) {
3144
+ return;
3145
+ }
3146
+ self2.audioDestination = self2.audioContext.createMediaStreamDestination();
3147
+ self2.audioSources.forEach(function(audioSource) {
3148
+ audioSource.connect(self2.audioDestination);
3149
+ });
3150
+ return self2.audioDestination.stream;
3151
+ }
3152
+ function getVideo(stream) {
3153
+ var video = document.createElement("video");
3154
+ setSrcObject2(stream, video);
3155
+ video.className = elementClass;
3156
+ video.muted = true;
3157
+ video.volume = 0;
3158
+ video.width = stream.width || self2.width || 360;
3159
+ video.height = stream.height || self2.height || 240;
3160
+ video.play();
3161
+ return video;
3162
+ }
3163
+ this.appendStreams = function(streams) {
3164
+ if (!streams) {
3165
+ throw "First parameter is required.";
3166
+ }
3167
+ if (!(streams instanceof Array)) {
3168
+ streams = [streams];
3169
+ }
3170
+ streams.forEach(function(stream) {
3171
+ var newStream = new MediaStream2();
3172
+ if (stream.getTracks().filter(function(t) {
3173
+ return t.kind === "video";
3174
+ }).length) {
3175
+ var video = getVideo(stream);
3176
+ video.stream = stream;
3177
+ videos.push(video);
3178
+ newStream.addTrack(stream.getTracks().filter(function(t) {
3179
+ return t.kind === "video";
3180
+ })[0]);
3181
+ }
3182
+ if (stream.getTracks().filter(function(t) {
3183
+ return t.kind === "audio";
3184
+ }).length) {
3185
+ var audioSource = self2.audioContext.createMediaStreamSource(stream);
3186
+ self2.audioDestination = self2.audioContext.createMediaStreamDestination();
3187
+ audioSource.connect(self2.audioDestination);
3188
+ newStream.addTrack(self2.audioDestination.stream.getTracks().filter(function(t) {
3189
+ return t.kind === "audio";
3190
+ })[0]);
3191
+ }
3192
+ arrayOfMediaStreams.push(newStream);
3193
+ });
3194
+ };
3195
+ this.releaseStreams = function() {
3196
+ videos = [];
3197
+ isStopDrawingFrames = true;
3198
+ if (self2.gainNode) {
3199
+ self2.gainNode.disconnect();
3200
+ self2.gainNode = null;
3201
+ }
3202
+ if (self2.audioSources.length) {
3203
+ self2.audioSources.forEach(function(source) {
3204
+ source.disconnect();
3205
+ });
3206
+ self2.audioSources = [];
3207
+ }
3208
+ if (self2.audioDestination) {
3209
+ self2.audioDestination.disconnect();
3210
+ self2.audioDestination = null;
3211
+ }
3212
+ if (self2.audioContext) {
3213
+ self2.audioContext.close();
3214
+ }
3215
+ self2.audioContext = null;
3216
+ context.clearRect(0, 0, canvas.width, canvas.height);
3217
+ if (canvas.stream) {
3218
+ canvas.stream.stop();
3219
+ canvas.stream = null;
3220
+ }
3221
+ };
3222
+ this.resetVideoStreams = function(streams) {
3223
+ if (streams && !(streams instanceof Array)) {
3224
+ streams = [streams];
3225
+ }
3226
+ resetVideoStreams(streams);
3227
+ };
3228
+ function resetVideoStreams(streams) {
3229
+ videos = [];
3230
+ streams = streams || arrayOfMediaStreams;
3231
+ streams.forEach(function(stream) {
3232
+ if (!stream.getTracks().filter(function(t) {
3233
+ return t.kind === "video";
3234
+ }).length) {
3235
+ return;
3236
+ }
3237
+ var video = getVideo(stream);
3238
+ video.stream = stream;
3239
+ videos.push(video);
3240
+ });
3241
+ }
3242
+ this.name = "MultiStreamsMixer";
3243
+ this.toString = function() {
3244
+ return this.name;
3245
+ };
3246
+ this.getMixedStream = getMixedStream;
3247
+ }
3248
+ if (typeof RecordRTC === "undefined") {
3249
+ if (typeof module2 !== "undefined") {
3250
+ module2.exports = MultiStreamsMixer;
3251
+ }
3252
+ if (typeof define === "function" && define.amd) {
3253
+ define("MultiStreamsMixer", [], function() {
3254
+ return MultiStreamsMixer;
3255
+ });
3256
+ }
3257
+ }
3258
+ function MultiStreamRecorder(arrayOfMediaStreams, options) {
3259
+ arrayOfMediaStreams = arrayOfMediaStreams || [];
3260
+ var self2 = this;
3261
+ var mixer;
3262
+ var mediaRecorder;
3263
+ options = options || {
3264
+ elementClass: "multi-streams-mixer",
3265
+ mimeType: "video/webm",
3266
+ video: {
3267
+ width: 360,
3268
+ height: 240
3269
+ }
3270
+ };
3271
+ if (!options.frameInterval) {
3272
+ options.frameInterval = 10;
3273
+ }
3274
+ if (!options.video) {
3275
+ options.video = {};
3276
+ }
3277
+ if (!options.video.width) {
3278
+ options.video.width = 360;
3279
+ }
3280
+ if (!options.video.height) {
3281
+ options.video.height = 240;
3282
+ }
3283
+ this.record = function() {
3284
+ mixer = new MultiStreamsMixer(arrayOfMediaStreams, options.elementClass || "multi-streams-mixer");
3285
+ if (getAllVideoTracks().length) {
3286
+ mixer.frameInterval = options.frameInterval || 10;
3287
+ mixer.width = options.video.width || 360;
3288
+ mixer.height = options.video.height || 240;
3289
+ mixer.startDrawingFrames();
3290
+ }
3291
+ if (options.previewStream && typeof options.previewStream === "function") {
3292
+ options.previewStream(mixer.getMixedStream());
3293
+ }
3294
+ mediaRecorder = new MediaStreamRecorder(mixer.getMixedStream(), options);
3295
+ mediaRecorder.record();
3296
+ };
3297
+ function getAllVideoTracks() {
3298
+ var tracks = [];
3299
+ arrayOfMediaStreams.forEach(function(stream) {
3300
+ getTracks(stream, "video").forEach(function(track) {
3301
+ tracks.push(track);
3302
+ });
3303
+ });
3304
+ return tracks;
3305
+ }
3306
+ this.stop = function(callback) {
3307
+ if (!mediaRecorder) {
3308
+ return;
3309
+ }
3310
+ mediaRecorder.stop(function(blob) {
3311
+ self2.blob = blob;
3312
+ callback(blob);
3313
+ self2.clearRecordedData();
3314
+ });
3315
+ };
3316
+ this.pause = function() {
3317
+ if (mediaRecorder) {
3318
+ mediaRecorder.pause();
3319
+ }
3320
+ };
3321
+ this.resume = function() {
3322
+ if (mediaRecorder) {
3323
+ mediaRecorder.resume();
3324
+ }
3325
+ };
3326
+ this.clearRecordedData = function() {
3327
+ if (mediaRecorder) {
3328
+ mediaRecorder.clearRecordedData();
3329
+ mediaRecorder = null;
3330
+ }
3331
+ if (mixer) {
3332
+ mixer.releaseStreams();
3333
+ mixer = null;
3334
+ }
3335
+ };
3336
+ this.addStreams = function(streams) {
3337
+ if (!streams) {
3338
+ throw "First parameter is required.";
3339
+ }
3340
+ if (!(streams instanceof Array)) {
3341
+ streams = [streams];
3342
+ }
3343
+ arrayOfMediaStreams.concat(streams);
3344
+ if (!mediaRecorder || !mixer) {
3345
+ return;
3346
+ }
3347
+ mixer.appendStreams(streams);
3348
+ if (options.previewStream && typeof options.previewStream === "function") {
3349
+ options.previewStream(mixer.getMixedStream());
3350
+ }
3351
+ };
3352
+ this.resetVideoStreams = function(streams) {
3353
+ if (!mixer) {
3354
+ return;
3355
+ }
3356
+ if (streams && !(streams instanceof Array)) {
3357
+ streams = [streams];
3358
+ }
3359
+ mixer.resetVideoStreams(streams);
3360
+ };
3361
+ this.getMixer = function() {
3362
+ return mixer;
3363
+ };
3364
+ this.name = "MultiStreamRecorder";
3365
+ this.toString = function() {
3366
+ return this.name;
3367
+ };
3368
+ }
3369
+ if (typeof RecordRTC !== "undefined") {
3370
+ RecordRTC.MultiStreamRecorder = MultiStreamRecorder;
3371
+ }
3372
+ function RecordRTCPromisesHandler3(mediaStream, options) {
3373
+ if (!this) {
3374
+ throw 'Use "new RecordRTCPromisesHandler()"';
3375
+ }
3376
+ if (typeof mediaStream === "undefined") {
3377
+ throw 'First argument "MediaStream" is required.';
3378
+ }
3379
+ var self2 = this;
3380
+ self2.recordRTC = new RecordRTC(mediaStream, options);
3381
+ this.startRecording = function() {
3382
+ return new Promise(function(resolve, reject) {
3383
+ try {
3384
+ self2.recordRTC.startRecording();
3385
+ resolve();
3386
+ } catch (e) {
3387
+ reject(e);
3388
+ }
3389
+ });
3390
+ };
3391
+ this.stopRecording = function() {
3392
+ return new Promise(function(resolve, reject) {
3393
+ try {
3394
+ self2.recordRTC.stopRecording(function(url) {
3395
+ self2.blob = self2.recordRTC.getBlob();
3396
+ if (!self2.blob || !self2.blob.size) {
3397
+ reject("Empty blob.", self2.blob);
3398
+ return;
3399
+ }
3400
+ resolve(url);
3401
+ });
3402
+ } catch (e) {
3403
+ reject(e);
3404
+ }
3405
+ });
3406
+ };
3407
+ this.pauseRecording = function() {
3408
+ return new Promise(function(resolve, reject) {
3409
+ try {
3410
+ self2.recordRTC.pauseRecording();
3411
+ resolve();
3412
+ } catch (e) {
3413
+ reject(e);
3414
+ }
3415
+ });
3416
+ };
3417
+ this.resumeRecording = function() {
3418
+ return new Promise(function(resolve, reject) {
3419
+ try {
3420
+ self2.recordRTC.resumeRecording();
3421
+ resolve();
3422
+ } catch (e) {
3423
+ reject(e);
3424
+ }
3425
+ });
3426
+ };
3427
+ this.getDataURL = function(callback) {
3428
+ return new Promise(function(resolve, reject) {
3429
+ try {
3430
+ self2.recordRTC.getDataURL(function(dataURL) {
3431
+ resolve(dataURL);
3432
+ });
3433
+ } catch (e) {
3434
+ reject(e);
3435
+ }
3436
+ });
3437
+ };
3438
+ this.getBlob = function() {
3439
+ return new Promise(function(resolve, reject) {
3440
+ try {
3441
+ resolve(self2.recordRTC.getBlob());
3442
+ } catch (e) {
3443
+ reject(e);
3444
+ }
3445
+ });
3446
+ };
3447
+ this.getInternalRecorder = function() {
3448
+ return new Promise(function(resolve, reject) {
3449
+ try {
3450
+ resolve(self2.recordRTC.getInternalRecorder());
3451
+ } catch (e) {
3452
+ reject(e);
3453
+ }
3454
+ });
3455
+ };
3456
+ this.reset = function() {
3457
+ return new Promise(function(resolve, reject) {
3458
+ try {
3459
+ resolve(self2.recordRTC.reset());
3460
+ } catch (e) {
3461
+ reject(e);
3462
+ }
3463
+ });
3464
+ };
3465
+ this.destroy = function() {
3466
+ return new Promise(function(resolve, reject) {
3467
+ try {
3468
+ resolve(self2.recordRTC.destroy());
3469
+ } catch (e) {
3470
+ reject(e);
3471
+ }
3472
+ });
3473
+ };
3474
+ this.getState = function() {
3475
+ return new Promise(function(resolve, reject) {
3476
+ try {
3477
+ resolve(self2.recordRTC.getState());
3478
+ } catch (e) {
3479
+ reject(e);
3480
+ }
3481
+ });
3482
+ };
3483
+ this.blob = null;
3484
+ this.version = "5.6.2";
3485
+ }
3486
+ if (typeof RecordRTC !== "undefined") {
3487
+ RecordRTC.RecordRTCPromisesHandler = RecordRTCPromisesHandler3;
3488
+ }
3489
+ function WebAssemblyRecorder(stream, config2) {
3490
+ if (typeof ReadableStream === "undefined" || typeof WritableStream === "undefined") {
3491
+ console.error("Following polyfill is strongly recommended: https://unpkg.com/@mattiasbuelens/web-streams-polyfill/dist/polyfill.min.js");
3492
+ }
3493
+ config2 = config2 || {};
3494
+ config2.width = config2.width || 640;
3495
+ config2.height = config2.height || 480;
3496
+ config2.frameRate = config2.frameRate || 30;
3497
+ config2.bitrate = config2.bitrate || 1200;
3498
+ config2.realtime = config2.realtime || true;
3499
+ function createBufferURL(buffer, type) {
3500
+ return URL2.createObjectURL(new Blob([buffer], {
3501
+ type: type || ""
3502
+ }));
3503
+ }
3504
+ var finished;
3505
+ function cameraStream() {
3506
+ return new ReadableStream({
3507
+ start: function(controller) {
3508
+ var cvs = document.createElement("canvas");
3509
+ var video = document.createElement("video");
3510
+ var first = true;
3511
+ video.srcObject = stream;
3512
+ video.muted = true;
3513
+ video.height = config2.height;
3514
+ video.width = config2.width;
3515
+ video.volume = 0;
3516
+ video.onplaying = function() {
3517
+ cvs.width = config2.width;
3518
+ cvs.height = config2.height;
3519
+ var ctx = cvs.getContext("2d");
3520
+ var frameTimeout = 1e3 / config2.frameRate;
3521
+ var cameraTimer = setInterval(function f() {
3522
+ if (finished) {
3523
+ clearInterval(cameraTimer);
3524
+ controller.close();
3525
+ }
3526
+ if (first) {
3527
+ first = false;
3528
+ if (config2.onVideoProcessStarted) {
3529
+ config2.onVideoProcessStarted();
3530
+ }
3531
+ }
3532
+ ctx.drawImage(video, 0, 0);
3533
+ if (controller._controlledReadableStream.state !== "closed") {
3534
+ try {
3535
+ controller.enqueue(ctx.getImageData(0, 0, config2.width, config2.height));
3536
+ } catch (e) {
3537
+ }
3538
+ }
3539
+ }, frameTimeout);
3540
+ };
3541
+ video.play();
3542
+ }
3543
+ });
3544
+ }
3545
+ var worker;
3546
+ function startRecording(stream2, buffer) {
3547
+ if (!config2.workerPath && !buffer) {
3548
+ finished = false;
3549
+ fetch("https://unpkg.com/webm-wasm@latest/dist/webm-worker.js").then(function(r) {
3550
+ r.arrayBuffer().then(function(buffer2) {
3551
+ startRecording(stream2, buffer2);
3552
+ });
3553
+ });
3554
+ return;
3555
+ }
3556
+ if (!config2.workerPath && buffer instanceof ArrayBuffer) {
3557
+ var blob = new Blob([buffer], {
3558
+ type: "text/javascript"
3559
+ });
3560
+ config2.workerPath = URL2.createObjectURL(blob);
3561
+ }
3562
+ if (!config2.workerPath) {
3563
+ console.error("workerPath parameter is missing.");
3564
+ }
3565
+ worker = new Worker(config2.workerPath);
3566
+ worker.postMessage(config2.webAssemblyPath || "https://unpkg.com/webm-wasm@latest/dist/webm-wasm.wasm");
3567
+ worker.addEventListener("message", function(event) {
3568
+ if (event.data === "READY") {
3569
+ worker.postMessage({
3570
+ width: config2.width,
3571
+ height: config2.height,
3572
+ bitrate: config2.bitrate || 1200,
3573
+ timebaseDen: config2.frameRate || 30,
3574
+ realtime: config2.realtime
3575
+ });
3576
+ cameraStream().pipeTo(new WritableStream({
3577
+ write: function(image) {
3578
+ if (finished) {
3579
+ console.error("Got image, but recorder is finished!");
3580
+ return;
3581
+ }
3582
+ worker.postMessage(image.data.buffer, [image.data.buffer]);
3583
+ }
3584
+ }));
3585
+ } else if (!!event.data) {
3586
+ if (!isPaused) {
3587
+ arrayOfBuffers.push(event.data);
3588
+ }
3589
+ }
3590
+ });
3591
+ }
3592
+ this.record = function() {
3593
+ arrayOfBuffers = [];
3594
+ isPaused = false;
3595
+ this.blob = null;
3596
+ startRecording(stream);
3597
+ if (typeof config2.initCallback === "function") {
3598
+ config2.initCallback();
3599
+ }
3600
+ };
3601
+ var isPaused;
3602
+ this.pause = function() {
3603
+ isPaused = true;
3604
+ };
3605
+ this.resume = function() {
3606
+ isPaused = false;
3607
+ };
3608
+ function terminate(callback) {
3609
+ if (!worker) {
3610
+ if (callback) {
3611
+ callback();
3612
+ }
3613
+ return;
3614
+ }
3615
+ worker.addEventListener("message", function(event) {
3616
+ if (event.data === null) {
3617
+ worker.terminate();
3618
+ worker = null;
3619
+ if (callback) {
3620
+ callback();
3621
+ }
3622
+ }
3623
+ });
3624
+ worker.postMessage(null);
3625
+ }
3626
+ var arrayOfBuffers = [];
3627
+ this.stop = function(callback) {
3628
+ finished = true;
3629
+ var recorder = this;
3630
+ terminate(function() {
3631
+ recorder.blob = new Blob(arrayOfBuffers, {
3632
+ type: "video/webm"
3633
+ });
3634
+ callback(recorder.blob);
3635
+ });
3636
+ };
3637
+ this.name = "WebAssemblyRecorder";
3638
+ this.toString = function() {
3639
+ return this.name;
3640
+ };
3641
+ this.clearRecordedData = function() {
3642
+ arrayOfBuffers = [];
3643
+ isPaused = false;
3644
+ this.blob = null;
3645
+ };
3646
+ this.blob = null;
3647
+ }
3648
+ if (typeof RecordRTC !== "undefined") {
3649
+ RecordRTC.WebAssemblyRecorder = WebAssemblyRecorder;
3650
+ }
3651
+ }
3652
+ });
3653
+
26
3654
  // src/plugins/mp3.js
27
3655
  var require_mp3 = __commonJS({
28
3656
  "src/plugins/mp3.js"(exports, module2) {
@@ -74027,39 +77655,8 @@ __export(src_exports, {
74027
77655
  });
74028
77656
  module.exports = __toCommonJS(src_exports);
74029
77657
 
74030
- // src/modules/recorder.ts
74031
- function recorder(stream, buffer) {
74032
- let resolvePromise;
74033
- const options = {
74034
- mimeType: "video/webm;codecs=vp9",
74035
- videoBitsPerSecond: 128e3,
74036
- audioBitsPerSecond: 64 * 1e3
74037
- };
74038
- const mediaRecorder = new MediaRecorder(stream, options);
74039
- mediaRecorder.ondataavailable = (e) => {
74040
- if (e.data.size > 0) {
74041
- buffer.push(e.data);
74042
- }
74043
- resolvePromise && resolvePromise();
74044
- };
74045
- mediaRecorder.start();
74046
- function stopRecording() {
74047
- return new Promise((resolve) => {
74048
- if (mediaRecorder.state == "recording") {
74049
- resolvePromise = resolve;
74050
- mediaRecorder.stop();
74051
- stream.getTracks().forEach((el) => {
74052
- el.stop();
74053
- });
74054
- } else {
74055
- resolve();
74056
- }
74057
- });
74058
- }
74059
- return stopRecording;
74060
- }
74061
-
74062
77658
  // src/modules/startCameraCapture.ts
77659
+ var import_recordrtc = __toESM(require_RecordRTC());
74063
77660
  async function startCameraCapture(buffer, options = { cameraId: void 0, microphoneId: void 0 }, videoOptions = { width: 640, height: 480 }) {
74064
77661
  const { cameraId, microphoneId } = options;
74065
77662
  const constraints = {
@@ -74072,7 +77669,23 @@ async function startCameraCapture(buffer, options = { cameraId: void 0, micropho
74072
77669
  }
74073
77670
  };
74074
77671
  const cameraStream = await navigator.mediaDevices.getUserMedia(constraints);
74075
- const stopCameraRecording = recorder(cameraStream, buffer);
77672
+ const recorder = new import_recordrtc.RecordRTCPromisesHandler(cameraStream, {
77673
+ type: "video"
77674
+ });
77675
+ recorder.startRecording();
77676
+ const stopCameraRecording = async () => {
77677
+ await recorder.stopRecording();
77678
+ const blob = await recorder.getBlob();
77679
+ (0, import_recordrtc.getSeekableBlob)(blob, function(seekableBlob) {
77680
+ recorder.destroy();
77681
+ buffer.push(seekableBlob);
77682
+ console.log(buffer);
77683
+ console.log(seekableBlob);
77684
+ cameraStream.getTracks().forEach((el) => {
77685
+ el.stop();
77686
+ });
77687
+ });
77688
+ };
74076
77689
  return { cameraStream, stopCameraRecording };
74077
77690
  }
74078
77691
 
@@ -74080,17 +77693,17 @@ async function startCameraCapture(buffer, options = { cameraId: void 0, micropho
74080
77693
  var import_mp3 = __toESM(require_mp3());
74081
77694
  var stopRecord;
74082
77695
  function startAudioCapture() {
74083
- const recorder2 = new import_mp3.default({
77696
+ const recorder = new import_mp3.default({
74084
77697
  bitRate: 128
74085
77698
  });
74086
77699
  function start() {
74087
- recorder2.start().then(() => {
77700
+ recorder.start().then(() => {
74088
77701
  }).catch((e) => {
74089
77702
  console.error(e);
74090
77703
  });
74091
77704
  }
74092
77705
  async function stop() {
74093
- const response = await recorder2.stop().getMp3().then(async ([buffer, blob]) => {
77706
+ const response = await recorder.stop().getMp3().then(async ([buffer, blob]) => {
74094
77707
  return { buffer, blob };
74095
77708
  }).catch((e) => {
74096
77709
  alert("We could not retrieve your message");
@@ -74102,6 +77715,9 @@ function startAudioCapture() {
74102
77715
  return { start, stop };
74103
77716
  }
74104
77717
 
77718
+ // src/modules/startScreenCapture.ts
77719
+ var import_recordrtc2 = __toESM(require_RecordRTC());
77720
+
74105
77721
  // src/errors/errors.ts
74106
77722
  var SCRIPT_NOT_CALLED_INSIDE_BODY = "script_not_called_inside_body";
74107
77723
  var INCOMPATIBLE_NAVIGATOR = "incompatible_navigator";
@@ -74141,7 +77757,21 @@ async function startScreenCapture(buffer, options) {
74141
77757
  });
74142
77758
  throw NOT_SHARED_FIRST_SCREEN;
74143
77759
  }
74144
- const stopScreenRecorder = recorder(screenStream, buffer);
77760
+ const recorder = new import_recordrtc2.RecordRTCPromisesHandler(screenStream, {
77761
+ type: "video"
77762
+ });
77763
+ recorder.startRecording();
77764
+ const stopScreenRecorder = async () => {
77765
+ await recorder.stopRecording();
77766
+ const blob = await recorder.getBlob();
77767
+ (0, import_recordrtc2.getSeekableBlob)(blob, function(seekableBlob) {
77768
+ recorder.destroy();
77769
+ buffer.push(seekableBlob);
77770
+ screenStream.getTracks().forEach((el) => {
77771
+ el.stop();
77772
+ });
77773
+ });
77774
+ };
74145
77775
  return { screenStream, stopScreenRecorder };
74146
77776
  }
74147
77777
 
@@ -74945,3 +78575,283 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
74945
78575
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
74946
78576
  PERFORMANCE OF THIS SOFTWARE.
74947
78577
  ***************************************************************************** */
78578
+ /**
78579
+ * CanvasRecorder is a standalone class used by {@link RecordRTC} to bring HTML5-Canvas recording into video WebM. It uses HTML2Canvas library and runs top over {@link Whammy}.
78580
+ * @summary HTML2Canvas recording into video WebM.
78581
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78582
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78583
+ * @typedef CanvasRecorder
78584
+ * @class
78585
+ * @example
78586
+ * var recorder = new CanvasRecorder(htmlElement, { disableLogs: true, useWhammyRecorder: true });
78587
+ * recorder.record();
78588
+ * recorder.stop(function(blob) {
78589
+ * video.src = URL.createObjectURL(blob);
78590
+ * });
78591
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78592
+ * @param {HTMLElement} htmlElement - querySelector/getElementById/getElementsByTagName[0]/etc.
78593
+ * @param {object} config - {disableLogs:true, initCallback: function}
78594
+ */
78595
+ /**
78596
+ * DiskStorage is a standalone object used by {@link RecordRTC} to store recorded blobs in IndexedDB storage.
78597
+ * @summary Writing blobs into IndexedDB.
78598
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78599
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78600
+ * @example
78601
+ * DiskStorage.Store({
78602
+ * audioBlob: yourAudioBlob,
78603
+ * videoBlob: yourVideoBlob,
78604
+ * gifBlob : yourGifBlob
78605
+ * });
78606
+ * DiskStorage.Fetch(function(dataURL, type) {
78607
+ * if(type === 'audioBlob') { }
78608
+ * if(type === 'videoBlob') { }
78609
+ * if(type === 'gifBlob') { }
78610
+ * });
78611
+ * // DiskStorage.dataStoreName = 'recordRTC';
78612
+ * // DiskStorage.onError = function(error) { };
78613
+ * @property {function} init - This method must be called once to initialize IndexedDB ObjectStore. Though, it is auto-used internally.
78614
+ * @property {function} Fetch - This method fetches stored blobs from IndexedDB.
78615
+ * @property {function} Store - This method stores blobs in IndexedDB.
78616
+ * @property {function} onError - This function is invoked for any known/unknown error.
78617
+ * @property {string} dataStoreName - Name of the ObjectStore created in IndexedDB storage.
78618
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78619
+ */
78620
+ /**
78621
+ * GifRecorder is standalone calss used by {@link RecordRTC} to record video or canvas into animated gif.
78622
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78623
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78624
+ * @typedef GifRecorder
78625
+ * @class
78626
+ * @example
78627
+ * var recorder = new GifRecorder(mediaStream || canvas || context, { onGifPreview: function, onGifRecordingStarted: function, width: 1280, height: 720, frameRate: 200, quality: 10 });
78628
+ * recorder.record();
78629
+ * recorder.stop(function(blob) {
78630
+ * img.src = URL.createObjectURL(blob);
78631
+ * });
78632
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78633
+ * @param {MediaStream} mediaStream - MediaStream object or HTMLCanvasElement or CanvasRenderingContext2D.
78634
+ * @param {object} config - {disableLogs:true, initCallback: function, width: 320, height: 240, frameRate: 200, quality: 10}
78635
+ */
78636
+ /**
78637
+ * MRecordRTC runs on top of {@link RecordRTC} to bring multiple recordings in a single place, by providing simple API.
78638
+ * @summary MRecordRTC stands for "Multiple-RecordRTC".
78639
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78640
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78641
+ * @typedef MRecordRTC
78642
+ * @class
78643
+ * @example
78644
+ * var recorder = new MRecordRTC();
78645
+ * recorder.addStream(MediaStream);
78646
+ * recorder.mediaType = {
78647
+ * audio: true, // or StereoAudioRecorder or MediaStreamRecorder
78648
+ * video: true, // or WhammyRecorder or MediaStreamRecorder or WebAssemblyRecorder or CanvasRecorder
78649
+ * gif: true // or GifRecorder
78650
+ * };
78651
+ * // mimeType is optional and should be set only in advance cases.
78652
+ * recorder.mimeType = {
78653
+ * audio: 'audio/wav',
78654
+ * video: 'video/webm',
78655
+ * gif: 'image/gif'
78656
+ * };
78657
+ * recorder.startRecording();
78658
+ * @see For further information:
78659
+ * @see {@link https://github.com/muaz-khan/RecordRTC/tree/master/MRecordRTC|MRecordRTC Source Code}
78660
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78661
+ * @requires {@link RecordRTC}
78662
+ */
78663
+ /**
78664
+ * MediaStreamRecorder is an abstraction layer for {@link https://w3c.github.io/mediacapture-record/MediaRecorder.html|MediaRecorder API}. It is used by {@link RecordRTC} to record MediaStream(s) in both Chrome and Firefox.
78665
+ * @summary Runs top over {@link https://w3c.github.io/mediacapture-record/MediaRecorder.html|MediaRecorder API}.
78666
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78667
+ * @author {@link https://github.com/muaz-khan|Muaz Khan}
78668
+ * @typedef MediaStreamRecorder
78669
+ * @class
78670
+ * @example
78671
+ * var config = {
78672
+ * mimeType: 'video/webm', // vp8, vp9, h264, mkv, opus/vorbis
78673
+ * audioBitsPerSecond : 256 * 8 * 1024,
78674
+ * videoBitsPerSecond : 256 * 8 * 1024,
78675
+ * bitsPerSecond: 256 * 8 * 1024, // if this is provided, skip above two
78676
+ * checkForInactiveTracks: true,
78677
+ * timeSlice: 1000, // concatenate intervals based blobs
78678
+ * ondataavailable: function() {} // get intervals based blobs
78679
+ * }
78680
+ * var recorder = new MediaStreamRecorder(mediaStream, config);
78681
+ * recorder.record();
78682
+ * recorder.stop(function(blob) {
78683
+ * video.src = URL.createObjectURL(blob);
78684
+ *
78685
+ * // or
78686
+ * var blob = recorder.blob;
78687
+ * });
78688
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78689
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78690
+ * @param {object} config - {disableLogs:true, initCallback: function, mimeType: "video/webm", timeSlice: 1000}
78691
+ * @throws Will throw an error if first argument "MediaStream" is missing. Also throws error if "MediaRecorder API" are not supported by the browser.
78692
+ */
78693
+ /**
78694
+ * MultiStreamRecorder can record multiple videos in single container.
78695
+ * @summary Multi-videos recorder.
78696
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78697
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78698
+ * @typedef MultiStreamRecorder
78699
+ * @class
78700
+ * @example
78701
+ * var options = {
78702
+ * mimeType: 'video/webm'
78703
+ * }
78704
+ * var recorder = new MultiStreamRecorder(ArrayOfMediaStreams, options);
78705
+ * recorder.record();
78706
+ * recorder.stop(function(blob) {
78707
+ * video.src = URL.createObjectURL(blob);
78708
+ *
78709
+ * // or
78710
+ * var blob = recorder.blob;
78711
+ * });
78712
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78713
+ * @param {MediaStreams} mediaStreams - Array of MediaStreams.
78714
+ * @param {object} config - {disableLogs:true, frameInterval: 1, mimeType: "video/webm"}
78715
+ */
78716
+ /**
78717
+ * RecordRTCPromisesHandler adds promises support in {@link RecordRTC}. Try a {@link https://github.com/muaz-khan/RecordRTC/blob/master/simple-demos/RecordRTCPromisesHandler.html|demo here}
78718
+ * @summary Promises for {@link RecordRTC}
78719
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78720
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78721
+ * @typedef RecordRTCPromisesHandler
78722
+ * @class
78723
+ * @example
78724
+ * var recorder = new RecordRTCPromisesHandler(mediaStream, options);
78725
+ * recorder.startRecording()
78726
+ * .then(successCB)
78727
+ * .catch(errorCB);
78728
+ * // Note: You can access all RecordRTC API using "recorder.recordRTC" e.g.
78729
+ * recorder.recordRTC.onStateChanged = function(state) {};
78730
+ * recorder.recordRTC.setRecordingDuration(5000);
78731
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78732
+ * @param {MediaStream} mediaStream - Single media-stream object, array of media-streams, html-canvas-element, etc.
78733
+ * @param {object} config - {type:"video", recorderType: MediaStreamRecorder, disableLogs: true, numberOfAudioChannels: 1, bufferSize: 0, sampleRate: 0, video: HTMLVideoElement, etc.}
78734
+ * @throws Will throw an error if "new" keyword is not used to initiate "RecordRTCPromisesHandler". Also throws error if first argument "MediaStream" is missing.
78735
+ * @requires {@link RecordRTC}
78736
+ */
78737
+ /**
78738
+ * StereoAudioRecorder is a standalone class used by {@link RecordRTC} to bring "stereo" audio-recording in chrome.
78739
+ * @summary JavaScript standalone object for stereo audio recording.
78740
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78741
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78742
+ * @typedef StereoAudioRecorder
78743
+ * @class
78744
+ * @example
78745
+ * var recorder = new StereoAudioRecorder(MediaStream, {
78746
+ * sampleRate: 44100,
78747
+ * bufferSize: 4096
78748
+ * });
78749
+ * recorder.record();
78750
+ * recorder.stop(function(blob) {
78751
+ * video.src = URL.createObjectURL(blob);
78752
+ * });
78753
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78754
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78755
+ * @param {object} config - {sampleRate: 44100, bufferSize: 4096, numberOfAudioChannels: 1, etc.}
78756
+ */
78757
+ /**
78758
+ * Storage is a standalone object used by {@link RecordRTC} to store reusable objects e.g. "new AudioContext".
78759
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78760
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78761
+ * @example
78762
+ * Storage.AudioContext === webkitAudioContext
78763
+ * @property {webkitAudioContext} AudioContext - Keeps a reference to AudioContext object.
78764
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78765
+ */
78766
+ /**
78767
+ * WebAssemblyRecorder lets you create webm videos in JavaScript via WebAssembly. The library consumes raw RGBA32 buffers (4 bytes per pixel) and turns them into a webm video with the given framerate and quality. This makes it compatible out-of-the-box with ImageData from a CANVAS. With realtime mode you can also use webm-wasm for streaming webm videos.
78768
+ * @summary Video recording feature in Chrome, Firefox and maybe Edge.
78769
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78770
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78771
+ * @typedef WebAssemblyRecorder
78772
+ * @class
78773
+ * @example
78774
+ * var recorder = new WebAssemblyRecorder(mediaStream);
78775
+ * recorder.record();
78776
+ * recorder.stop(function(blob) {
78777
+ * video.src = URL.createObjectURL(blob);
78778
+ * });
78779
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78780
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78781
+ * @param {object} config - {webAssemblyPath:'webm-wasm.wasm',workerPath: 'webm-worker.js', frameRate: 30, width: 1920, height: 1080, bitrate: 1024, realtime: true}
78782
+ */
78783
+ /**
78784
+ * Whammy is a standalone class used by {@link RecordRTC} to bring video recording in Chrome. It is written by {@link https://github.com/antimatter15|antimatter15}
78785
+ * @summary A real time javascript webm encoder based on a canvas hack.
78786
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78787
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78788
+ * @typedef Whammy
78789
+ * @class
78790
+ * @example
78791
+ * var recorder = new Whammy().Video(15);
78792
+ * recorder.add(context || canvas || dataURL);
78793
+ * var output = recorder.compile();
78794
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78795
+ */
78796
+ /**
78797
+ * WhammyRecorder is a standalone class used by {@link RecordRTC} to bring video recording in Chrome. It runs top over {@link Whammy}.
78798
+ * @summary Video recording feature in Chrome.
78799
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78800
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78801
+ * @typedef WhammyRecorder
78802
+ * @class
78803
+ * @example
78804
+ * var recorder = new WhammyRecorder(mediaStream);
78805
+ * recorder.record();
78806
+ * recorder.stop(function(blob) {
78807
+ * video.src = URL.createObjectURL(blob);
78808
+ * });
78809
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78810
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78811
+ * @param {object} config - {disableLogs: true, initCallback: function, video: HTMLVideoElement, etc.}
78812
+ */
78813
+ /**
78814
+ * {@link GetRecorderType} is an inner/private helper for {@link RecordRTC}.
78815
+ * @summary It returns best recorder-type available for your browser.
78816
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78817
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78818
+ * @typedef GetRecorderType
78819
+ * @class
78820
+ * @example
78821
+ * var RecorderType = GetRecorderType(options);
78822
+ * var recorder = new RecorderType(options);
78823
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78824
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78825
+ * @param {object} config - {type:"video", disableLogs: true, numberOfAudioChannels: 1, bufferSize: 0, sampleRate: 0, video: HTMLVideoElement, etc.}
78826
+ */
78827
+ /**
78828
+ * {@link RecordRTCConfiguration} is an inner/private helper for {@link RecordRTC}.
78829
+ * @summary It configures the 2nd parameter passed over {@link RecordRTC} and returns a valid "config" object.
78830
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78831
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78832
+ * @typedef RecordRTCConfiguration
78833
+ * @class
78834
+ * @example
78835
+ * var options = RecordRTCConfiguration(mediaStream, options);
78836
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78837
+ * @param {MediaStream} mediaStream - MediaStream object fetched using getUserMedia API or generated using captureStreamUntilEnded or WebAudio API.
78838
+ * @param {object} config - {type:"video", disableLogs: true, numberOfAudioChannels: 1, bufferSize: 0, sampleRate: 0, video: HTMLVideoElement, getNativeBlob:true, etc.}
78839
+ */
78840
+ /**
78841
+ * {@link https://github.com/muaz-khan/RecordRTC|RecordRTC} is a WebRTC JavaScript library for audio/video as well as screen activity recording. It supports Chrome, Firefox, Opera, Android, and Microsoft Edge. Platforms: Linux, Mac and Windows.
78842
+ * @summary Record audio, video or screen inside the browser.
78843
+ * @license {@link https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE|MIT}
78844
+ * @author {@link https://MuazKhan.com|Muaz Khan}
78845
+ * @typedef RecordRTC
78846
+ * @class
78847
+ * @example
78848
+ * var recorder = RecordRTC(mediaStream or [arrayOfMediaStream], {
78849
+ * type: 'video', // audio or video or gif or canvas
78850
+ * recorderType: MediaStreamRecorder || CanvasRecorder || StereoAudioRecorder || Etc
78851
+ * });
78852
+ * recorder.startRecording();
78853
+ * @see For further information:
78854
+ * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
78855
+ * @param {MediaStream} mediaStream - Single media-stream object, array of media-streams, html-canvas-element, etc.
78856
+ * @param {object} config - {type:"video", recorderType: MediaStreamRecorder, disableLogs: true, numberOfAudioChannels: 1, bufferSize: 0, sampleRate: 0, desiredSampRate: 16000, video: HTMLVideoElement, etc.}
78857
+ */