testaugnitorecorder4 1.0.90 → 1.0.91

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.
@@ -830,6 +830,12 @@ var Streamer = /*#__PURE__*/function () {
830
830
  this.echoCancellation = echoCancellation;
831
831
  this.noiseSuppression = noiseSuppression;
832
832
  this.autoGainControl = autoGainControl;
833
+ this.micNeedsRecovery = false;
834
+ this.trackEndedHandler = null;
835
+ this.isRecovering = false;
836
+ this.currentWsUrl = "";
837
+ this.currentDuration = 0;
838
+ this.deviceChangeHandler = null;
833
839
  if (this.shouldPreIntialiseRecorder) {
834
840
  this.InitialiseMediaStream(reconnectAudioDuration, socketUrl);
835
841
  }
@@ -837,30 +843,33 @@ var Streamer = /*#__PURE__*/function () {
837
843
  return _createClass(Streamer, [{
838
844
  key: "InitialiseMediaStream",
839
845
  value: function () {
840
- var _InitialiseMediaStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(duration, wsUrl) {
841
- return _regeneratorRuntime().wrap(function _callee$(_context) {
842
- while (1) switch (_context.prev = _context.next) {
846
+ var _InitialiseMediaStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(duration, wsUrl) {
847
+ var _this = this;
848
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
849
+ while (1) switch (_context2.prev = _context2.next) {
843
850
  case 0:
844
- _context.next = 2;
851
+ this.currentDuration = duration;
852
+ this.currentWsUrl = wsUrl;
853
+ _context2.next = 4;
845
854
  return this.createMediaStreamSourceNode();
846
- case 2:
855
+ case 4:
847
856
  if (this.source) {
848
- _context.next = 5;
857
+ _context2.next = 7;
849
858
  break;
850
859
  }
851
860
  console.error("Error: unable to create source node");
852
- return _context.abrupt("return", false);
853
- case 5:
854
- _context.next = 7;
855
- return this.createProcessorNode();
861
+ return _context2.abrupt("return", false);
856
862
  case 7:
863
+ _context2.next = 9;
864
+ return this.createProcessorNode();
865
+ case 9:
857
866
  if (this.processorNode) {
858
- _context.next = 10;
867
+ _context2.next = 12;
859
868
  break;
860
869
  }
861
870
  console.error("Error: unable to create processor node");
862
- return _context.abrupt("return", false);
863
- case 10:
871
+ return _context2.abrupt("return", false);
872
+ case 12:
864
873
  this.source.connect(this.processorNode).connect(this.audioContext.destination);
865
874
  this.log("AudioContext Sample Rate: " + this.audioContext.sampleRate);
866
875
  if (wsUrl !== "") {
@@ -869,11 +878,39 @@ var Streamer = /*#__PURE__*/function () {
869
878
  // if (this.audioContext && this.audioContext.state == "running") {
870
879
  // await this.audioContext.suspend();
871
880
  // }
872
- case 13:
881
+ if (!this.deviceChangeHandler) {
882
+ this.deviceChangeHandler = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
883
+ var _this$audioStream, _this$audioStream$get;
884
+ var track;
885
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
886
+ while (1) switch (_context.prev = _context.next) {
887
+ case 0:
888
+ track = (_this$audioStream = _this.audioStream) === null || _this$audioStream === void 0 || (_this$audioStream$get = _this$audioStream.getAudioTracks) === null || _this$audioStream$get === void 0 ? void 0 : _this$audioStream$get.call(_this$audioStream)[0];
889
+ if (!(!track || track.readyState === "ended")) {
890
+ _context.next = 7;
891
+ break;
892
+ }
893
+ _this.log("Detected invalid audio track");
894
+ _this.micNeedsRecovery = true;
895
+ if (_this.isPaused) {
896
+ _context.next = 7;
897
+ break;
898
+ }
899
+ _context.next = 7;
900
+ return _this.recoverAudioGraph();
901
+ case 7:
902
+ case "end":
903
+ return _context.stop();
904
+ }
905
+ }, _callee);
906
+ }));
907
+ navigator.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
908
+ }
909
+ case 16:
873
910
  case "end":
874
- return _context.stop();
911
+ return _context2.stop();
875
912
  }
876
- }, _callee, this);
913
+ }, _callee2, this);
877
914
  }));
878
915
  function InitialiseMediaStream(_x, _x2) {
879
916
  return _InitialiseMediaStream.apply(this, arguments);
@@ -883,9 +920,9 @@ var Streamer = /*#__PURE__*/function () {
883
920
  }, {
884
921
  key: "StartStream",
885
922
  value: function () {
886
- var _StartStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(duration, wsUrl) {
887
- return _regeneratorRuntime().wrap(function _callee2$(_context2) {
888
- while (1) switch (_context2.prev = _context2.next) {
923
+ var _StartStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(duration, wsUrl) {
924
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
925
+ while (1) switch (_context3.prev = _context3.next) {
889
926
  case 0:
890
927
  this.log("New stream started...");
891
928
 
@@ -893,13 +930,13 @@ var Streamer = /*#__PURE__*/function () {
893
930
  // await this.createBufferedSourceNode();
894
931
  // Uncomment to stream microphone audio
895
932
  if (!(!this.shouldPreIntialiseRecorder || !this.source)) {
896
- _context2.next = 6;
933
+ _context3.next = 6;
897
934
  break;
898
935
  }
899
- _context2.next = 4;
936
+ _context3.next = 4;
900
937
  return this.InitialiseMediaStream(duration, wsUrl, false);
901
938
  case 4:
902
- _context2.next = 7;
939
+ _context3.next = 7;
903
940
  break;
904
941
  case 6:
905
942
  if (this.shouldPreIntialiseRecorder) {
@@ -907,30 +944,30 @@ var Streamer = /*#__PURE__*/function () {
907
944
  }
908
945
  case 7:
909
946
  if (!this.IsMicrophoneMuted) {
910
- _context2.next = 13;
947
+ _context3.next = 13;
911
948
  break;
912
949
  }
913
950
  if (!(this.audioContext && this.audioContext.state == "running")) {
914
- _context2.next = 11;
951
+ _context3.next = 11;
915
952
  break;
916
953
  }
917
- _context2.next = 11;
954
+ _context3.next = 11;
918
955
  return this.audioContext.suspend();
919
956
  case 11:
920
957
  this.onError(JSON.stringify({
921
958
  Type: "ERROR",
922
959
  Data: "Microphone is muted."
923
960
  }));
924
- return _context2.abrupt("return", false);
961
+ return _context3.abrupt("return", false);
925
962
  case 13:
926
963
  this.onStateChanged(true);
927
964
  this.isStreaming = true;
928
- return _context2.abrupt("return", true);
965
+ return _context3.abrupt("return", true);
929
966
  case 16:
930
967
  case "end":
931
- return _context2.stop();
968
+ return _context3.stop();
932
969
  }
933
- }, _callee2, this);
970
+ }, _callee3, this);
934
971
  }));
935
972
  function StartStream(_x3, _x4) {
936
973
  return _StartStream.apply(this, arguments);
@@ -940,21 +977,21 @@ var Streamer = /*#__PURE__*/function () {
940
977
  }, {
941
978
  key: "createBufferedSourceNode",
942
979
  value: function () {
943
- var _createBufferedSourceNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3() {
980
+ var _createBufferedSourceNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
944
981
  var audioBuffer;
945
- return _regeneratorRuntime().wrap(function _callee3$(_context3) {
946
- while (1) switch (_context3.prev = _context3.next) {
982
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
983
+ while (1) switch (_context4.prev = _context4.next) {
947
984
  case 0:
948
- _context3.next = 2;
985
+ _context4.next = 2;
949
986
  return this.loadAudio();
950
987
  case 2:
951
- audioBuffer = _context3.sent;
988
+ audioBuffer = _context4.sent;
952
989
  if (audioBuffer) {
953
- _context3.next = 6;
990
+ _context4.next = 6;
954
991
  break;
955
992
  }
956
993
  console.error("Error: unable to create audio buffer");
957
- return _context3.abrupt("return");
994
+ return _context4.abrupt("return");
958
995
  case 6:
959
996
  this.source = this.audioContext.createBufferSource();
960
997
  this.source.buffer = audioBuffer;
@@ -962,9 +999,9 @@ var Streamer = /*#__PURE__*/function () {
962
999
  this.source.start();
963
1000
  case 10:
964
1001
  case "end":
965
- return _context3.stop();
1002
+ return _context4.stop();
966
1003
  }
967
- }, _callee3, this);
1004
+ }, _callee4, this);
968
1005
  }));
969
1006
  function createBufferedSourceNode() {
970
1007
  return _createBufferedSourceNode.apply(this, arguments);
@@ -974,13 +1011,13 @@ var Streamer = /*#__PURE__*/function () {
974
1011
  }, {
975
1012
  key: "createMediaStreamSourceNode",
976
1013
  value: function () {
977
- var _createMediaStreamSourceNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
978
- var _this = this;
979
- var audioConstraints, errMessage;
980
- return _regeneratorRuntime().wrap(function _callee4$(_context4) {
981
- while (1) switch (_context4.prev = _context4.next) {
1014
+ var _createMediaStreamSourceNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
1015
+ var _this2 = this;
1016
+ var audioConstraints, track, errMessage;
1017
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
1018
+ while (1) switch (_context6.prev = _context6.next) {
982
1019
  case 0:
983
- _context4.prev = 0;
1020
+ _context6.prev = 0;
984
1021
  audioConstraints = {
985
1022
  channelCount: CHANNEL_COUNT,
986
1023
  noiseSuppression: this.noiseSuppression !== undefined ? this.noiseSuppression : NOISE_SUPPRESS_ENABLED
@@ -998,41 +1035,62 @@ var Streamer = /*#__PURE__*/function () {
998
1035
  audioConstraints.autoGainControl = this.autoGainControl;
999
1036
  audioConstraints.googAutoGainControl = this.autoGainControl;
1000
1037
  }
1001
- _context4.next = 7;
1038
+ _context6.next = 7;
1002
1039
  return navigator.mediaDevices.getUserMedia({
1003
1040
  audio: audioConstraints
1004
1041
  });
1005
1042
  case 7:
1006
- this.audioStream = _context4.sent;
1007
- console.log("Audio stream created with settings: ", this.audioStream.getAudioTracks()[0].getSettings());
1008
- this.audioContext = new AudioContext();
1043
+ this.audioStream = _context6.sent;
1044
+ if (!this.audioContext || this.audioContext.state === "closed") {
1045
+ this.audioContext = new AudioContext();
1046
+ }
1009
1047
  this.source = this.audioContext.createMediaStreamSource(this.audioStream);
1010
- this.audioStream.getAudioTracks()[0].addEventListener("ended", function () {
1011
- _this.onError(JSON.stringify({
1012
- Type: "ERROR",
1013
- Data: "Audio track ended. Possibly the mic was unplugged."
1014
- }));
1015
- });
1016
- _context4.next = 19;
1048
+ track = this.audioStream.getAudioTracks()[0];
1049
+ this.trackEndedHandler = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
1050
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
1051
+ while (1) switch (_context5.prev = _context5.next) {
1052
+ case 0:
1053
+ _this2.log("Microphone disconnected");
1054
+ _this2.micNeedsRecovery = true;
1055
+ _this2.onError(JSON.stringify({
1056
+ Type: "ERROR",
1057
+ Data: "Audio track ended. Possibly the mic was unplugged."
1058
+ }));
1059
+ if (_this2.isPaused) {
1060
+ _context5.next = 6;
1061
+ break;
1062
+ }
1063
+ _context5.next = 6;
1064
+ return _this2.recoverAudioGraph();
1065
+ case 6:
1066
+ case "end":
1067
+ return _context5.stop();
1068
+ }
1069
+ }, _callee5);
1070
+ }));
1071
+ track.addEventListener("ended", this.trackEndedHandler);
1072
+ _context6.next = 20;
1017
1073
  break;
1018
- case 14:
1019
- _context4.prev = 14;
1020
- _context4.t0 = _context4["catch"](0);
1074
+ case 15:
1075
+ _context6.prev = 15;
1076
+ _context6.t0 = _context6["catch"](0);
1021
1077
  errMessage = "";
1022
- if (_context4.t0.name == "NotAllowedError") {
1078
+ if (_context6.t0.name == "NotAllowedError") {
1023
1079
  errMessage = "Mic permission denied";
1024
- } else if (_context4.t0.name === "NotFoundError") {
1080
+ } else if (_context6.t0.name === "NotFoundError") {
1025
1081
  errMessage = "No suitable media device found";
1082
+ } else if (_context6.t0.name === "NotReadableError") {
1083
+ errMessage = "Microphone is being used by another application";
1026
1084
  }
1027
1085
  this.onError(JSON.stringify({
1028
1086
  Type: "ERROR",
1029
1087
  Data: errMessage
1030
1088
  }));
1031
- case 19:
1089
+ case 20:
1032
1090
  case "end":
1033
- return _context4.stop();
1091
+ return _context6.stop();
1034
1092
  }
1035
- }, _callee4, this, [[0, 14]]);
1093
+ }, _callee6, this, [[0, 15]]);
1036
1094
  }));
1037
1095
  function createMediaStreamSourceNode() {
1038
1096
  return _createMediaStreamSourceNode.apply(this, arguments);
@@ -1042,35 +1100,35 @@ var Streamer = /*#__PURE__*/function () {
1042
1100
  }, {
1043
1101
  key: "loadAudio",
1044
1102
  value: function () {
1045
- var _loadAudio = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
1103
+ var _loadAudio = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
1046
1104
  var response, arrayBuffer, audioBuffer;
1047
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
1048
- while (1) switch (_context5.prev = _context5.next) {
1105
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
1106
+ while (1) switch (_context7.prev = _context7.next) {
1049
1107
  case 0:
1050
- _context5.prev = 0;
1051
- _context5.next = 3;
1108
+ _context7.prev = 0;
1109
+ _context7.next = 3;
1052
1110
  return fetch("./radiology_speed_test.wav");
1053
1111
  case 3:
1054
- response = _context5.sent;
1055
- _context5.next = 6;
1112
+ response = _context7.sent;
1113
+ _context7.next = 6;
1056
1114
  return response.arrayBuffer();
1057
1115
  case 6:
1058
- arrayBuffer = _context5.sent;
1059
- _context5.next = 9;
1116
+ arrayBuffer = _context7.sent;
1117
+ _context7.next = 9;
1060
1118
  return this.audioContext.decodeAudioData(arrayBuffer);
1061
1119
  case 9:
1062
- audioBuffer = _context5.sent;
1063
- return _context5.abrupt("return", audioBuffer);
1120
+ audioBuffer = _context7.sent;
1121
+ return _context7.abrupt("return", audioBuffer);
1064
1122
  case 13:
1065
- _context5.prev = 13;
1066
- _context5.t0 = _context5["catch"](0);
1067
- console.error("Unable to fetch the audio file. Error: ".concat(_context5.t0.message));
1068
- return _context5.abrupt("return", null);
1123
+ _context7.prev = 13;
1124
+ _context7.t0 = _context7["catch"](0);
1125
+ console.error("Unable to fetch the audio file. Error: ".concat(_context7.t0.message));
1126
+ return _context7.abrupt("return", null);
1069
1127
  case 17:
1070
1128
  case "end":
1071
- return _context5.stop();
1129
+ return _context7.stop();
1072
1130
  }
1073
- }, _callee5, this, [[0, 13]]);
1131
+ }, _callee7, this, [[0, 13]]);
1074
1132
  }));
