videomail-client 13.14.1 → 13.15.1

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.
@@ -10876,7 +10876,7 @@ var __webpack_exports__ = {};
10876
10876
  var client = __webpack_require__(5734);
10877
10877
  var client_default = /*#__PURE__*/ __webpack_require__.n(client);
10878
10878
  var package_namespaceObject = {
10879
- rE: "13.14.1"
10879
+ rE: "13.15.1"
10880
10880
  };
10881
10881
  function isAudioEnabled(options) {
10882
10882
  return Boolean(options.audio.enabled);
@@ -17026,6 +17026,20 @@ var __webpack_exports__ = {};
17026
17026
  "volumechange"
17027
17027
  ];
17028
17028
  const mediaEvents = MEDIA_EVENTS;
17029
+ const VIRTUAL_KEYWORDS = [
17030
+ "obs",
17031
+ "virtual",
17032
+ "manycam",
17033
+ "vcam",
17034
+ "splitcam",
17035
+ "droidcam"
17036
+ ];
17037
+ function isVirtualCamera(videoTrack) {
17038
+ const capabilities = videoTrack.getCapabilities();
17039
+ if (!capabilities.frameRate) return true;
17040
+ return VIRTUAL_KEYWORDS.some((keyword)=>videoTrack.label.toLowerCase().includes(keyword));
17041
+ }
17042
+ const util_isVirtualCamera = isVirtualCamera;
17029
17043
  function userMedia_define_property(obj, key, value) {
17030
17044
  if (key in obj) Object.defineProperty(obj, key, {
17031
17045
  value: value,
@@ -17096,6 +17110,7 @@ var __webpack_exports__ = {};
17096
17110
  this.onPlayReached = false;
17097
17111
  this.onLoadedMetaDataReached = false;
17098
17112
  this.playingPromiseReached = false;
17113
+ this.videoTrackLabel = void 0;
17099
17114
  if (isAudioEnabled(this.options)) null != this.audioRecorder || (this.audioRecorder = new media_AudioRecorder(this, this.options));
17100
17115
  const unloadAllEventListeners = ()=>{
17101
17116
  var _this_rawVisualUserMedia, _this_rawVisualUserMedia1;
@@ -17193,12 +17208,19 @@ var __webpack_exports__ = {};
17193
17208
  try {
17194
17209
  var _this_rawVisualUserMedia, _this_rawVisualUserMedia1, _this_rawVisualUserMedia2;
17195
17210
  const videoTrack = media_getFirstVideoTrack(localMediaStream);
17196
- if (videoTrack) if (videoTrack.enabled) {
17211
+ this.videoTrackLabel = null == videoTrack ? void 0 : videoTrack.label;
17212
+ if (videoTrack) if (videoTrack.enabled) if (util_isVirtualCamera(videoTrack)) throw error_createError({
17213
+ message: "Virtual cameras are not allowed.",
17214
+ explanation: `Please use a real camera, not "${videoTrack.label}".`,
17215
+ options: this.options
17216
+ });
17217
+ else {
17197
17218
  let description = "";
17198
- if (videoTrack.label && videoTrack.label.length > 0) description = description.concat(videoTrack.label);
17219
+ if (videoTrack.label.length > 0) description = description.concat(videoTrack.label);
17199
17220
  description = description.concat(` with enabled=${videoTrack.enabled}, muted=${videoTrack.muted}, readyState=${videoTrack.readyState}`);
17200
17221
  this.options.logger.debug(`UserMedia: ${videoTrack.kind} detected. ${description}`);
17201
- } else throw error_createError({
17222
+ }
17223
+ else throw error_createError({
17202
17224
  message: "Webcam is disabled",
17203
17225
  explanation: "The video track seems to be disabled. Enable it in your system.",
17204
17226
  options: this.options
@@ -17217,6 +17239,9 @@ var __webpack_exports__ = {};
17217
17239
  });
17218
17240
  }
17219
17241
  }
17242
+ getVideoTrackLabel() {
17243
+ return this.videoTrackLabel;
17244
+ }
17220
17245
  isReady() {
17221
17246
  var _this_rawVisualUserMedia;
17222
17247
  return Boolean(null == (_this_rawVisualUserMedia = this.rawVisualUserMedia) ? void 0 : _this_rawVisualUserMedia.src);
@@ -17323,7 +17348,7 @@ var __webpack_exports__ = {};
17323
17348
  };
17324
17349
  }
17325
17350
  constructor(recorder, options){
17326
- super("UserMedia", options), userMedia_define_property(this, "recorder", void 0), userMedia_define_property(this, "rawVisualUserMedia", void 0), userMedia_define_property(this, "paused", false), userMedia_define_property(this, "recording", false), userMedia_define_property(this, "audioRecorder", void 0), userMedia_define_property(this, "currentVisualStream", void 0), userMedia_define_property(this, "onPlayReached", false), userMedia_define_property(this, "onLoadedMetaDataReached", false), userMedia_define_property(this, "playingPromiseReached", false);
17351
+ super("UserMedia", options), userMedia_define_property(this, "recorder", void 0), userMedia_define_property(this, "rawVisualUserMedia", void 0), userMedia_define_property(this, "paused", false), userMedia_define_property(this, "recording", false), userMedia_define_property(this, "audioRecorder", void 0), userMedia_define_property(this, "currentVisualStream", void 0), userMedia_define_property(this, "onPlayReached", false), userMedia_define_property(this, "onLoadedMetaDataReached", false), userMedia_define_property(this, "playingPromiseReached", false), userMedia_define_property(this, "videoTrackLabel", void 0);
17327
17352
  this.recorder = recorder;
17328
17353
  this.rawVisualUserMedia = recorder.getRawVisualUserMedia();
17329
17354
  mediaEvents.forEach((eventName)=>{
@@ -17896,6 +17921,7 @@ var __webpack_exports__ = {};
17896
17921
  framesCount: this.framesCount,
17897
17922
  videoType
17898
17923
  };
17924
+ if (this.userMedia) this.recordingStats.videoTrackLabel = this.userMedia.getVideoTrackLabel();
17899
17925
  if (isAudioEnabled(this.options) && this.userMedia) {
17900
17926
  this.recordingStats.samplesCount = this.samplesCount;
17901
17927
  this.recordingStats.sampleRate = this.userMedia.getAudioSampleRate();
@@ -19031,6 +19057,7 @@ var __webpack_exports__ = {};
19031
19057
  else if (params.exc.message) this.options.logger.error(params.exc.message);
19032
19058
  } else this.options.logger.error(params.exc);
19033
19059
  if (this.options.displayErrors && params.err) this.visuals.error(params.err);
19060
+ else if (this.options.displayErrors && params.exc && params.exc instanceof error_VideomailError) this.visuals.error(params.exc);
19034
19061
  else this.visuals.reset();
19035
19062
  }
19036
19063
  initEvents(playerOnly = false) {
package/dist/esm/index.js CHANGED
@@ -3617,7 +3617,7 @@ const constants = {
3617
3617
  }
3618
3618
  };
3619
3619
  var package_namespaceObject = {
3620
- rE: "13.14.1"
3620
+ rE: "13.15.1"
3621
3621
  };
3622
3622
  function isAudioEnabled(options) {
3623
3623
  return Boolean(options.audio.enabled);
@@ -6173,6 +6173,20 @@ const MEDIA_EVENTS = [
6173
6173
  "volumechange"
6174
6174
  ];
6175
6175
  const mediaEvents = MEDIA_EVENTS;
6176
+ const VIRTUAL_KEYWORDS = [
6177
+ "obs",
6178
+ "virtual",
6179
+ "manycam",
6180
+ "vcam",
6181
+ "splitcam",
6182
+ "droidcam"
6183
+ ];
6184
+ function isVirtualCamera(videoTrack) {
6185
+ const capabilities = videoTrack.getCapabilities();
6186
+ if (!capabilities.frameRate) return true;
6187
+ return VIRTUAL_KEYWORDS.some((keyword)=>videoTrack.label.toLowerCase().includes(keyword));
6188
+ }
6189
+ const util_isVirtualCamera = isVirtualCamera;
6176
6190
  function userMedia_define_property(obj, key, value) {
6177
6191
  if (key in obj) Object.defineProperty(obj, key, {
6178
6192
  value: value,
@@ -6237,6 +6251,7 @@ class UserMedia extends util_Despot {
6237
6251
  this.onPlayReached = false;
6238
6252
  this.onLoadedMetaDataReached = false;
6239
6253
  this.playingPromiseReached = false;
6254
+ this.videoTrackLabel = void 0;
6240
6255
  if (isAudioEnabled(this.options)) this.audioRecorder ??= new media_AudioRecorder(this, this.options);
6241
6256
  const unloadAllEventListeners = ()=>{
6242
6257
  this.options.logger.debug("UserMedia: unloadAllEventListeners()");
@@ -6328,12 +6343,19 @@ class UserMedia extends util_Despot {
6328
6343
  };
6329
6344
  try {
6330
6345
  const videoTrack = media_getFirstVideoTrack(localMediaStream);
6331
- if (videoTrack) if (videoTrack.enabled) {
6346
+ this.videoTrackLabel = videoTrack?.label;
6347
+ if (videoTrack) if (videoTrack.enabled) if (util_isVirtualCamera(videoTrack)) throw error_createError({
6348
+ message: "Virtual cameras are not allowed.",
6349
+ explanation: `Please use a real camera, not "${videoTrack.label}".`,
6350
+ options: this.options
6351
+ });
6352
+ else {
6332
6353
  let description = "";
6333
- if (videoTrack.label && videoTrack.label.length > 0) description = description.concat(videoTrack.label);
6354
+ if (videoTrack.label.length > 0) description = description.concat(videoTrack.label);
6334
6355
  description = description.concat(` with enabled=${videoTrack.enabled}, muted=${videoTrack.muted}, readyState=${videoTrack.readyState}`);
6335
6356
  this.options.logger.debug(`UserMedia: ${videoTrack.kind} detected. ${description}`);
6336
- } else throw error_createError({
6357
+ }
6358
+ else throw error_createError({
6337
6359
  message: "Webcam is disabled",
6338
6360
  explanation: "The video track seems to be disabled. Enable it in your system.",
6339
6361
  options: this.options
@@ -6352,6 +6374,9 @@ class UserMedia extends util_Despot {
6352
6374
  });
6353
6375
  }
6354
6376
  }
6377
+ getVideoTrackLabel() {
6378
+ return this.videoTrackLabel;
6379
+ }
6355
6380
  isReady() {
6356
6381
  return Boolean(this.rawVisualUserMedia?.src);
6357
6382
  }
@@ -6455,7 +6480,7 @@ class UserMedia extends util_Despot {
6455
6480
  };
6456
6481
  }
6457
6482
  constructor(recorder, options){
6458
- super("UserMedia", options), userMedia_define_property(this, "recorder", void 0), userMedia_define_property(this, "rawVisualUserMedia", void 0), userMedia_define_property(this, "paused", false), userMedia_define_property(this, "recording", false), userMedia_define_property(this, "audioRecorder", void 0), userMedia_define_property(this, "currentVisualStream", void 0), userMedia_define_property(this, "onPlayReached", false), userMedia_define_property(this, "onLoadedMetaDataReached", false), userMedia_define_property(this, "playingPromiseReached", false);
6483
+ super("UserMedia", options), userMedia_define_property(this, "recorder", void 0), userMedia_define_property(this, "rawVisualUserMedia", void 0), userMedia_define_property(this, "paused", false), userMedia_define_property(this, "recording", false), userMedia_define_property(this, "audioRecorder", void 0), userMedia_define_property(this, "currentVisualStream", void 0), userMedia_define_property(this, "onPlayReached", false), userMedia_define_property(this, "onLoadedMetaDataReached", false), userMedia_define_property(this, "playingPromiseReached", false), userMedia_define_property(this, "videoTrackLabel", void 0);
6459
6484
  this.recorder = recorder;
6460
6485
  this.rawVisualUserMedia = recorder.getRawVisualUserMedia();
6461
6486
  mediaEvents.forEach((eventName)=>{
@@ -7020,6 +7045,7 @@ class Recorder extends util_Despot {
7020
7045
  framesCount: this.framesCount,
7021
7046
  videoType
7022
7047
  };
7048
+ if (this.userMedia) this.recordingStats.videoTrackLabel = this.userMedia.getVideoTrackLabel();
7023
7049
  if (isAudioEnabled(this.options) && this.userMedia) {
7024
7050
  this.recordingStats.samplesCount = this.samplesCount;
7025
7051
  this.recordingStats.sampleRate = this.userMedia.getAudioSampleRate();
@@ -8093,6 +8119,7 @@ class Container extends util_Despot {
8093
8119
  else if (params.exc.message) this.options.logger.error(params.exc.message);
8094
8120
  } else this.options.logger.error(params.exc);
8095
8121
  if (this.options.displayErrors && params.err) this.visuals.error(params.err);
8122
+ else if (this.options.displayErrors && params.exc && params.exc instanceof error_VideomailError) this.visuals.error(params.exc);
8096
8123
  else this.visuals.reset();
8097
8124
  }
8098
8125
  initEvents(playerOnly = false) {
@@ -9,5 +9,6 @@ interface RecordingStats {
9
9
  waitingTime?: number | undefined;
10
10
  wantedFps?: number;
11
11
  wantedInterval?: number;
12
+ videoTrackLabel?: string | undefined;
12
13
  }
13
14
  export type { RecordingStats };
@@ -0,0 +1,2 @@
1
+ declare function isVirtualCamera(videoTrack: MediaStreamTrack): boolean;
2
+ export default isVirtualCamera;
@@ -140,6 +140,7 @@ declare class Form extends Despot {
140
140
  waitingTime?: number | undefined | undefined;
141
141
  wantedFps?: number;
142
142
  wantedInterval?: number;
143
+ videoTrackLabel?: string | undefined | undefined;
143
144
  } | undefined;
144
145
  recordLocation?: string | undefined | undefined;
145
146
  parentKey?: string | undefined | undefined;
@@ -325,6 +326,7 @@ declare class Form extends Despot {
325
326
  waitingTime?: number | undefined | undefined;
326
327
  wantedFps?: number;
327
328
  wantedInterval?: number;
329
+ videoTrackLabel?: string | undefined | undefined;
328
330
  } | undefined;
329
331
  recordLocation?: string | undefined | undefined;
330
332
  parentKey?: string | undefined | undefined;
@@ -17,6 +17,7 @@ declare class UserMedia extends Despot {
17
17
  private onPlayReached;
18
18
  private onLoadedMetaDataReached;
19
19
  private playingPromiseReached;
20
+ private videoTrackLabel?;
20
21
  constructor(recorder: Recorder, options: VideomailClientOptions);
21
22
  private attachMediaStream;
22
23
  private setVisualStream;
@@ -27,6 +28,7 @@ declare class UserMedia extends Despot {
27
28
  unloadRemainingEventListeners(): void;
28
29
  private audioRecord;
29
30
  init(localMediaStream: MediaStream, videoCallback: () => void, audioCallback: AudioProcessCB, endedEarlyCallback: (err: any) => void, switchingFacingMode?: ConstrainDOMString): void;
31
+ getVideoTrackLabel(): string | undefined;
30
32
  isReady(): boolean;
31
33
  stop(visualStream?: MediaStream, params?: StopParams): void;
32
34
  createCanvas(): HTMLCanvasElement;
package/dist/umd/index.js CHANGED
@@ -10882,7 +10882,7 @@
10882
10882
  var client = __webpack_require__(5734);
10883
10883
  var client_default = /*#__PURE__*/ __webpack_require__.n(client);
10884
10884
  var package_namespaceObject = {
10885
- rE: "13.14.1"
10885
+ rE: "13.15.1"
10886
10886
  };
10887
10887
  function isAudioEnabled(options) {
10888
10888
  return Boolean(options.audio.enabled);
@@ -16779,6 +16779,20 @@
16779
16779
  "volumechange"
16780
16780
  ];
16781
16781
  const mediaEvents = MEDIA_EVENTS;
16782
+ const VIRTUAL_KEYWORDS = [
16783
+ "obs",
16784
+ "virtual",
16785
+ "manycam",
16786
+ "vcam",
16787
+ "splitcam",
16788
+ "droidcam"
16789
+ ];
16790
+ function isVirtualCamera(videoTrack) {
16791
+ const capabilities = videoTrack.getCapabilities();
16792
+ if (!capabilities.frameRate) return true;
16793
+ return VIRTUAL_KEYWORDS.some((keyword)=>videoTrack.label.toLowerCase().includes(keyword));
16794
+ }
16795
+ const util_isVirtualCamera = isVirtualCamera;
16782
16796
  const EVENT_ASCII = "|—O—|";
16783
16797
  class UserMedia extends util_Despot {
16784
16798
  recorder;
@@ -16790,6 +16804,7 @@
16790
16804
  onPlayReached = false;
16791
16805
  onLoadedMetaDataReached = false;
16792
16806
  playingPromiseReached = false;
16807
+ videoTrackLabel;
16793
16808
  constructor(recorder, options){
16794
16809
  super("UserMedia", options);
16795
16810
  this.recorder = recorder;
@@ -16850,6 +16865,7 @@
16850
16865
  this.onPlayReached = false;
16851
16866
  this.onLoadedMetaDataReached = false;
16852
16867
  this.playingPromiseReached = false;
16868
+ this.videoTrackLabel = void 0;
16853
16869
  if (isAudioEnabled(this.options)) this.audioRecorder ??= new media_AudioRecorder(this, this.options);
16854
16870
  const unloadAllEventListeners = ()=>{
16855
16871
  this.options.logger.debug("UserMedia: unloadAllEventListeners()");
@@ -16941,12 +16957,19 @@
16941
16957
  };
16942
16958
  try {
16943
16959
  const videoTrack = media_getFirstVideoTrack(localMediaStream);
16944
- if (videoTrack) if (videoTrack.enabled) {
16960
+ this.videoTrackLabel = videoTrack?.label;
16961
+ if (videoTrack) if (videoTrack.enabled) if (util_isVirtualCamera(videoTrack)) throw error_createError({
16962
+ message: "Virtual cameras are not allowed.",
16963
+ explanation: `Please use a real camera, not "${videoTrack.label}".`,
16964
+ options: this.options
16965
+ });
16966
+ else {
16945
16967
  let description = "";
16946
- if (videoTrack.label && videoTrack.label.length > 0) description = description.concat(videoTrack.label);
16968
+ if (videoTrack.label.length > 0) description = description.concat(videoTrack.label);
16947
16969
  description = description.concat(` with enabled=${videoTrack.enabled}, muted=${videoTrack.muted}, readyState=${videoTrack.readyState}`);
16948
16970
  this.options.logger.debug(`UserMedia: ${videoTrack.kind} detected. ${description}`);
16949
- } else throw error_createError({
16971
+ }
16972
+ else throw error_createError({
16950
16973
  message: "Webcam is disabled",
16951
16974
  explanation: "The video track seems to be disabled. Enable it in your system.",
16952
16975
  options: this.options
@@ -16965,6 +16988,9 @@
16965
16988
  });
16966
16989
  }
16967
16990
  }
16991
+ getVideoTrackLabel() {
16992
+ return this.videoTrackLabel;
16993
+ }
16968
16994
  isReady() {
16969
16995
  return Boolean(this.rawVisualUserMedia?.src);
16970
16996
  }
@@ -17654,6 +17680,7 @@
17654
17680
  framesCount: this.framesCount,
17655
17681
  videoType
17656
17682
  };
17683
+ if (this.userMedia) this.recordingStats.videoTrackLabel = this.userMedia.getVideoTrackLabel();
17657
17684
  if (isAudioEnabled(this.options) && this.userMedia) {
17658
17685
  this.recordingStats.samplesCount = this.samplesCount;
17659
17686
  this.recordingStats.sampleRate = this.userMedia.getAudioSampleRate();
@@ -18719,6 +18746,7 @@
18719
18746
  else if (params.exc.message) this.options.logger.error(params.exc.message);
18720
18747
  } else this.options.logger.error(params.exc);
18721
18748
  if (this.options.displayErrors && params.err) this.visuals.error(params.err);
18749
+ else if (this.options.displayErrors && params.exc && params.exc instanceof error_VideomailError) this.visuals.error(params.exc);
18722
18750
  else this.visuals.reset();
18723
18751
  }
18724
18752
  initEvents(playerOnly = false) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "videomail-client",
3
- "version": "13.14.1",
3
+ "version": "13.15.1",
4
4
  "description": "A wicked npm package to record videos directly in the browser, for Deaf and Sign Language!",
5
5
  "keywords": [
6
6
  "webcam",
@@ -94,26 +94,26 @@
94
94
  "@types/ua-parser-js": "0.7.39",
95
95
  "@vitest/eslint-plugin": "1.6.20",
96
96
  "audit-ci": "7.1.0",
97
- "chromatic": "17.5.0",
97
+ "chromatic": "17.7.2",
98
98
  "cross-env": "10.1.0",
99
- "eslint": "10.5.0",
99
+ "eslint": "10.6.0",
100
100
  "eslint-import-resolver-typescript": "4.4.5",
101
101
  "eslint-plugin-de-morgan": "2.1.2",
102
102
  "eslint-plugin-depend": "1.5.0",
103
103
  "eslint-plugin-import-x": "4.17.0",
104
104
  "eslint-plugin-package-json": "1.5.0",
105
- "eslint-plugin-regexp": "3.1.0",
105
+ "eslint-plugin-regexp": "3.1.1",
106
106
  "eslint-plugin-simple-import-sort": "13.0.0",
107
107
  "globals": "17.7.0",
108
108
  "jsdom": "29.1.1",
109
109
  "msw": "2.14.6",
110
110
  "msw-storybook-addon": "2.0.7",
111
- "prettier": "3.8.4",
111
+ "prettier": "3.8.5",
112
112
  "prettier-plugin-curly": "0.4.1",
113
113
  "prettier-plugin-jsdoc": "1.8.1",
114
114
  "prettier-plugin-packagejson": "3.0.2",
115
115
  "prettier-plugin-sh": "0.18.1",
116
- "release-it": "20.2.0",
116
+ "release-it": "20.2.1",
117
117
  "storybook": "10.4.6",
118
118
  "storybook-html-rsbuild": "3.3.4",
119
119
  "type-fest": "5.7.0",