@bigbinary/neeto-media-recorder 2.7.6 → 2.7.7

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
@@ -1,8 +1,8 @@
1
1
  import { shallow } from 'zustand/shallow';
2
- import { useEffect, useState, forwardRef, useRef, useImperativeHandle } from 'react';
2
+ import { useState, useRef, useCallback, useEffect, forwardRef, useImperativeHandle } from 'react';
3
3
  import classNames from 'classnames';
4
4
  import { isNotEmpty, noop } from '@bigbinary/neeto-cist';
5
- import { SCREEN_RECORDER_STATUS, UPLOAD_STATUS as UPLOAD_STATUS$1, ONE_SECOND_IN_MILLISECONDS as ONE_SECOND_IN_MILLISECONDS$1, MIME_TYPE as MIME_TYPE$1, ONE_MINUTE_IN_MILLISECONDS as ONE_MINUTE_IN_MILLISECONDS$1, IS_EXTENSION as IS_EXTENSION$1, SCREEN_RECORDER_ERROR, IS_SAFARI_EXTENSION, SCREEN_RECORDER_EVENT, UPLOAD_EVENT } from '@bigbinary/neeto-media-recorder/constants';
5
+ import { SCREEN_RECORDER_STATUS, UPLOAD_STATUS as UPLOAD_STATUS$1, ONE_SECOND_IN_MILLISECONDS as ONE_SECOND_IN_MILLISECONDS$1, MIME_TYPE as MIME_TYPE$1, ONE_MINUTE_IN_MILLISECONDS as ONE_MINUTE_IN_MILLISECONDS$1, IS_EXTENSION as IS_EXTENSION$1, SCREEN_RECORDER_ERROR, IS_SAFARI_EXTENSION, MIC_NOT_WORKING_SILENCE_TIMEOUT, SCREEN_RECORDER_EVENT, UPLOAD_EVENT } from '@bigbinary/neeto-media-recorder/constants';
6
6
  import { screenRecorder, useMultipartS3UploadStatus, getMultipartS3Uploader } from '@bigbinary/neeto-media-recorder/core';
7
7
  import PageLoader from '@bigbinary/neeto-molecules/PageLoader';
8
8
  import Alert from '@bigbinary/neetoui/Alert';
@@ -512,7 +512,6 @@ var MIME_TYPE = {
512
512
  mp4: "video/mp4",
513
513
  webmH264: "video/webm;codecs=h264"
514
514
  };
515
- // 2 hours
516
515
 
517
516
  var getSupportedMimeType = function getSupportedMimeType() {
518
517
  return MIME_TYPE.webmH264;
@@ -921,6 +920,183 @@ var Controls = function Controls(_ref) {
921
920
  });
922
921
  };
923
922
 
