@bigbinary/neeto-media-recorder 2.7.51 → 2.7.54
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/core.js +447 -97
- package/core.js.map +1 -1
- package/index.js +4 -1
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/v2/index.js +4 -1
- package/v2/index.js.map +1 -1
package/core.js
CHANGED
|
@@ -1,43 +1,13 @@
|
|
|
1
|
+
import { isEmpty, isNotNil, min, isNil, identity, pick, not } from 'ramda';
|
|
1
2
|
import axios from 'axios';
|
|
2
3
|
import { existsBy, isNotEmpty, isNot, noop } from '@bigbinary/neeto-cist';
|
|
3
4
|
import { UPLOAD_STATUS, UPLOAD_EVENT, SCREEN_RECORDER_STATUS as SCREEN_RECORDER_STATUS$1, COUNTDOWN_TIME } from '@bigbinary/neeto-media-recorder/constants';
|
|
4
5
|
import { useMultipartS3UploadStatus as useMultipartS3UploadStatus$1, getMultipartS3Uploader as getMultipartS3Uploader$1 } from '@bigbinary/neeto-media-recorder/core';
|
|
5
|
-
import { isNotNil, min, isNil, identity, isEmpty, pick, not } from 'ramda';
|
|
6
6
|
import platform from 'platform';
|
|
7
7
|
import withImmutableActions from '@bigbinary/neeto-commons-frontend/react-utils/withImmutableActions';
|
|
8
8
|
import { create as create$3 } from 'zustand';
|
|
9
9
|
import { useSyncExternalStore } from 'react';
|
|
10
10
|
|
|
11
|
-
function _arrayLikeToArray(r, a) {
|
|
12
|
-
(null == a || a > r.length) && (a = r.length);
|
|
13
|
-
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
14
|
-
return n;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function _arrayWithoutHoles(r) {
|
|
18
|
-
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function _iterableToArray(r) {
|
|
22
|
-
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function _unsupportedIterableToArray(r, a) {
|
|
26
|
-
if (r) {
|
|
27
|
-
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
28
|
-
var t = {}.toString.call(r).slice(8, -1);
|
|
29
|
-
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function _nonIterableSpread() {
|
|
34
|
-
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function _toConsumableArray(r) {
|
|
38
|
-
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
39
|
-
}
|
|
40
|
-
|
|
41
11
|
function asyncGeneratorStep(n, t, e, r, o, a, c) {
|
|
42
12
|
try {
|
|
43
13
|
var i = n[a](c),
|
|
@@ -494,6 +464,386 @@ try {
|
|
|
494
464
|
|
|
495
465
|
var _regeneratorRuntime = /*@__PURE__*/getDefaultExportFromCjs(regenerator);
|
|
496
466
|
|
|
467
|
+
// Where a recording's opening audio is PUT. Uploading it is the whole handoff —
|
|
468
|
+
// the bucket triggers a lambda which titles the recording and reports it to the
|
|
469
|
+
// server, so there is no second call to make.
|
|
470
|
+
//
|
|
471
|
+
// A nil upload_url means the recording already has a title, which is the
|
|
472
|
+
// caller's signal to stop.
|
|
473
|
+
var show = function show(_ref) {
|
|
474
|
+
var recordingId = _ref.recordingId;
|
|
475
|
+
return axios.get("/api/v1/recordings/".concat(encodeURIComponent(recordingId), "/fast_title_upload_url"));
|
|
476
|
+
};
|
|
477
|
+
var fastTitleApi = {
|
|
478
|
+
show: show
|
|
479
|
+
};
|
|
480
|
+
|
|
481
|
+
var createPrefixedLogger = function createPrefixedLogger(prefix) {
|
|
482
|
+
return {
|
|
483
|
+
info: function info() {
|
|
484
|
+
var _logger;
|
|
485
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
486
|
+
args[_key] = arguments[_key];
|
|
487
|
+
}
|
|
488
|
+
return (_logger = logger).info.apply(_logger, [prefix].concat(args));
|
|
489
|
+
},
|
|
490
|
+
error: function error() {
|
|
491
|
+
var _logger2;
|
|
492
|
+
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
493
|
+
args[_key2] = arguments[_key2];
|
|
494
|
+
}
|
|
495
|
+
return (_logger2 = logger).error.apply(_logger2, [prefix].concat(args));
|
|
496
|
+
},
|
|
497
|
+
warn: function warn() {
|
|
498
|
+
var _logger3;
|
|
499
|
+
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
500
|
+
args[_key3] = arguments[_key3];
|
|
501
|
+
}
|
|
502
|
+
return (_logger3 = logger).warn.apply(_logger3, [prefix].concat(args));
|
|
503
|
+
},
|
|
504
|
+
debug: function debug() {
|
|
505
|
+
var _logger4;
|
|
506
|
+
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
507
|
+
args[_key4] = arguments[_key4];
|
|
508
|
+
}
|
|
509
|
+
return (_logger4 = logger).debug.apply(_logger4, [prefix].concat(args));
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
// How much of the opening to transcribe. Long enough that a recording has
|
|
515
|
+
// usually said something, short enough that the title is saved well before the
|
|
516
|
+
// user stops — which is the whole point, since a link pasted right after
|
|
517
|
+
// recording is what the unfurl cache captures.
|
|
518
|
+
//
|
|
519
|
+
// There is only ever one window. The title is built from whatever these seconds
|
|
520
|
+
// contain rather than waiting for a clearly stated topic, so a second attempt
|
|
521
|
+
// would rarely say anything new.
|
|
522
|
+
var FAST_TITLE_WINDOW_MS = 20000;
|
|
523
|
+
|
|
524
|
+
// Ordered by preference. Opus at a low bitrate is all the transcription API
|
|
525
|
+
// consumes, and keeps the window small enough that the upload never dominates.
|
|
526
|
+
//
|
|
527
|
+
// Independent of the video format: this records audio only, so a recording made
|
|
528
|
+
// in MP4 still captures its opening as Opus. The MP4 entries are the fallback
|
|
529
|
+
// for a browser whose MediaRecorder cannot do audio/webm at all — Safari.
|
|
530
|
+
var FAST_TITLE_MIME_TYPES = ["audio/webm;codecs=opus", "audio/ogg;codecs=opus", "audio/webm", "audio/mp4;codecs=mp4a.40.2", "audio/mp4"];
|
|
531
|
+
var FAST_TITLE_AUDIO_BITS_PER_SECOND = 24000;
|
|
532
|
+
|
|
533
|
+
function _classPrivateFieldInitSpec$2(e, t, a) { _checkPrivateRedeclaration$2(e, t), t.set(e, a); }
|
|
534
|
+
function _checkPrivateRedeclaration$2(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
|
|
535
|
+
var supportedMimeType = function supportedMimeType() {
|
|
536
|
+
return FAST_TITLE_MIME_TYPES.find(function (type) {
|
|
537
|
+
return MediaRecorder.isTypeSupported(type);
|
|
538
|
+
});
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Titles a recording while it is still being made.
|
|
543
|
+
*
|
|
544
|
+
* Link unfurlers (Slack, X, Teams) fetch a page's metadata the first time
|
|
545
|
+
* somebody pastes the URL and cache it per URL, with no purge API worth relying
|
|
546
|
+
* on — so whatever title exists at that moment is the one that sticks. Titling
|
|
547
|
+
* after the upload finishes can lose that race. Titling during the recording
|
|
548
|
+
* does not: for anything longer than about half a minute the title is saved
|
|
549
|
+
* before the user presses stop.
|
|
550
|
+
*
|
|
551
|
+
* Runs a second, audio-only MediaRecorder over cloned audio tracks. When its
|
|
552
|
+
* first window closes it PUTs that audio to S3 and stops. The upload is the
|
|
553
|
+
* whole handoff: the bucket triggers a lambda which titles the recording and
|
|
554
|
+
* reports it to the server, so there is no result to wait for here.
|
|
555
|
+
*
|
|
556
|
+
* It shares no object with the real recorder, and every failure path is a no-op
|
|
557
|
+
* — the transcode lambda still titles the recording from its full transcript
|
|
558
|
+
* afterwards.
|
|
559
|
+
*/
|
|
560
|
+
var _logger$2 = /*#__PURE__*/new WeakMap();
|
|
561
|
+
var _recorder = /*#__PURE__*/new WeakMap();
|
|
562
|
+
var _tracks = /*#__PURE__*/new WeakMap();
|
|
563
|
+
var _recordingId$1 = /*#__PURE__*/new WeakMap();
|
|
564
|
+
var _mimeType$2 = /*#__PURE__*/new WeakMap();
|
|
565
|
+
var _finished = /*#__PURE__*/new WeakMap();
|
|
566
|
+
var _reset = /*#__PURE__*/new WeakMap();
|
|
567
|
+
var _onWindowClosed = /*#__PURE__*/new WeakMap();
|
|
568
|
+
var _upload = /*#__PURE__*/new WeakMap();
|
|
569
|
+
var FastTitleRunner = /*#__PURE__*/function () {
|
|
570
|
+
function FastTitleRunner() {
|
|
571
|
+
var _this = this;
|
|
572
|
+
_classCallCheck(this, FastTitleRunner);
|
|
573
|
+
_classPrivateFieldInitSpec$2(this, _logger$2, {
|
|
574
|
+
writable: true,
|
|
575
|
+
value: createPrefixedLogger("[FastTitle]")
|
|
576
|
+
});
|
|
577
|
+
_classPrivateFieldInitSpec$2(this, _recorder, {
|
|
578
|
+
writable: true,
|
|
579
|
+
value: void 0
|
|
580
|
+
});
|
|
581
|
+
_classPrivateFieldInitSpec$2(this, _tracks, {
|
|
582
|
+
writable: true,
|
|
583
|
+
value: []
|
|
584
|
+
});
|
|
585
|
+
_classPrivateFieldInitSpec$2(this, _recordingId$1, {
|
|
586
|
+
writable: true,
|
|
587
|
+
value: null
|
|
588
|
+
});
|
|
589
|
+
_classPrivateFieldInitSpec$2(this, _mimeType$2, {
|
|
590
|
+
writable: true,
|
|
591
|
+
value: void 0
|
|
592
|
+
});
|
|
593
|
+
_classPrivateFieldInitSpec$2(this, _finished, {
|
|
594
|
+
writable: true,
|
|
595
|
+
value: false
|
|
596
|
+
});
|
|
597
|
+
_defineProperty(this, "setRecordingId", function (recordingId) {
|
|
598
|
+
_classPrivateFieldSet(_this, _recordingId$1, recordingId);
|
|
599
|
+
});
|
|
600
|
+
_defineProperty(this, "start", function (mediaStream) {
|
|
601
|
+
var _mediaStream$getAudio, _mediaStream$getAudio2;
|
|
602
|
+
if (_this.isRunning) return;
|
|
603
|
+
var audioTracks = (_mediaStream$getAudio = mediaStream === null || mediaStream === void 0 ? void 0 : (_mediaStream$getAudio2 = mediaStream.getAudioTracks) === null || _mediaStream$getAudio2 === void 0 ? void 0 : _mediaStream$getAudio2.call(mediaStream)) !== null && _mediaStream$getAudio !== void 0 ? _mediaStream$getAudio : [];
|
|
604
|
+
if (isEmpty(audioTracks)) {
|
|
605
|
+
_classPrivateFieldGet(_this, _logger$2).info("start -> no audio track, skipping");
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
_classPrivateFieldSet(_this, _mimeType$2, supportedMimeType());
|
|
609
|
+
if (!_classPrivateFieldGet(_this, _mimeType$2)) {
|
|
610
|
+
_classPrivateFieldGet(_this, _logger$2).info("start -> no supported audio mime type, skipping");
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
_classPrivateFieldGet(_this, _reset).call(_this);
|
|
614
|
+
try {
|
|
615
|
+
// Cloned rather than shared: a clone is an independent track, so a second
|
|
616
|
+
// MediaRecorder reading it cannot affect the one producing the actual
|
|
617
|
+
// recording. Clones must be stopped explicitly or they outlive the take.
|
|
618
|
+
_classPrivateFieldSet(_this, _tracks, audioTracks.map(function (track) {
|
|
619
|
+
return track.clone();
|
|
620
|
+
}));
|
|
621
|
+
_classPrivateFieldSet(_this, _recorder, new MediaRecorder(new MediaStream(_classPrivateFieldGet(_this, _tracks)), {
|
|
622
|
+
mimeType: _classPrivateFieldGet(_this, _mimeType$2),
|
|
623
|
+
audioBitsPerSecond: FAST_TITLE_AUDIO_BITS_PER_SECOND
|
|
624
|
+
}));
|
|
625
|
+
_classPrivateFieldGet(_this, _recorder).ondataavailable = _classPrivateFieldGet(_this, _onWindowClosed);
|
|
626
|
+
_classPrivateFieldGet(_this, _recorder).onerror = function (event) {
|
|
627
|
+
var _event$error;
|
|
628
|
+
_classPrivateFieldGet(_this, _logger$2).error("recorder error", event === null || event === void 0 ? void 0 : (_event$error = event.error) === null || _event$error === void 0 ? void 0 : _event$error.name);
|
|
629
|
+
_this.stop();
|
|
630
|
+
};
|
|
631
|
+
_classPrivateFieldGet(_this, _recorder).start(FAST_TITLE_WINDOW_MS);
|
|
632
|
+
_classPrivateFieldGet(_this, _logger$2).info("start -> recording opening audio", {
|
|
633
|
+
mimeType: _classPrivateFieldGet(_this, _mimeType$2),
|
|
634
|
+
trackCount: _classPrivateFieldGet(_this, _tracks).length
|
|
635
|
+
});
|
|
636
|
+
} catch (error) {
|
|
637
|
+
_classPrivateFieldGet(_this, _logger$2).error("start -> failed", error === null || error === void 0 ? void 0 : error.message);
|
|
638
|
+
_this.stop();
|
|
639
|
+
}
|
|
640
|
+
});
|
|
641
|
+
_defineProperty(this, "pause", function () {
|
|
642
|
+
var _classPrivateFieldGet2;
|
|
643
|
+
if (((_classPrivateFieldGet2 = _classPrivateFieldGet(_this, _recorder)) === null || _classPrivateFieldGet2 === void 0 ? void 0 : _classPrivateFieldGet2.state) === "recording") _classPrivateFieldGet(_this, _recorder).pause();
|
|
644
|
+
});
|
|
645
|
+
_defineProperty(this, "resume", function () {
|
|
646
|
+
var _classPrivateFieldGet3;
|
|
647
|
+
if (((_classPrivateFieldGet3 = _classPrivateFieldGet(_this, _recorder)) === null || _classPrivateFieldGet3 === void 0 ? void 0 : _classPrivateFieldGet3.state) === "paused") _classPrivateFieldGet(_this, _recorder).resume();
|
|
648
|
+
});
|
|
649
|
+
_defineProperty(this, "stop", function () {
|
|
650
|
+
_classPrivateFieldSet(_this, _finished, true);
|
|
651
|
+
try {
|
|
652
|
+
if (_classPrivateFieldGet(_this, _recorder) && _classPrivateFieldGet(_this, _recorder).state !== "inactive") {
|
|
653
|
+
// No final flush: audio sent now would arrive while the recording is
|
|
654
|
+
// already uploading, which is what the transcode lambda is for.
|
|
655
|
+
_classPrivateFieldGet(_this, _recorder).ondataavailable = null;
|
|
656
|
+
_classPrivateFieldGet(_this, _recorder).stop();
|
|
657
|
+
}
|
|
658
|
+
} catch (error) {
|
|
659
|
+
_classPrivateFieldGet(_this, _logger$2).error("stop -> error stopping recorder", error === null || error === void 0 ? void 0 : error.message);
|
|
660
|
+
}
|
|
661
|
+
_classPrivateFieldGet(_this, _tracks).forEach(function (track) {
|
|
662
|
+
return track.stop();
|
|
663
|
+
});
|
|
664
|
+
_classPrivateFieldGet(_this, _reset).call(_this);
|
|
665
|
+
});
|
|
666
|
+
_classPrivateFieldInitSpec$2(this, _reset, {
|
|
667
|
+
writable: true,
|
|
668
|
+
value: function value() {
|
|
669
|
+
_classPrivateFieldSet(_this, _recorder, null);
|
|
670
|
+
_classPrivateFieldSet(_this, _tracks, []);
|
|
671
|
+
_classPrivateFieldSet(_this, _finished, false);
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
_classPrivateFieldInitSpec$2(this, _onWindowClosed, {
|
|
675
|
+
writable: true,
|
|
676
|
+
value: function () {
|
|
677
|
+
var _value = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(event) {
|
|
678
|
+
var _event$data;
|
|
679
|
+
var _event$data$size, _event$data2, audio, recordingId;
|
|
680
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
681
|
+
while (1) switch (_context.prev = _context.next) {
|
|
682
|
+
case 0:
|
|
683
|
+
if (!_classPrivateFieldGet(_this, _finished)) {
|
|
684
|
+
_context.next = 2;
|
|
685
|
+
break;
|
|
686
|
+
}
|
|
687
|
+
return _context.abrupt("return");
|
|
688
|
+
case 2:
|
|
689
|
+
if (!(!((_event$data = event.data) !== null && _event$data !== void 0 && _event$data.size) || !_classPrivateFieldGet(_this, _recordingId$1))) {
|
|
690
|
+
_context.next = 6;
|
|
691
|
+
break;
|
|
692
|
+
}
|
|
693
|
+
_classPrivateFieldGet(_this, _logger$2).info("nothing to send, stopping", {
|
|
694
|
+
size: (_event$data$size = (_event$data2 = event.data) === null || _event$data2 === void 0 ? void 0 : _event$data2.size) !== null && _event$data$size !== void 0 ? _event$data$size : 0,
|
|
695
|
+
hasRecordingId: Boolean(_classPrivateFieldGet(_this, _recordingId$1))
|
|
696
|
+
});
|
|
697
|
+
_this.stop();
|
|
698
|
+
return _context.abrupt("return");
|
|
699
|
+
case 6:
|
|
700
|
+
// Stopped up front: this runs once either way, and stopping first means a
|
|
701
|
+
// slow upload cannot overlap a second window.
|
|
702
|
+
audio = event.data;
|
|
703
|
+
recordingId = _classPrivateFieldGet(_this, _recordingId$1);
|
|
704
|
+
_this.stop();
|
|
705
|
+
_context.prev = 9;
|
|
706
|
+
_context.next = 12;
|
|
707
|
+
return _classPrivateFieldGet(_this, _upload).call(_this, recordingId, audio);
|
|
708
|
+
case 12:
|
|
709
|
+
_context.next = 17;
|
|
710
|
+
break;
|
|
711
|
+
case 14:
|
|
712
|
+
_context.prev = 14;
|
|
713
|
+
_context.t0 = _context["catch"](9);
|
|
714
|
+
// Not fatal: the transcode lambda still titles the recording from its
|
|
715
|
+
// full transcript afterwards.
|
|
716
|
+
_classPrivateFieldGet(_this, _logger$2).error("upload failed", _context.t0 === null || _context.t0 === void 0 ? void 0 : _context.t0.message);
|
|
717
|
+
case 17:
|
|
718
|
+
case "end":
|
|
719
|
+
return _context.stop();
|
|
720
|
+
}
|
|
721
|
+
}, _callee, null, [[9, 14]]);
|
|
722
|
+
}));
|
|
723
|
+
function value(_x) {
|
|
724
|
+
return _value.apply(this, arguments);
|
|
725
|
+
}
|
|
726
|
+
return value;
|
|
727
|
+
}()
|
|
728
|
+
});
|
|
729
|
+
_classPrivateFieldInitSpec$2(this, _upload, {
|
|
730
|
+
writable: true,
|
|
731
|
+
value: function () {
|
|
732
|
+
var _value2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(recordingId, audio) {
|
|
733
|
+
var startedAt, _yield$fastTitleApi$s, uploadUrl, response;
|
|
734
|
+
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
|
735
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
736
|
+
case 0:
|
|
737
|
+
startedAt = performance.now(); // Already the response body: the host app's axios interceptors unwrap it,
|
|
738
|
+
// the same way generatePreSignedUrl's caller destructures its result.
|
|
739
|
+
_context2.next = 3;
|
|
740
|
+
return fastTitleApi.show({
|
|
741
|
+
recordingId: recordingId
|
|
742
|
+
});
|
|
743
|
+
case 3:
|
|
744
|
+
_yield$fastTitleApi$s = _context2.sent;
|
|
745
|
+
uploadUrl = _yield$fastTitleApi$s.uploadUrl;
|
|
746
|
+
if (uploadUrl) {
|
|
747
|
+
_context2.next = 8;
|
|
748
|
+
break;
|
|
749
|
+
}
|
|
750
|
+
_classPrivateFieldGet(_this, _logger$2).info("not wanted for this recording");
|
|
751
|
+
return _context2.abrupt("return");
|
|
752
|
+
case 8:
|
|
753
|
+
_context2.next = 10;
|
|
754
|
+
return fetch(uploadUrl, {
|
|
755
|
+
method: "PUT",
|
|
756
|
+
headers: {
|
|
757
|
+
"Content-Type": _classPrivateFieldGet(_this, _mimeType$2)
|
|
758
|
+
},
|
|
759
|
+
body: audio
|
|
760
|
+
});
|
|
761
|
+
case 10:
|
|
762
|
+
response = _context2.sent;
|
|
763
|
+
if (response.ok) {
|
|
764
|
+
_context2.next = 13;
|
|
765
|
+
break;
|
|
766
|
+
}
|
|
767
|
+
throw new Error("audio upload ".concat(response.status));
|
|
768
|
+
case 13:
|
|
769
|
+
// The last thing this client will say about the recording. Uploading is the
|
|
770
|
+
// whole handoff — the bucket triggers a lambda which transcribes, titles and
|
|
771
|
+
// reports the title to the server — so nothing further appears here whether
|
|
772
|
+
// it succeeds or finds nothing to title.
|
|
773
|
+
_classPrivateFieldGet(_this, _logger$2).info("upload succeeded -> handed off for titling", {
|
|
774
|
+
recordingId: recordingId,
|
|
775
|
+
bytes: audio.size,
|
|
776
|
+
mimeType: _classPrivateFieldGet(_this, _mimeType$2),
|
|
777
|
+
ms: Math.round(performance.now() - startedAt),
|
|
778
|
+
// Path only. The query string of a presigned URL carries its signature.
|
|
779
|
+
key: new URL(uploadUrl).pathname.replace(/^\//, "")
|
|
780
|
+
});
|
|
781
|
+
case 14:
|
|
782
|
+
case "end":
|
|
783
|
+
return _context2.stop();
|
|
784
|
+
}
|
|
785
|
+
}, _callee2);
|
|
786
|
+
}));
|
|
787
|
+
function value(_x2, _x3) {
|
|
788
|
+
return _value2.apply(this, arguments);
|
|
789
|
+
}
|
|
790
|
+
return value;
|
|
791
|
+
}()
|
|
792
|
+
});
|
|
793
|
+
}
|
|
794
|
+
_createClass(FastTitleRunner, [{
|
|
795
|
+
key: "isRunning",
|
|
796
|
+
get: function get() {
|
|
797
|
+
return Boolean(_classPrivateFieldGet(this, _recorder)) && !_classPrivateFieldGet(this, _finished);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// Set once the recording exists. It is created asynchronously and usually
|
|
801
|
+
// lands well before the first window closes.
|
|
802
|
+
/**
|
|
803
|
+
* @param {MediaStream} mediaStream the stream being recorded; its audio tracks
|
|
804
|
+
* are cloned so nothing here can disturb the real recorder
|
|
805
|
+
*/
|
|
806
|
+
// Fires once, when the first window closes. Whatever it holds is the title's
|
|
807
|
+
// only source, so this uploads it and stops.
|
|
808
|
+
}]);
|
|
809
|
+
return FastTitleRunner;
|
|
810
|
+
}();
|
|
811
|
+
var runner = null;
|
|
812
|
+
var getFastTitleRunner = function getFastTitleRunner() {
|
|
813
|
+
if (!runner) runner = new FastTitleRunner();
|
|
814
|
+
return runner;
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
function _arrayLikeToArray(r, a) {
|
|
818
|
+
(null == a || a > r.length) && (a = r.length);
|
|
819
|
+
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
820
|
+
return n;
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
function _arrayWithoutHoles(r) {
|
|
824
|
+
if (Array.isArray(r)) return _arrayLikeToArray(r);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function _iterableToArray(r) {
|
|
828
|
+
if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
function _unsupportedIterableToArray(r, a) {
|
|
832
|
+
if (r) {
|
|
833
|
+
if ("string" == typeof r) return _arrayLikeToArray(r, a);
|
|
834
|
+
var t = {}.toString.call(r).slice(8, -1);
|
|
835
|
+
return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
function _nonIterableSpread() {
|
|
840
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
function _toConsumableArray(r) {
|
|
844
|
+
return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
|
|
845
|
+
}
|
|
846
|
+
|
|
497
847
|
const byteToHex = [];
|
|
498
848
|
for (let i = 0; i < 256; ++i) {
|
|
499
849
|
byteToHex.push((i + 0x100).toString(16).slice(1));
|
|
@@ -952,39 +1302,6 @@ var s3Api = {
|
|
|
952
1302
|
presignedUpload: retryablePresignedUpload
|
|
953
1303
|
};
|
|
954
1304
|
|
|
955
|
-
var createPrefixedLogger = function createPrefixedLogger(prefix) {
|
|
956
|
-
return {
|
|
957
|
-
info: function info() {
|
|
958
|
-
var _logger;
|
|
959
|
-
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
960
|
-
args[_key] = arguments[_key];
|
|
961
|
-
}
|
|
962
|
-
return (_logger = logger).info.apply(_logger, [prefix].concat(args));
|
|
963
|
-
},
|
|
964
|
-
error: function error() {
|
|
965
|
-
var _logger2;
|
|
966
|
-
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
967
|
-
args[_key2] = arguments[_key2];
|
|
968
|
-
}
|
|
969
|
-
return (_logger2 = logger).error.apply(_logger2, [prefix].concat(args));
|
|
970
|
-
},
|
|
971
|
-
warn: function warn() {
|
|
972
|
-
var _logger3;
|
|
973
|
-
for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
|
|
974
|
-
args[_key3] = arguments[_key3];
|
|
975
|
-
}
|
|
976
|
-
return (_logger3 = logger).warn.apply(_logger3, [prefix].concat(args));
|
|
977
|
-
},
|
|
978
|
-
debug: function debug() {
|
|
979
|
-
var _logger4;
|
|
980
|
-
for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
981
|
-
args[_key4] = arguments[_key4];
|
|
982
|
-
}
|
|
983
|
-
return (_logger4 = logger).debug.apply(_logger4, [prefix].concat(args));
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
};
|
|
987
|
-
|
|
988
1305
|
/**
|
|
989
1306
|
* Due to the custom axios interceptor for s3Api,
|
|
990
1307
|
* it'll return false for cancelled requests instead of a cancelled error object.
|
|
@@ -1804,6 +2121,7 @@ var _playCountdownAudio = /*#__PURE__*/new WeakMap();
|
|
|
1804
2121
|
var _mimeType = /*#__PURE__*/new WeakMap();
|
|
1805
2122
|
var _dataReceiving = /*#__PURE__*/new WeakMap();
|
|
1806
2123
|
var _recordSystemAudio = /*#__PURE__*/new WeakMap();
|
|
2124
|
+
var _hasSpeechSourceForTitle = /*#__PURE__*/new WeakMap();
|
|
1807
2125
|
var _stopAllStreams = /*#__PURE__*/new WeakMap();
|
|
1808
2126
|
var _playCountdownBeep = /*#__PURE__*/new WeakMap();
|
|
1809
2127
|
var _checkCompatibility = /*#__PURE__*/new WeakMap();
|
|
@@ -2174,6 +2492,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2174
2492
|
status: SCREEN_RECORDER_STATUS.paused
|
|
2175
2493
|
});
|
|
2176
2494
|
_classPrivateFieldGet(_this, _mediaRecorder).pause();
|
|
2495
|
+
getFastTitleRunner().pause();
|
|
2177
2496
|
} else {
|
|
2178
2497
|
_classPrivateFieldGet(_this, _logger).warn("pauseRecording -> ignored, recorder not in recording state", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
|
|
2179
2498
|
}
|
|
@@ -2187,6 +2506,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2187
2506
|
status: SCREEN_RECORDER_STATUS.recording
|
|
2188
2507
|
});
|
|
2189
2508
|
_classPrivateFieldGet(_this, _mediaRecorder).resume();
|
|
2509
|
+
getFastTitleRunner().resume();
|
|
2190
2510
|
} else {
|
|
2191
2511
|
_classPrivateFieldGet(_this, _logger).warn("resumeRecording -> ignored, recorder not paused", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
|
|
2192
2512
|
}
|
|
@@ -2239,26 +2559,43 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2239
2559
|
_classPrivateFieldGet(_this, _mediaRecorder).onstop = null;
|
|
2240
2560
|
_classPrivateFieldGet(_this, _stopAllStreams).call(_this);
|
|
2241
2561
|
});
|
|
2562
|
+
_classPrivateFieldInitSpec(this, _hasSpeechSourceForTitle, {
|
|
2563
|
+
writable: true,
|
|
2564
|
+
value: function value() {
|
|
2565
|
+
var _classPrivateFieldGet9, _classPrivateFieldGet10, _classPrivateFieldGet11, _classPrivateFieldGet12, _classPrivateFieldGet13;
|
|
2566
|
+
var _ref2 = (_classPrivateFieldGet9 = (_classPrivateFieldGet10 = _classPrivateFieldGet(_this, _micAudioStream)) === null || _classPrivateFieldGet10 === void 0 ? void 0 : (_classPrivateFieldGet11 = _classPrivateFieldGet10.getAudioTracks) === null || _classPrivateFieldGet11 === void 0 ? void 0 : _classPrivateFieldGet11.call(_classPrivateFieldGet10)) !== null && _classPrivateFieldGet9 !== void 0 ? _classPrivateFieldGet9 : [],
|
|
2567
|
+
_ref3 = _slicedToArray(_ref2, 1),
|
|
2568
|
+
micTrack = _ref3[0];
|
|
2569
|
+
var micLive = Boolean(micTrack) && micTrack.readyState !== "ended" && !micTrack.muted && micTrack.enabled;
|
|
2570
|
+
var hasSystemAudio = isNotEmpty((_classPrivateFieldGet12 = (_classPrivateFieldGet13 = _classPrivateFieldGet(_this, _stream)) === null || _classPrivateFieldGet13 === void 0 ? void 0 : _classPrivateFieldGet13.getAudioTracks()) !== null && _classPrivateFieldGet12 !== void 0 ? _classPrivateFieldGet12 : []);
|
|
2571
|
+
if (!micLive && !hasSystemAudio) {
|
|
2572
|
+
_classPrivateFieldGet(_this, _logger).info("fast title skipped -> mic is off and no system audio");
|
|
2573
|
+
return false;
|
|
2574
|
+
}
|
|
2575
|
+
return true;
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2242
2578
|
_classPrivateFieldInitSpec(this, _stopAllStreams, {
|
|
2243
2579
|
writable: true,
|
|
2244
2580
|
value: function value() {
|
|
2245
|
-
var
|
|
2581
|
+
var _classPrivateFieldGet14, _classPrivateFieldGet15, _classPrivateFieldGet16, _classPrivateFieldGet17, _classPrivateFieldGet18, _classPrivateFieldGet19;
|
|
2582
|
+
getFastTitleRunner().stop();
|
|
2246
2583
|
_classPrivateFieldGet(_this, _logger).info("stopAllStreams", {
|
|
2247
2584
|
mediaStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _mediaStream)),
|
|
2248
2585
|
stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _stream)),
|
|
2249
2586
|
audioStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _audioStream)),
|
|
2250
2587
|
micAudioStream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, _classPrivateFieldGet(_this, _micAudioStream))
|
|
2251
2588
|
});
|
|
2252
|
-
_classPrivateFieldGet(_this, _mediaStream) && ((
|
|
2589
|
+
_classPrivateFieldGet(_this, _mediaStream) && ((_classPrivateFieldGet14 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet14 === void 0 ? void 0 : _classPrivateFieldGet14.getTracks().forEach(function (track) {
|
|
2253
2590
|
return track.stop();
|
|
2254
2591
|
}));
|
|
2255
|
-
(
|
|
2592
|
+
(_classPrivateFieldGet15 = _classPrivateFieldGet(_this, _stream)) === null || _classPrivateFieldGet15 === void 0 ? void 0 : _classPrivateFieldGet15.getTracks().forEach(function (track) {
|
|
2256
2593
|
return track.stop();
|
|
2257
2594
|
});
|
|
2258
|
-
(
|
|
2595
|
+
(_classPrivateFieldGet16 = _classPrivateFieldGet(_this, _audioStream)) === null || _classPrivateFieldGet16 === void 0 ? void 0 : (_classPrivateFieldGet17 = _classPrivateFieldGet16.getAudioTracks()) === null || _classPrivateFieldGet17 === void 0 ? void 0 : _classPrivateFieldGet17.forEach(function (track) {
|
|
2259
2596
|
return track.stop();
|
|
2260
2597
|
});
|
|
2261
|
-
(
|
|
2598
|
+
(_classPrivateFieldGet18 = _classPrivateFieldGet(_this, _micAudioStream)) === null || _classPrivateFieldGet18 === void 0 ? void 0 : (_classPrivateFieldGet19 = _classPrivateFieldGet18.getAudioTracks()) === null || _classPrivateFieldGet19 === void 0 ? void 0 : _classPrivateFieldGet19.forEach(function (track) {
|
|
2262
2599
|
return track.stop();
|
|
2263
2600
|
});
|
|
2264
2601
|
}
|
|
@@ -2389,9 +2726,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2389
2726
|
break;
|
|
2390
2727
|
}
|
|
2391
2728
|
_context2.prev = 41;
|
|
2392
|
-
workletUrl = IS_EXTENSION ?
|
|
2393
|
-
// eslint-disable-next-line no-undef
|
|
2394
|
-
chrome.runtime.getURL("public/NoiseSuppressorWorklet.js") : "NoiseSuppressorWorklet.js";
|
|
2729
|
+
workletUrl = IS_EXTENSION ? chrome.runtime.getURL("public/NoiseSuppressorWorklet.js") : "NoiseSuppressorWorklet.js";
|
|
2395
2730
|
_classPrivateFieldGet(_this, _logger).info("acquireMediaStream -> loading noise suppressor worklet", {
|
|
2396
2731
|
workletUrl: workletUrl
|
|
2397
2732
|
});
|
|
@@ -2447,10 +2782,10 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2447
2782
|
// diagnostics) over to it; otherwise preserve the legacy behavior of
|
|
2448
2783
|
// finalizing the recording immediately.
|
|
2449
2784
|
stream.getVideoTracks()[0].addEventListener("ended", function () {
|
|
2450
|
-
var
|
|
2451
|
-
var hasUnexpectedEndHandler = isNotEmpty((
|
|
2785
|
+
var _classPrivateFieldGet20, _classPrivateFieldGet21;
|
|
2786
|
+
var hasUnexpectedEndHandler = isNotEmpty((_classPrivateFieldGet20 = _classPrivateFieldGet(_this, _callbacks)[SCREEN_RECORDER_EVENT.onUnexpectedEnd]) !== null && _classPrivateFieldGet20 !== void 0 ? _classPrivateFieldGet20 : []);
|
|
2452
2787
|
_classPrivateFieldGet(_this, _logger).info("display video track ended event received", {
|
|
2453
|
-
recorderState: (
|
|
2788
|
+
recorderState: (_classPrivateFieldGet21 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet21 === void 0 ? void 0 : _classPrivateFieldGet21.state,
|
|
2454
2789
|
status: _classPrivateFieldGet(_this, _store).getState().status,
|
|
2455
2790
|
hasUnexpectedEndHandler: hasUnexpectedEndHandler,
|
|
2456
2791
|
stream: _classPrivateFieldGet(_this, _summarizeStream).call(_this, stream)
|
|
@@ -2542,9 +2877,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2542
2877
|
_classPrivateFieldInitSpec(this, _fireCallbacks, {
|
|
2543
2878
|
writable: true,
|
|
2544
2879
|
value: function value(event) {
|
|
2545
|
-
var
|
|
2880
|
+
var _classPrivateFieldGet22;
|
|
2546
2881
|
var args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
|
2547
|
-
(
|
|
2882
|
+
(_classPrivateFieldGet22 = _classPrivateFieldGet(_this, _callbacks)[event]) === null || _classPrivateFieldGet22 === void 0 ? void 0 : _classPrivateFieldGet22.forEach(function (callback) {
|
|
2548
2883
|
callback.apply(void 0, _toConsumableArray(args));
|
|
2549
2884
|
});
|
|
2550
2885
|
}
|
|
@@ -2558,9 +2893,9 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2558
2893
|
});
|
|
2559
2894
|
_classPrivateFieldInitSpec(this, _onRecordingActive, {
|
|
2560
2895
|
writable: true,
|
|
2561
|
-
value: function value(
|
|
2562
|
-
var
|
|
2563
|
-
var data =
|
|
2896
|
+
value: function value(_ref4) {
|
|
2897
|
+
var _classPrivateFieldGet23;
|
|
2898
|
+
var data = _ref4.data;
|
|
2564
2899
|
if (data.size <= 0) {
|
|
2565
2900
|
_classPrivateFieldGet(_this, _logger).warn("ondataavailable -> empty chunk, ignoring", {
|
|
2566
2901
|
chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length
|
|
@@ -2578,7 +2913,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2578
2913
|
chunkType: data.type,
|
|
2579
2914
|
chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
|
|
2580
2915
|
totalBytes: totalBytes,
|
|
2581
|
-
recorderState: (
|
|
2916
|
+
recorderState: (_classPrivateFieldGet23 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet23 === void 0 ? void 0 : _classPrivateFieldGet23.state
|
|
2582
2917
|
});
|
|
2583
2918
|
_classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onDataAvailable, [data]);
|
|
2584
2919
|
}
|
|
@@ -2586,14 +2921,14 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2586
2921
|
_classPrivateFieldInitSpec(this, _onRecordingStop, {
|
|
2587
2922
|
writable: true,
|
|
2588
2923
|
value: function value() {
|
|
2589
|
-
var
|
|
2924
|
+
var _classPrivateFieldGet24, _classPrivateFieldGet25;
|
|
2590
2925
|
var totalBytes = _classPrivateFieldGet(_this, _mediaChunks).reduce(function (sum, chunk) {
|
|
2591
2926
|
var _chunk$size2;
|
|
2592
2927
|
return sum + ((_chunk$size2 = chunk === null || chunk === void 0 ? void 0 : chunk.size) !== null && _chunk$size2 !== void 0 ? _chunk$size2 : 0);
|
|
2593
2928
|
}, 0);
|
|
2594
2929
|
_classPrivateFieldGet(_this, _logger).info("MediaRecorder.onstop fired", _objectSpread(_objectSpread({}, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)), {}, {
|
|
2595
2930
|
totalBytes: totalBytes,
|
|
2596
|
-
mediaStreamActive: (
|
|
2931
|
+
mediaStreamActive: (_classPrivateFieldGet24 = _classPrivateFieldGet(_this, _mediaStream)) === null || _classPrivateFieldGet24 === void 0 ? void 0 : _classPrivateFieldGet24.active
|
|
2597
2932
|
}));
|
|
2598
2933
|
_classPrivateFieldGet(_this, _store).setState({
|
|
2599
2934
|
status: SCREEN_RECORDER_STATUS.stopped
|
|
@@ -2602,7 +2937,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2602
2937
|
|
|
2603
2938
|
// If mediaStream is active after stopping mediaRecorder, then that means that
|
|
2604
2939
|
// we are restarting and not stopping.
|
|
2605
|
-
if ((
|
|
2940
|
+
if ((_classPrivateFieldGet25 = _classPrivateFieldGet(_this, _mediaStream)) !== null && _classPrivateFieldGet25 !== void 0 && _classPrivateFieldGet25.active) {
|
|
2606
2941
|
_classPrivateFieldGet(_this, _logger).info("onRecordingStop -> mediaStream still active, transitioning to restarting");
|
|
2607
2942
|
_classPrivateFieldGet(_this, _store).setState({
|
|
2608
2943
|
status: SCREEN_RECORDER_STATUS.restarting
|
|
@@ -2686,10 +3021,10 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2686
3021
|
_classPrivateFieldInitSpec(this, _summarizeRecorderState, {
|
|
2687
3022
|
writable: true,
|
|
2688
3023
|
value: function value() {
|
|
2689
|
-
var
|
|
3024
|
+
var _classPrivateFieldGet26;
|
|
2690
3025
|
var extra = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
2691
3026
|
return _objectSpread({
|
|
2692
|
-
recorderState: (
|
|
3027
|
+
recorderState: (_classPrivateFieldGet26 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet26 === void 0 ? void 0 : _classPrivateFieldGet26.state,
|
|
2693
3028
|
status: _classPrivateFieldGet(_this, _store).getState().status,
|
|
2694
3029
|
elapsedTime: _classPrivateFieldGet(_this, _store).getState().elapsedTime,
|
|
2695
3030
|
chunkCount: _classPrivateFieldGet(_this, _mediaChunks).length,
|
|
@@ -2707,7 +3042,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2707
3042
|
}, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)));
|
|
2708
3043
|
_classPrivateFieldSet(_this, _startRecordingTimeoutID, setTimeout(function () {
|
|
2709
3044
|
try {
|
|
2710
|
-
var
|
|
3045
|
+
var _classPrivateFieldGet27;
|
|
2711
3046
|
if (!_classPrivateFieldGet(_this, _mediaRecorder)) {
|
|
2712
3047
|
_classPrivateFieldGet(_this, _logger).error("startMediaRecorder -> aborted, mediaRecorder is null", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
|
|
2713
3048
|
_classPrivateFieldGet(_this, _store).setState({
|
|
@@ -2728,7 +3063,7 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2728
3063
|
});
|
|
2729
3064
|
return;
|
|
2730
3065
|
}
|
|
2731
|
-
if (((
|
|
3066
|
+
if (((_classPrivateFieldGet27 = _classPrivateFieldGet(_this, _mediaRecorder)) === null || _classPrivateFieldGet27 === void 0 ? void 0 : _classPrivateFieldGet27.state) === "recording") {
|
|
2732
3067
|
_classPrivateFieldGet(_this, _logger).warn("startMediaRecorder -> mediaRecorder already recording, skipping", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
|
|
2733
3068
|
return;
|
|
2734
3069
|
}
|
|
@@ -2736,6 +3071,12 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2736
3071
|
timesliceMs: 5000
|
|
2737
3072
|
}, _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this)));
|
|
2738
3073
|
_classPrivateFieldGet(_this, _mediaRecorder).start(5000);
|
|
3074
|
+
|
|
3075
|
+
// Titles the recording from its opening seconds, while it is still
|
|
3076
|
+
// being made. Skipped when there is nothing that could carry speech.
|
|
3077
|
+
if (_classPrivateFieldGet(_this, _hasSpeechSourceForTitle).call(_this)) {
|
|
3078
|
+
getFastTitleRunner().start(_classPrivateFieldGet(_this, _mediaStream));
|
|
3079
|
+
}
|
|
2739
3080
|
_classPrivateFieldGet(_this, _logger).info("startMediaRecorder -> start() returned", _classPrivateFieldGet(_this, _summarizeRecorderState).call(_this));
|
|
2740
3081
|
_classPrivateFieldGet(_this, _startTimer).call(_this);
|
|
2741
3082
|
} catch (error) {
|
|
@@ -2776,8 +3117,8 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2776
3117
|
_classPrivateFieldGet(_this, _fireCallbacks).call(_this, SCREEN_RECORDER_EVENT.onCountdownStart);
|
|
2777
3118
|
_classPrivateFieldSet(_this, _countdownTimerId, setInterval(function () {
|
|
2778
3119
|
var shouldBeep = false;
|
|
2779
|
-
_classPrivateFieldGet(_this, _store).setState(function (
|
|
2780
|
-
var countdownTimeLeft =
|
|
3120
|
+
_classPrivateFieldGet(_this, _store).setState(function (_ref5) {
|
|
3121
|
+
var countdownTimeLeft = _ref5.countdownTimeLeft;
|
|
2781
3122
|
if (countdownTimeLeft - ONE_SECOND > 0) {
|
|
2782
3123
|
var next = countdownTimeLeft - ONE_SECOND;
|
|
2783
3124
|
_classPrivateFieldGet(_this, _logger).info("startCountdown -> tick", {
|
|
@@ -2812,8 +3153,8 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2812
3153
|
value: function value() {
|
|
2813
3154
|
_classPrivateFieldSet(_this, _lastTimerUpdatedAt, Date.now());
|
|
2814
3155
|
_classPrivateFieldSet(_this, _timerId, setInterval(function () {
|
|
2815
|
-
_classPrivateFieldGet(_this, _store).setState(function (
|
|
2816
|
-
var elapsedTime =
|
|
3156
|
+
_classPrivateFieldGet(_this, _store).setState(function (_ref6) {
|
|
3157
|
+
var elapsedTime = _ref6.elapsedTime;
|
|
2817
3158
|
var now = Date.now();
|
|
2818
3159
|
var newElapsedTime = elapsedTime + (now - _classPrivateFieldGet(_this, _lastTimerUpdatedAt));
|
|
2819
3160
|
_classPrivateFieldSet(_this, _lastTimerUpdatedAt, now);
|
|
@@ -2884,10 +3225,10 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2884
3225
|
}, {
|
|
2885
3226
|
key: "displaySurface",
|
|
2886
3227
|
get: function get() {
|
|
2887
|
-
var
|
|
2888
|
-
var
|
|
2889
|
-
|
|
2890
|
-
videoTrack =
|
|
3228
|
+
var _classPrivateFieldGet28, _classPrivateFieldGet29;
|
|
3229
|
+
var _ref7 = (_classPrivateFieldGet28 = (_classPrivateFieldGet29 = _classPrivateFieldGet(this, _mediaStream)) === null || _classPrivateFieldGet29 === void 0 ? void 0 : _classPrivateFieldGet29.getVideoTracks()) !== null && _classPrivateFieldGet28 !== void 0 ? _classPrivateFieldGet28 : [],
|
|
3230
|
+
_ref8 = _slicedToArray(_ref7, 1),
|
|
3231
|
+
videoTrack = _ref8[0];
|
|
2891
3232
|
return videoTrack === null || videoTrack === void 0 ? void 0 : videoTrack.getSettings().displaySurface;
|
|
2892
3233
|
}
|
|
2893
3234
|
}, {
|
|
@@ -2905,6 +3246,15 @@ var ScreenRecorder = /*#__PURE__*/function () {
|
|
|
2905
3246
|
// The chime is suppressed (vs. natural completion which plays it) since the
|
|
2906
3247
|
// user explicitly opted out of the count-in. Listeners hook onCountdownSkip
|
|
2907
3248
|
// to clean up countdown-only side effects like scheduled beeps.
|
|
3249
|
+
// Whether this recording could contain speech worth titling from.
|
|
3250
|
+
//
|
|
3251
|
+
// A muted mic is the case that matters: with the mic off the fast-title path
|
|
3252
|
+
// would upload audio, spend a transcription and a completion, and get nothing
|
|
3253
|
+
// back. Checked against the raw mic rather than #audioStream, which is the mic
|
|
3254
|
+
// mixed with system audio and stays loud through a dead mic.
|
|
3255
|
+
//
|
|
3256
|
+
// System audio counts on its own — a recording narrated by the thing on screen
|
|
3257
|
+
// is exactly as titleable as one narrated by the user.
|
|
2908
3258
|
// `delayMs` only exists to keep the start chime out of the recording; when no
|
|
2909
3259
|
// chime plays (countdown skipped or disabled) we start immediately so the
|
|
2910
3260
|
// recorder begins ticking without a perceptible gap.
|
|
@@ -2950,5 +3300,5 @@ var useMultipartS3UploadStatus = function useMultipartS3UploadStatus() {
|
|
|
2950
3300
|
};
|
|
2951
3301
|
useMultipartS3UploadStatus.triggerStatusChange = triggerStatusChange;
|
|
2952
3302
|
|
|
2953
|
-
export { getMultipartS3Uploader, getSupportedMimeType, screenRecorder, useMultipartS3UploadStatus };
|
|
3303
|
+
export { getFastTitleRunner, getMultipartS3Uploader, getSupportedMimeType, screenRecorder, useMultipartS3UploadStatus };
|
|
2954
3304
|
//# sourceMappingURL=core.js.map
|