1075
1133
  function loadAudio() {
1076
1134
  return _loadAudio.apply(this, arguments);
@@ -1080,14 +1138,14 @@ var Streamer = /*#__PURE__*/function () {
1080
1138
  }, {
1081
1139
  key: "createProcessorNode",
1082
1140
  value: function () {
1083
- var _createProcessorNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6() {
1084
- var _this2 = this;
1141
+ var _createProcessorNode = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
1142
+ var _this3 = this;
1085
1143
  var _this$shouldReadInten, sampleRateParam, bufferSizeIntervalParam, pausedBufferIntervalParam, shouldReadIntensityParam;
1086
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
1087
- while (1) switch (_context6.prev = _context6.next) {
1144
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
1145
+ while (1) switch (_context8.prev = _context8.next) {
1088
1146
  case 0:
1089
- _context6.prev = 0;
1090
- _context6.next = 3;
1147
+ _context8.prev = 0;
1148
+ _context8.next = 3;
1091
1149
  return this.audioContext.audioWorklet.addModule("data:application/javascript,".concat(encodeURIComponent(worklet)));
1092
1150
  case 3:
1093
1151
  this.processorNode = new AudioWorkletNode(this.audioContext, WORKLET_PROCESSOR);
@@ -1105,47 +1163,47 @@ var Streamer = /*#__PURE__*/function () {
1105
1163
  type = _event$data.type,
1106
1164
  value = _event$data.value;
1107
1165
  if (type == DONE_MSG) {
1108
- _this2.log("Worklet processing done, clearing resources...");
1166
+ _this3.log("Worklet processing done, clearing resources...");
1109
1167
 
1110
1168
  // Uncomment to save recording
1111
- if (_this2.isDebug) _this2.saveAudio();
1112
- _this2.cleanup();
1169
+ if (_this3.isDebug) _this3.saveAudio();
1170
+ _this3.cleanup();
1113
1171
  } else if (event.data == PAUSE_SOCKET_MSG) {
1114
- _this2.executor.Send(PAUSE_SOCKET_MSG);
1172
+ _this3.executor.Send(PAUSE_SOCKET_MSG);
1115
1173
  }
1116
1174
  // Uncomment to save recording
1117
1175
  else {
1118
1176
  if (type === "intensity") {
1119
- var _this2$onIntensity;
1120
- (_this2$onIntensity = _this2.onIntensity) === null || _this2$onIntensity === void 0 || _this2$onIntensity.call(_this2, value);
1177
+ var _this3$onIntensity;
1178
+ (_this3$onIntensity = _this3.onIntensity) === null || _this3$onIntensity === void 0 || _this3$onIntensity.call(_this3, value);
1121
1179
  } else if (type === "audioData") {
1122
- if (_this2.isDebug) {
1180
+ if (_this3.isDebug) {
1123
1181
  new Int16Array(value).forEach(function (element) {
1124
- if (_this2.audioData.length <= MAX_AUDIO_SAMPLES) _this2.audioData.push(element);
1182
+ if (_this3.audioData.length <= MAX_AUDIO_SAMPLES) _this3.audioData.push(element);
1125
1183
  });
1126
1184
  }
1127
1185
  }
1128
1186
  }
1129
- if (_this2.executor) {
1130
- if (_this2.closeSocketWithoutEOS) {
1131
- _this2.executor.Send(CLOSE_MSG);
1132
- _this2.closeSocketWithoutEOS = false;
1187
+ if (_this3.executor) {
1188
+ if (_this3.closeSocketWithoutEOS) {
1189
+ _this3.executor.Send(CLOSE_MSG);
1190
+ _this3.closeSocketWithoutEOS = false;
1133
1191
  } else {
1134
- if (type !== "intensity") _this2.executor.Send(value);
1192
+ if (type !== "intensity") _this3.executor.Send(value);
1135
1193
  }
1136
1194
  }
1137
1195
  };
1138
- _context6.next = 18;
1196
+ _context8.next = 18;
1139
1197
  break;
1140
1198
  case 15:
1141
- _context6.prev = 15;
1142
- _context6.t0 = _context6["catch"](0);
1143
- console.error("Error: Unable to create worklet node: ", _context6.t0);
1199
+ _context8.prev = 15;
1200
+ _context8.t0 = _context8["catch"](0);
1201
+ console.error("Error: Unable to create worklet node: ", _context8.t0);
1144
1202
  case 18:
1145
1203
  case "end":
1146
- return _context6.stop();
1204
+ return _context8.stop();
1147
1205
  }
1148
- }, _callee6, this, [[0, 15]]);
1206
+ }, _callee8, this, [[0, 15]]);
1149
1207
  }));
1150
1208
  function createProcessorNode() {
1151
1209
  return _createProcessorNode.apply(this, arguments);
@@ -1155,25 +1213,25 @@ var Streamer = /*#__PURE__*/function () {
1155
1213
  }, {
1156
1214
  key: "PauseStream",
1157
1215
  value: function () {
1158
- var _PauseStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7() {
1159
- return _regeneratorRuntime().wrap(function _callee7$(_context7) {
1160
- while (1) switch (_context7.prev = _context7.next) {
1216
+ var _PauseStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
1217
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
1218
+ while (1) switch (_context9.prev = _context9.next) {
1161
1219
  case 0:
1162
1220
  if (!(this.audioContext.state == "running")) {
1163
- _context7.next = 9;
1221
+ _context9.next = 9;
1164
1222
  break;
1165
1223
  }
1166
1224
  if (this.shouldPreIntialiseRecorder) {
1167
- _context7.next = 8;
1225
+ _context9.next = 8;
1168
1226
  break;
1169
1227
  }
1170
- _context7.next = 4;
1228
+ _context9.next = 4;
1171
1229
  return this.audioContext.suspend();
1172
1230
  case 4:
1173
1231
  this.log("Stream paused...");
1174
1232
  // message sent to worklet-thread
1175
1233
  this.processorNode.port.postMessage(PAUSE_MSG);
1176
- _context7.next = 9;
1234
+ _context9.next = 9;
1177
1235
  break;
1178
1236
  case 8:
1179
1237
  this.processorNode.port.postMessage(PAUSE_SOCKET_MSG);
@@ -1183,9 +1241,9 @@ var Streamer = /*#__PURE__*/function () {
1183
1241
  this.isStreaming = false;
1184
1242
  case 12:
1185
1243
  case "end":
1186
- return _context7.stop();
1244
+ return _context9.stop();
1187
1245
  }
1188
- }, _callee7, this);
1246
+ }, _callee9, this);
1189
1247
  }));
1190
1248
  function PauseStream() {
1191
1249
  return _PauseStream.apply(this, arguments);
@@ -1195,42 +1253,54 @@ var Streamer = /*#__PURE__*/function () {
1195
1253
  }, {
1196
1254
  key: "ResumeStream",
1197
1255
  value: function () {
1198
- var _ResumeStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8() {
1199
- return _regeneratorRuntime().wrap(function _callee8$(_context8) {
1200
- while (1) switch (_context8.prev = _context8.next) {
1256
+ var _ResumeStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10() {
1257
+ var _this$audioStream2, _this$audioStream2$ge;
1258
+ var track, trackEnded;
1259
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
1260
+ while (1) switch (_context10.prev = _context10.next) {
1201
1261
  case 0:
1262
+ track = (_this$audioStream2 = this.audioStream) === null || _this$audioStream2 === void 0 || (_this$audioStream2$ge = _this$audioStream2.getAudioTracks) === null || _this$audioStream2$ge === void 0 ? void 0 : _this$audioStream2$ge.call(_this$audioStream2)[0];
1263
+ trackEnded = !track || track.readyState === "ended";
1264
+ if (!(trackEnded || this.micNeedsRecovery)) {
1265
+ _context10.next = 6;
1266
+ break;
1267
+ }
1268
+ this.log("Recovering before resume");
1269
+ _context10.next = 6;
1270
+ return this.recoverAudioGraph();
1271
+ case 6:
1202
1272
  if (!(!this.shouldPreIntialiseRecorder && this.audioContext.state == "suspended")) {
1203
- _context8.next = 9;
1273
+ _context10.next = 15;
1204
1274
  break;
1205
1275
  }
1206
1276
  if (!this.IsMicrophoneMuted) {
1207
- _context8.next = 4;
1277
+ _context10.next = 10;
1208
1278
  break;
1209
1279
  }
1210
1280
  this.onError(JSON.stringify({
1211
1281
  Type: "ERROR",
1212
1282
  Data: "Microphone is muted."
1213
1283
  }));
1214
- return _context8.abrupt("return");
1215
- case 4:
1216
- _context8.next = 6;
1284
+ return _context10.abrupt("return");
1285
+ case 10:
1286
+ _context10.next = 12;
1217
1287
  return this.audioContext.resume();
1218
- case 6:
1288
+ case 12:
1219
1289
  this.log("Stream resumed...");
1220
- _context8.next = 11;
1290
+ _context10.next = 17;
1221
1291
  break;
1222
- case 9:
1292
+ case 15:
1223
1293
  this.processorNode.port.postMessage(RESUME_SOCKET_MSG);
1224
1294
  this.executor.Send(RESUME_SOCKET_MSG);
1225
- case 11:
1295
+ case 17:
1226
1296
  this.onStateChanged(true);
1227
1297
  this.isPaused = false;
1228
1298
  this.isStreaming = true;
1229
- case 14:
1299
+ case 20:
1230
1300
  case "end":
1231
- return _context8.stop();
1301
+ return _context10.stop();
1232
1302
  }
1233
- }, _callee8, this);
1303
+ }, _callee10, this);
1234
1304
  }));
1235
1305
  function ResumeStream() {
1236
1306
  return _ResumeStream.apply(this, arguments);
@@ -1250,22 +1320,27 @@ var Streamer = /*#__PURE__*/function () {
1250
1320
  }, {
1251
1321
  key: "IsMicrophoneMuted",
1252
1322
  get: function get() {
1253
- return this.audioStream.getAudioTracks()[0].muted;
1323
+ var _this$audioStream3, _this$audioStream3$ge;
1324
+ var track = (_this$audioStream3 = this.audioStream) === null || _this$audioStream3 === void 0 || (_this$audioStream3$ge = _this$audioStream3.getAudioTracks) === null || _this$audioStream3$ge === void 0 ? void 0 : _this$audioStream3$ge.call(_this$audioStream3)[0];
1325
+ if (!track) {
1326
+ return true;
1327
+ }
1328
+ return track.muted || track.readyState === "ended";
1254
1329
  }
1255
1330
  }, {
1256
1331
  key: "StopStream",
1257
1332
  value: function () {
1258
- var _StopStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9(shouldSendEOS) {
1259
- var _this$audioContext, _this$processorNode, _this$audioStream;
1333
+ var _StopStream = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee11(shouldSendEOS) {
1334
+ var _this$audioContext, _this$processorNode, _this$audioStream4;
1260
1335
  var _this$audioContext2;
1261
- return _regeneratorRuntime().wrap(function _callee9$(_context9) {
1262
- while (1) switch (_context9.prev = _context9.next) {
1336
+ return _regeneratorRuntime().wrap(function _callee11$(_context11) {
1337
+ while (1) switch (_context11.prev = _context11.next) {
1263
1338
  case 0:
1264
1339
  if (!(((_this$audioContext = this.audioContext) === null || _this$audioContext === void 0 ? void 0 : _this$audioContext.state) !== "suspended")) {
1265
- _context9.next = 4;
1340
+ _context11.next = 4;
1266
1341
  break;
1267
1342
  }
1268
- _context9.next = 3;
1343
+ _context11.next = 3;
1269
1344
  return (_this$audioContext2 = this.audioContext) === null || _this$audioContext2 === void 0 ? void 0 : _this$audioContext2.suspend();
1270
1345
  case 3:
1271
1346
  this.onStateChanged(false);
@@ -1275,18 +1350,106 @@ var Streamer = /*#__PURE__*/function () {
1275
1350
  this.closeSocketWithoutEOS = !shouldSendEOS;
1276
1351
  // message sent to worklet-thread
1277
1352
  (_this$processorNode = this.processorNode) === null || _this$processorNode === void 0 || (_this$processorNode = _this$processorNode.port) === null || _this$processorNode === void 0 || _this$processorNode.postMessage(STOP_MSG);
1278
- (_this$audioStream = this.audioStream) === null || _this$audioStream === void 0 || _this$audioStream.getAudioTracks()[0].removeEventListener("ended", function () {});
1353
+ (_this$audioStream4 = this.audioStream) === null || _this$audioStream4 === void 0 || _this$audioStream4.getAudioTracks()[0].removeEventListener("ended", function () {});
1279
1354
  case 9:
1280
1355
  case "end":
1281
- return _context9.stop();
1356
+ return _context11.stop();
1282
1357
  }
1283
- }, _callee9, this);
1358
+ }, _callee11, this);
1284
1359
  }));
1285
1360
  function StopStream(_x5) {
1286
1361
  return _StopStream.apply(this, arguments);
1287
1362
  }
1288
1363
  return StopStream;
1289
1364
  }()
1365
+ }, {
1366
+ key: "recoverAudioGraph",
1367
+ value: function () {
1368
+ var _recoverAudioGraph = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee12() {
1369
+ var _this$audioStream5, _this$source, _this$processorNode2;
1370
+ return _regeneratorRuntime().wrap(function _callee12$(_context12) {
1371
+ while (1) switch (_context12.prev = _context12.next) {
1372
+ case 0:
1373
+ if (!this.isRecovering) {
1374
+ _context12.next = 2;
1375
+ break;
1376
+ }
1377
+ return _context12.abrupt("return");
1378
+ case 2:
1379
+ this.isRecovering = true;
1380
+ _context12.prev = 3;
1381
+ this.log("Recovering audio graph...");
1382
+
1383
+ // stop old track
1384
+ (_this$audioStream5 = this.audioStream) === null || _this$audioStream5 === void 0 || (_this$audioStream5 = _this$audioStream5.getTracks()) === null || _this$audioStream5 === void 0 || _this$audioStream5.forEach(function (t) {
1385
+ try {
1386
+ t.stop();
1387
+ } catch (_unused) {}
1388
+ });
1389
+
1390
+ // disconnect source
1391
+ try {
1392
+ (_this$source = this.source) === null || _this$source === void 0 || _this$source.disconnect();
1393
+ } catch (_unused2) {}
1394
+
1395
+ // disconnect processor
1396
+ try {
1397
+ (_this$processorNode2 = this.processorNode) === null || _this$processorNode2 === void 0 || _this$processorNode2.disconnect();
1398
+ } catch (_unused3) {}
1399
+
1400
+ // recreate media stream ONLY
1401
+ _context12.next = 10;
1402
+ return this.createMediaStreamSourceNode();
1403
+ case 10:
1404
+ if (this.source) {
1405
+ _context12.next = 12;
1406
+ break;
1407
+ }
1408
+ throw new Error("Failed to recreate source");
1409
+ case 12:
1410
+ // AudioContext may become closed/suspended
1411
+ if (!this.audioContext || this.audioContext.state === "closed") {
1412
+ this.audioContext = new AudioContext();
1413
+ }
1414
+ if (!(this.audioContext.state === "suspended")) {
1415
+ _context12.next = 16;
1416
+ break;
1417
+ }
1418
+ _context12.next = 16;
1419
+ return this.audioContext.resume();
1420
+ case 16:
1421
+ _context12.next = 18;
1422
+ return this.createProcessorNode();
1423
+ case 18:
1424
+ // reconnect graph
1425
+ this.source.connect(this.processorNode).connect(this.audioContext.destination);
1426
+ this.micNeedsRecovery = false;
1427
+ this.log("Audio graph recovery completed");
1428
+ _context12.next = 27;
1429
+ break;
1430
+ case 23:
1431
+ _context12.prev = 23;
1432
+ _context12.t0 = _context12["catch"](3);
1433
+ console.error("Recovery failed", _context12.t0);
1434
+ this.onError(JSON.stringify({
1435
+ Type: "ERROR",
1436
+ Data: "Failed to recover microphone"
1437
+ }));
1438
+ case 27:
1439
+ _context12.prev = 27;
1440
+ this.isRecovering = false;
1441
+ return _context12.finish(27);
1442
+ case 30:
1443
+ case "end":
1444
+ return _context12.stop();
1445
+ }
1446
+ }, _callee12, this, [[3, 23, 27, 30]]);
1447
+ }));
1448
+ function recoverAudioGraph() {
1449
+ return _recoverAudioGraph.apply(this, arguments);
1450
+ }
1451
+ return recoverAudioGraph;
1452
+ }()
1290
1453
  }, {
1291
1454
  key: "IntentStartStream",
1292
1455
  value: function IntentStartStream() {
@@ -1295,10 +1458,15 @@ var Streamer = /*#__PURE__*/function () {
1295
1458
  }, {
1296
1459
  key: "cleanup",
1297
1460
  value: function cleanup() {
1461
+ var _this$audioStream6;
1298
1462
  // Uncomment to stop recorded audio
1299
1463
  // this.source.stop();
1300
1464
  // Uncomment to stop microphone audio
1301
- this.source.mediaStream.getAudioTracks()[0].stop();
1465
+ (_this$audioStream6 = this.audioStream) === null || _this$audioStream6 === void 0 || (_this$audioStream6 = _this$audioStream6.getTracks()) === null || _this$audioStream6 === void 0 || _this$audioStream6.forEach(function (track) {
1466
+ try {
1467
+ track.stop();
1468
+ } catch (_unused4) {}
1469
+ });
1302
1470
  this.source.disconnect();
1303
1471
  this.processorNode.disconnect();
1304
1472
  this.processorNode.port.close();