923
+ var getAnalyser = function getAnalyser() {
924
+ var _screenRecorder$getAu;
925
+ var stream = (_screenRecorder$getAu = screenRecorder.getAudioStream) === null || _screenRecorder$getAu === void 0 ? void 0 : _screenRecorder$getAu.call(screenRecorder);
926
+ if (!stream) return null;
927
+ var ctx = new (window.AudioContext || window.webkitAudioContext)();
928
+ var source = ctx.createMediaStreamSource(stream);
929
+ var analyser = ctx.createAnalyser();
930
+ analyser.fftSize = 2048;
931
+ source.connect(analyser);
932
+ var data = new Uint8Array(analyser.fftSize);
933
+ return {
934
+ ctx: ctx,
935
+ source: source,
936
+ analyser: analyser,
937
+ data: data
938
+ };
939
+ };
940
+ var hasChrome = typeof chrome !== "undefined" && chrome.runtime && chrome.runtime.onMessage;
941
+ var useAudioIsCapturing = function useAudioIsCapturing(_ref) {
942
+ var isMicOn = _ref.isMicOn;
943
+ var _useState = useState(true),
944
+ _useState2 = _slicedToArray(_useState, 2),
945
+ hasAudio = _useState2[0],
946
+ setHasAudio = _useState2[1];
947
+ var _useState3 = useState(false),
948
+ _useState4 = _slicedToArray(_useState3, 2),
949
+ disable = _useState4[0],
950
+ setDisable = _useState4[1];
951
+ var _useState5 = useState(false),
952
+ _useState6 = _slicedToArray(_useState5, 2),
953
+ timerStarted = _useState6[0],
954
+ setTimerStarted = _useState6[1];
955
+ var timerRef = useRef(null);
956
+ var remainingRef = useRef(MIC_NOT_WORKING_SILENCE_TIMEOUT);
957
+ var startedAtRef = useRef(null);
958
+ var clearTimer = function clearTimer() {
959
+ if (timerRef.current) clearTimeout(timerRef.current);
960
+ timerRef.current = null;
961
+ };
962
+ var armTimer = function armTimer() {
963
+ if (timerRef.current || !timerStarted) return;
964
+ logger.info("useAudioIsCapturing new timer");
965
+ startedAtRef.current = Date.now();
966
+ timerRef.current = setTimeout(function () {
967
+ return setHasAudio(false);
968
+ }, remainingRef.current);
969
+ };
970
+ var pauseTimer = function pauseTimer() {
971
+ if (!timerRef.current) return;
972
+ var elapsed = Date.now() - startedAtRef.current;
973
+ remainingRef.current = Math.max(0, remainingRef.current - elapsed);
974
+ clearTimer();
975
+ };
976
+ var resumeTimer = function resumeTimer() {
977
+ if (timerRef.current || !timerStarted || disable) return;
978
+ logger.info("useAudioIsCapturing resumeTimer");
979
+ startedAtRef.current = Date.now();
980
+ timerRef.current = setTimeout(function () {
981
+ return setHasAudio(false);
982
+ }, remainingRef.current);
983
+ };
984
+ var reset = useCallback(function () {
985
+ logger.info("useAudioIsCapturing reset");
986
+ clearTimer();
987
+ remainingRef.current = MIC_NOT_WORKING_SILENCE_TIMEOUT;
988
+ setTimerStarted(false);
989
+ setHasAudio(true);
990
+ }, []);
991
+
992
+ // Listen for Chrome extension messages
993
+ useEffect(function () {
994
+ var handleMessage = function handleMessage(message) {
995
+ if (!(message.type === "IGNORE_AUDIO_NOT_CAPTURING")) return;
996
+ logger.info("useAudioIsCapturing -> IGNORE_AUDIO_NOT_CAPTURING received");
997
+ setDisable(true);
998
+ };
999
+
1000
+ // Check if we're in a Chrome extension context
1001
+ if (hasChrome) {
1002
+ chrome.runtime.onMessage.addListener(handleMessage);
1003
+ }
1004
+ return function () {
1005
+ if (hasChrome) {
1006
+ var _chrome, _chrome$runtime, _chrome$runtime$onMes;
1007
+ (_chrome = chrome) === null || _chrome === void 0 ? void 0 : (_chrome$runtime = _chrome.runtime) === null || _chrome$runtime === void 0 ? void 0 : (_chrome$runtime$onMes = _chrome$runtime.onMessage) === null || _chrome$runtime$onMes === void 0 ? void 0 : _chrome$runtime$onMes.removeListener(handleMessage);
1008
+ }
1009
+ };
1010
+ }, []);
1011
+ useEffect(function () {
1012
+ logger.info("useAudioIsCapturing->", timerStarted, hasAudio, isMicOn, disable);
1013
+ if (!isMicOn || !timerStarted || disable) return noop;
1014
+ var analyserObj = null;
1015
+ var rafId;
1016
+ var loop = function loop() {
1017
+ if (!analyserObj) analyserObj = getAnalyser();
1018
+ // if no stream yet or analyser failed, treat as silence
1019
+ var isSilent = !analyserObj ? true : function () {
1020
+ analyserObj.analyser.getByteTimeDomainData(analyserObj.data);
1021
+ return analyserObj.data.every(function (v) {
1022
+ return v === 128;
1023
+ }); // absolute silence
1024
+ }();
1025
+
1026
+ if (isSilent) {
1027
+ armTimer();
1028
+ } else {
1029
+ clearTimer();
1030
+ remainingRef.current = MIC_NOT_WORKING_SILENCE_TIMEOUT;
1031
+ if (!hasAudio) setHasAudio(true);
1032
+ }
1033
+ rafId = requestAnimationFrame(loop);
1034
+ };
1035
+ loop();
1036
+ return function () {
1037
+ cancelAnimationFrame(rafId);
1038
+ clearTimer();
1039
+ if (analyserObj) {
1040
+ analyserObj.source.disconnect();
1041
+ analyserObj.ctx.close();
1042
+ }
1043
+ };
1044
+ }, [timerStarted, hasAudio, isMicOn, disable]);
1045
+ useEffect(function () {
1046
+ var _callbacks;
1047
+ if (!isMicOn) return noop;
1048
+ var callbacks = (_callbacks = {}, _defineProperty(_callbacks, SCREEN_RECORDER_EVENT.onStart, function () {
1049
+ logger.info("useAudioIsCapturing onStart");
1050
+ reset();
1051
+ setTimerStarted(true);
1052
+ armTimer();
1053
+ }), _defineProperty(_callbacks, SCREEN_RECORDER_EVENT.onRestart, function () {
1054
+ logger.info("useAudioIsCapturing onRestart");
1055
+ reset();
1056
+ setTimerStarted(true);
1057
+ armTimer();
1058
+ }), _defineProperty(_callbacks, SCREEN_RECORDER_EVENT.onResume, function () {
1059
+ logger.info("useAudioIsCapturing onResume");
1060
+ setTimerStarted(true);
1061
+ resumeTimer();
1062
+ }), _defineProperty(_callbacks, SCREEN_RECORDER_EVENT.onPause, function () {
1063
+ logger.info("useAudioIsCapturing onPause");
1064
+ pauseTimer();
1065
+ }), _defineProperty(_callbacks, SCREEN_RECORDER_EVENT.onStop, function () {
1066
+ logger.info("useAudioIsCapturing onStop");
1067
+ clearTimer();
1068
+ reset();
1069
+ }), _defineProperty(_callbacks, "disable-mic-not-working-warning", function disableMicNotWorkingWarning() {
1070
+ logger.info("useAudioIsCapturing -> disable-mic-not-working-warning");
1071
+ setDisable(true);
1072
+ setTimeout(function () {
1073
+ clearTimer();
1074
+ reset();
1075
+ }, 500);
1076
+ }), _callbacks);
1077
+ // start straight a way.
1078
+ callbacks[SCREEN_RECORDER_EVENT.onStart]();
1079
+ Object.entries(callbacks).forEach(function (_ref2) {
1080
+ var _ref3 = _slicedToArray(_ref2, 2),
1081
+ ev = _ref3[0],
1082
+ fn = _ref3[1];
1083
+ return screenRecorder.addCallback(ev, fn);
1084
+ });
1085
+ return function () {
1086
+ Object.entries(callbacks).forEach(function (_ref4) {
1087
+ var _ref5 = _slicedToArray(_ref4, 2),
1088
+ ev = _ref5[0],
1089
+ fn = _ref5[1];
1090
+ return screenRecorder.removeCallback(ev, fn);
1091
+ });
1092
+ };
1093
+ }, [isMicOn, reset]);
1094
+ return {
1095
+ hasAudio: hasAudio,
1096
+ reset: reset
1097
+ };
1098
+ };
1099
+
924
1100
  var useHandleErrors = function useHandleErrors(_ref) {
925
1101
  var error = _ref.error,
926
1102
  recorderStatus = _ref.recorderStatus;
@@ -1286,7 +1462,11 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
1286
1462
  appName = _ref$appName === void 0 ? globalProps.appName : _ref$appName,
1287
1463
  _ref$mimeType = _ref.mimeType,
1288
1464
  mimeType = _ref$mimeType === void 0 ? getSupportedMimeType() : _ref$mimeType,
1289
- folderId = _ref.folderId;
1465
+ folderId = _ref.folderId,
1466
+ _ref$isMicOn = _ref.isMicOn,
1467
+ isMicOn = _ref$isMicOn === void 0 ? false : _ref$isMicOn,
1468
+ _ref$onAudioNotCaptur = _ref.onAudioNotCapturing,
1469
+ onAudioNotCapturing = _ref$onAudioNotCaptur === void 0 ? function () {} : _ref$onAudioNotCaptur;
1290
1470
  var _useTranslation = useTranslation(),
1291
1471
  t = _useTranslation.t;
1292
1472
  var _useState = useState(false),
@@ -1306,6 +1486,18 @@ var MediaRecorder = function MediaRecorder(_ref, ref) {
1306
1486
  isRetryUpload = _useState8[0],
1307
1487
  setIsRetryUpload = _useState8[1];
1308
1488
  var recordingRef = useRef({});
1489
+ var _useAudioIsCapturing = useAudioIsCapturing({
1490
+ isMicOn: isMicOn
1491
+ }),
1492
+ hasAudio = _useAudioIsCapturing.hasAudio,
1493
+ reset = _useAudioIsCapturing.reset;
1494
+ useEffect(function () {
1495
+ if (hasAudio) return;
1496
+ onAudioNotCapturing();
1497
+ setTimeout(function () {
1498
+ reset();
1499
+ }, 1000);
1500
+ }, [hasAudio]);
1309
1501
 
1310
1502
  /**
1311
1503
  * @type {React.RefObject<Promise<unknown> | null>}