@besovideo/webrtc-player 0.10.5 → 0.10.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.
@@ -117,7 +117,7 @@ var bvPlayerCore = (() => {
117
117
  var define_processenv_default;
118
118
  var init_define_processenv = __esm({
119
119
  "<define:processenv>"() {
120
- define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.5", PROJECT_NAMESPACE: "bvplayer" };
120
+ define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.7", PROJECT_NAMESPACE: "bvplayer" };
121
121
  }
122
122
  });
123
123
 
@@ -15271,16 +15271,18 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
15271
15271
  };
15272
15272
  return handle2;
15273
15273
  }
15274
- var _onIcon, _offIcon, _doingIcon, _isBusy, _talk, _intercom, _type, _onTalkStart, onTalkStart_fn, _onTalkEnd, onTalkEnd_fn;
15274
+ var _onIcon, _offIcon, _doingIcon, _currentIcon, _isBusy, _talk, _intercom, _type, _onTalkStart, onTalkStart_fn, _onTalkEnd, onTalkEnd_fn, _setIcon, setIcon_fn;
15275
15275
  var MikeButton = class extends HTMLElement {
15276
15276
  constructor() {
15277
15277
  super();
15278
15278
  __privateAdd(this, _onTalkStart);
15279
15279
  __privateAdd(this, _onTalkEnd);
15280
+ __privateAdd(this, _setIcon);
15280
15281
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields weakmep实现的私有变量
15281
15282
  __privateAdd(this, _onIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h(icons_default.MikeOn, null)));
15282
15283
  __privateAdd(this, _offIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h(icons_default.MikeOff, null)));
15283
15284
  __privateAdd(this, _doingIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h(icons_default.MikeDoing, null)));
15285
+ __privateAdd(this, _currentIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("span", null)));
15284
15286
  __privateAdd(this, _isBusy, false);
15285
15287
  //是否正在喊话
15286
15288
  __privateAdd(this, _talk, false);
@@ -15289,6 +15291,7 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
15289
15291
  __privateAdd(this, _intercom, void 0);
15290
15292
  // 协议类型
15291
15293
  __privateAdd(this, _type, void 0);
15294
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "off");
15292
15295
  this.attachShadow({ mode: "open" });
15293
15296
  this.addEventListener("click", () => {
15294
15297
  if (!__privateGet(this, _isBusy)) {
@@ -15314,7 +15317,7 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
15314
15317
  if (toast) {
15315
15318
  toast.error(e);
15316
15319
  }
15317
- __privateGet(this, _doingIcon).replaceWith(__privateGet(this, _offIcon));
15320
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "off");
15318
15321
  });
15319
15322
  pm.finally(() => {
15320
15323
  __privateSet(this, _isBusy, false);
@@ -15333,12 +15336,13 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
15333
15336
  render() {
15334
15337
  if (!this.shadowRoot)
15335
15338
  return;
15336
- this.shadowRoot.appendChild(__privateGet(this, _talk) ? __privateGet(this, _onIcon) : __privateGet(this, _offIcon));
15339
+ this.shadowRoot.appendChild(__privateGet(this, _currentIcon));
15337
15340
  }
15338
15341
  };
15339
15342
  _onIcon = new WeakMap();
15340
15343
  _offIcon = new WeakMap();
15341
15344
  _doingIcon = new WeakMap();
15345
+ _currentIcon = new WeakMap();
15342
15346
  _isBusy = new WeakMap();
15343
15347
  _talk = new WeakMap();
15344
15348
  _intercom = new WeakMap();
@@ -15349,12 +15353,12 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
15349
15353
  var _a;
15350
15354
  if (!__privateGet(this, _intercom))
15351
15355
  return;
15352
- __privateGet(this, _offIcon).replaceWith(__privateGet(this, _doingIcon));
15356
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "doing");
15353
15357
  if (!navigator.mediaDevices) {
15354
15358
  throw t("mei-you-mai-ke-feng-huo-zhe-mei-you-quan-xian");
15355
15359
  }
15356
15360
  yield (_a = __privateGet(this, _intercom)) == null ? void 0 : _a.open(void 0, __privateGet(this, _type));
15357
- __privateGet(this, _doingIcon).replaceWith(__privateGet(this, _onIcon));
15361
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "on");
15358
15362
  this.events.dispatch("intercomStart");
15359
15363
  });
15360
15364
  };
@@ -15362,15 +15366,36 @@ If you want to allow non-zero first timestamps, set firstTimestampBehavior: 'per
15362
15366
  onTalkEnd_fn = function() {
15363
15367
  return __async(this, null, function* () {
15364
15368
  var _a;
15365
- __privateGet(this, _onIcon).replaceWith(__privateGet(this, _doingIcon));
15369
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "doing");
15366
15370
  yield (_a = __privateGet(this, _intercom)) == null ? void 0 : _a.close();
15367
15371
  yield new Promise((r) => {
15368
15372
  setTimeout(r, 1e3);
15369
15373
  });
15370
- __privateGet(this, _doingIcon).replaceWith(__privateGet(this, _offIcon));
15374
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "off");
15371
15375
  this.events.dispatch("intercomStop");
15372
15376
  });
15373
15377
  };
15378
+ _setIcon = new WeakSet();
15379
+ setIcon_fn = function(iconType) {
15380
+ core_default.dom.empty(__privateGet(this, _currentIcon));
15381
+ switch (iconType) {
15382
+ case "doing":
15383
+ {
15384
+ __privateGet(this, _currentIcon).appendChild(__privateGet(this, _doingIcon));
15385
+ }
15386
+ break;
15387
+ case "on":
15388
+ {
15389
+ __privateGet(this, _currentIcon).appendChild(__privateGet(this, _onIcon));
15390
+ }
15391
+ break;
15392
+ case "off":
15393
+ {
15394
+ __privateGet(this, _currentIcon).appendChild(__privateGet(this, _offIcon));
15395
+ }
15396
+ break;
15397
+ }
15398
+ };
15374
15399
  customElements.define("mike-button", MikeButton);
15375
15400
 
15376
15401
  // src/plugins/controller/index.tsx
@@ -22481,7 +22506,7 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22481
22506
  logger_default.debug("BvWebrtcInstance close", `_dialogId: ${this._dialogId}`);
22482
22507
  this.player.mask.visible = true;
22483
22508
  this.player.mask.text = t("video-closed");
22484
- this.player.close();
22509
+ yield this.player.close();
22485
22510
  logger_default.debug(
22486
22511
  `BvWebrtcInstance close\uFF0C player closed\uFF0C\u68C0\u67E5 remoteSdpFetcher: `,
22487
22512
  this._remoteSdpFetcher
@@ -22569,10 +22594,10 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22569
22594
  bvInstance.removeEventListener("close", handleClose);
22570
22595
  onClose && onClose();
22571
22596
  };
22572
- bvInstance.addEventListener("close", handleClose);
22573
22597
  const instance2 = {
22574
22598
  open: () => __async(void 0, null, function* () {
22575
22599
  logger_default.debug("BvWebrtc open");
22600
+ bvInstance.addEventListener("close", handleClose);
22576
22601
  yield bvInstance.open();
22577
22602
  }),
22578
22603
  setOption: (option) => {
@@ -22641,6 +22666,66 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22641
22666
  logger_default.debug("microphone audio tracks\uFF1A", audioTracks);
22642
22667
  return localStream;
22643
22668
  });
22669
+ function CreatePlayerCloseInterruptManager(player) {
22670
+ let isCloseEmit = false;
22671
+ function onCloseEmitHandle() {
22672
+ if (isCloseEmit == false) {
22673
+ setCloseEmited();
22674
+ }
22675
+ }
22676
+ let isBegin = false;
22677
+ let isEnd = false;
22678
+ const szInvoke = [];
22679
+ function invokeWaitResult() {
22680
+ szInvoke.forEach((item) => {
22681
+ try {
22682
+ item();
22683
+ } catch (e) {
22684
+ }
22685
+ });
22686
+ szInvoke.splice(0, szInvoke.length);
22687
+ }
22688
+ function setCloseEmited() {
22689
+ isCloseEmit = true;
22690
+ }
22691
+ return {
22692
+ WaitForClose() {
22693
+ return __async(this, null, function* () {
22694
+ setCloseEmited();
22695
+ return new Promise((r) => {
22696
+ if (!isBegin) {
22697
+ r();
22698
+ } else {
22699
+ szInvoke.push(r);
22700
+ }
22701
+ });
22702
+ });
22703
+ },
22704
+ Begin(notListenCloseEvent) {
22705
+ isBegin = true;
22706
+ isEnd = false;
22707
+ isCloseEmit = false;
22708
+ if (!notListenCloseEvent) {
22709
+ player.addEventListener("close", onCloseEmitHandle);
22710
+ }
22711
+ },
22712
+ Check() {
22713
+ if (isCloseEmit) {
22714
+ this.End();
22715
+ invokeWaitResult();
22716
+ throw "abort open";
22717
+ }
22718
+ },
22719
+ End() {
22720
+ isBegin = false;
22721
+ isEnd = true;
22722
+ try {
22723
+ player.removeEventListener("close", onCloseEmitHandle);
22724
+ } catch (e) {
22725
+ }
22726
+ }
22727
+ };
22728
+ }
22644
22729
  var AudioPlayer = (props) => {
22645
22730
  const {
22646
22731
  container,
@@ -22719,7 +22804,9 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22719
22804
  onPcEventAdded: (pc) => __async(void 0, null, function* () {
22720
22805
  try {
22721
22806
  const localStream = yield getUserMedia();
22722
- localStream.getTracks().forEach((track) => pc.addTrack(track, localStream));
22807
+ localStream.getTracks().forEach((track) => {
22808
+ pc.addTrack(track, localStream);
22809
+ });
22723
22810
  releaseLocalStream();
22724
22811
  localStreamRelease = () => {
22725
22812
  localStream.getTracks().forEach((t2) => t2.stop());
@@ -22731,21 +22818,38 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22731
22818
  //对讲和会议不启用控制器
22732
22819
  enableController: false
22733
22820
  });
22821
+ const player = bvWebrtcComponentInstance.__dangerGetPlayer();
22822
+ const playerCloseInteruptMgr = CreatePlayerCloseInterruptManager(player);
22734
22823
  const instance2 = __spreadProps(__spreadValues({}, bvWebrtcComponentInstance), {
22824
+ destroy() {
22825
+ return __async(this, null, function* () {
22826
+ yield instance2.close();
22827
+ bvWebrtcComponentInstance.destroy();
22828
+ });
22829
+ },
22830
+ close: () => __async(void 0, null, function* () {
22831
+ console.log("wait for close intercom");
22832
+ yield playerCloseInteruptMgr.WaitForClose();
22833
+ console.log("wait for close intercom do");
22834
+ bvWebrtcComponentInstance.close();
22835
+ }),
22735
22836
  open: (..._0) => __async(void 0, [..._0], function* (protocol = type, mikeButtonType) {
22736
- var _a, _b, _c;
22837
+ var _a2, _b, _c;
22737
22838
  if (mikeButtonType)
22738
22839
  protocol = mikeButtonType;
22739
- const player = bvWebrtcComponentInstance.__dangerGetPlayer();
22740
22840
  let hplayer = null;
22741
22841
  try {
22742
22842
  if (protocol === "ws-bvrtc") {
22743
22843
  throw "protocol == ws-bvrtc";
22744
22844
  }
22745
22845
  player.enableCanvas(false);
22846
+ playerCloseInteruptMgr.Begin(true);
22746
22847
  yield bvWebrtcComponentInstance.open();
22848
+ playerCloseInteruptMgr.Check();
22849
+ playerCloseInteruptMgr.End();
22747
22850
  } catch (e) {
22748
22851
  try {
22852
+ playerCloseInteruptMgr.Begin();
22749
22853
  logger_default.debug("error type", e.name, e instanceof OpenDialogError);
22750
22854
  if (e instanceof OpenDialogError || protocol === "webrtc")
22751
22855
  throw e;
@@ -22758,6 +22862,7 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22758
22862
  hplayer.setPrefix(apiPrefix);
22759
22863
  }
22760
22864
  yield hplayer.open(5e3, 3, "");
22865
+ playerCloseInteruptMgr.Check();
22761
22866
  if (typeof (bvrtcConfig == null ? void 0 : bvrtcConfig.realTimeLevel) == "number") {
22762
22867
  if (bvrtcConfig.realTimeLevel >= 0 && bvrtcConfig.realTimeLevel <= 10) {
22763
22868
  yield hplayer.setRealTimeIndex(bvrtcConfig.realTimeLevel);
@@ -22782,16 +22887,18 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22782
22887
  hplayer.close();
22783
22888
  throw new Error("ws-bvrtc create offer failed.");
22784
22889
  }
22785
- logger_default.debug("ws-bvrtc localSDP: ", (_a = res == null ? void 0 : res.data) == null ? void 0 : _a.sdp);
22890
+ logger_default.debug("ws-bvrtc localSDP: ", (_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2.sdp);
22891
+ playerCloseInteruptMgr.Check();
22786
22892
  yield dialog_default.closeDialogs(
22787
22893
  [sdpFetcher.dialogId || ""],
22788
22894
  sdpFetcher.token
22789
22895
  );
22790
22896
  yield new Promise((resolve) => {
22791
22897
  setTimeout(() => {
22792
- resolve(1);
22793
- }, 1e3);
22898
+ resolve();
22899
+ }, 0);
22794
22900
  });
22901
+ playerCloseInteruptMgr.Check();
22795
22902
  const dialog = isConference ? yield dialog_default.getConferenceBvrtc(
22796
22903
  {
22797
22904
  id,
@@ -22809,39 +22916,38 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
22809
22916
  );
22810
22917
  logger_default.debug("ws-bvrtc remoteSDP: ", dialog.sdp);
22811
22918
  hplayer.setRemoteSDP(dialog.dialogId, dialog.sdp);
22812
- let invokePomiseWaitResult = () => {
22813
- };
22814
- let rejectPomiseWaitResult = () => {
22815
- };
22816
- const promiseWaitResult = new Promise((r, j) => {
22817
- invokePomiseWaitResult = r;
22818
- rejectPomiseWaitResult = j;
22819
- });
22919
+ playerCloseInteruptMgr.Check();
22920
+ const {
22921
+ promise: promiseWaitResult,
22922
+ resolve: invokePomiseWaitResult,
22923
+ reject: rejectPomiseWaitResult
22924
+ } = Promise.withResolvers();
22820
22925
  hplayer.onevent = function(bCloseEvent, iResult) {
22821
- if (bCloseEvent !== 0) {
22822
- logger_default.debug("ws-bvrtc", "av channel be closed");
22823
- onDisConnected && onDisConnected();
22824
- } else if (iResult == 0) {
22825
- logger_default.debug("ws-bvrtc", "open av channel success ");
22826
- onConnected && onConnected();
22827
- invokePomiseWaitResult();
22828
- } else {
22829
- logger_default.debug("ws-bvrtc", "open av channel fail " + iResult);
22830
- onConnectedFailed && onConnectedFailed();
22831
- rejectPomiseWaitResult();
22832
- }
22926
+ return __async(this, null, function* () {
22927
+ if (bCloseEvent !== 0) {
22928
+ logger_default.debug("ws-bvrtc", "av channel be closed");
22929
+ onDisConnected && onDisConnected();
22930
+ } else if (iResult == 0) {
22931
+ logger_default.debug("ws-bvrtc", "open av channel success ");
22932
+ onConnected && onConnected();
22933
+ invokePomiseWaitResult();
22934
+ } else {
22935
+ logger_default.debug("ws-bvrtc", "open av channel fail " + iResult);
22936
+ onConnectedFailed && onConnectedFailed();
22937
+ rejectPomiseWaitResult();
22938
+ }
22939
+ });
22833
22940
  };
22834
22941
  yield promiseWaitResult;
22942
+ playerCloseInteruptMgr.End();
22835
22943
  player.spinner.spin = false;
22836
22944
  const closeHandle = () => __async(void 0, null, function* () {
22837
22945
  if (!hplayer)
22838
22946
  return;
22839
22947
  player.removeEventListener("close", closeHandle);
22948
+ const dialogId = hplayer.getDialogID();
22840
22949
  hplayer.close();
22841
- yield dialog_default.closeDialogs(
22842
- [hplayer.getDialogID()],
22843
- sdpFetcher.token
22844
- );
22950
+ yield dialog_default.closeDialogs([dialogId], sdpFetcher.token);
22845
22951
  });
22846
22952
  player.addEventListener("close", closeHandle);
22847
22953
  } catch (e2) {
@@ -24067,6 +24173,11 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
24067
24173
  }
24068
24174
  }
24069
24175
  const dlgMgr = new DialogManager();
24176
+ if (player.mikeBtn) {
24177
+ player.mikeBtn.intercom = intercom == null ? void 0 : intercom.instance;
24178
+ } else {
24179
+ player.intercomUtils = CreateIntercomUtils(intercom == null ? void 0 : intercom.instance, (void 0).protocol);
24180
+ }
24070
24181
  const instance2 = {
24071
24182
  getVideoElement: () => {
24072
24183
  const el = player.video.getVideoEl();
@@ -24110,6 +24221,9 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
24110
24221
  }
24111
24222
  player.enableCanvas(false);
24112
24223
  this.protocol = "webrtc";
24224
+ if (player.mikeBtn) {
24225
+ player.mikeBtn.type = this.protocol;
24226
+ }
24113
24227
  yield player.prepareWebrtc();
24114
24228
  if (dlgMgr.enterOpeningCanClose()) {
24115
24229
  return;
@@ -24118,12 +24232,6 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
24118
24232
  audioWaveShow.setMediaStream(player.video.srcObject);
24119
24233
  audioWaveShow.setEle(playerEl);
24120
24234
  }
24121
- if (player.mikeBtn) {
24122
- player.mikeBtn.intercom = intercom == null ? void 0 : intercom.instance;
24123
- player.mikeBtn.type = this.protocol;
24124
- } else {
24125
- player.intercomUtils = CreateIntercomUtils(intercom == null ? void 0 : intercom.instance, this.protocol);
24126
- }
24127
24235
  } catch (e) {
24128
24236
  tokenFailDetect(e, () => {
24129
24237
  player.mask.visible = true;
@@ -24329,7 +24437,6 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
24329
24437
  });
24330
24438
  }
24331
24439
  if (player.mikeBtn) {
24332
- player.mikeBtn.intercom = intercom == null ? void 0 : intercom.instance;
24333
24440
  player.mikeBtn.type = this.protocol;
24334
24441
  }
24335
24442
  } catch (e2) {
@@ -24433,14 +24540,15 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
24433
24540
  yield player.close();
24434
24541
  useRecntMgr = void 0;
24435
24542
  reconnectMgr == null ? void 0 : reconnectMgr.cancelReconnect();
24436
- if (player.mikeBtn) {
24437
- player.mikeBtn.talking = false;
24438
- player.mikeBtn.intercom = void 0;
24439
- }
24440
24543
  }),
24441
24544
  render: player.init,
24442
24545
  destroy: () => __async(void 0, null, function* () {
24443
24546
  logger_default.debug("PuPlayer destroy");
24547
+ if (player.mikeBtn) {
24548
+ player.mikeBtn.talking = false;
24549
+ player.mikeBtn.intercom = void 0;
24550
+ intercom == null ? void 0 : intercom.instance.close();
24551
+ }
24444
24552
  intercom == null ? void 0 : intercom.instance.destroy();
24445
24553
  player.destroy();
24446
24554
  reconnectMgr == null ? void 0 : reconnectMgr.cancelReconnect();
@@ -25463,6 +25571,9 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
25463
25571
  this.svgSound = core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("span", { class: "svg-sound" }, /* @__PURE__ */ jsx_default.h("input", { type: "range", className: "range-input", value: this.volumeCurrent, oninput: (e) => {
25464
25572
  this.onVolumeChange(e.target.value);
25465
25573
  } })));
25574
+ this.svgSnapshot = core_default.dom.createByJsx(
25575
+ /* @__PURE__ */ jsx_default.h("svg", { onclick: () => this.dispatch("snapshot"), style: "margin-left: 20px; cursor: pointer", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 256 256" }, /* @__PURE__ */ jsx_default.h("rect", { width: "256", height: "256", fill: "none" }), /* @__PURE__ */ jsx_default.h("path", { fill: "#fff", d: "M208 58h-28.79L165 36.67a6 6 0 0 0-5-2.67H96a6 6 0 0 0-5 2.67L76.78 58H48a22 22 0 0 0-22 22v112a22 22 0 0 0 22 22h160a22 22 0 0 0 22-22V80a22 22 0 0 0-22-22m10 134a10 10 0 0 1-10 10H48a10 10 0 0 1-10-10V80a10 10 0 0 1 10-10h32a6 6 0 0 0 5-2.67L99.21 46h57.57L171 67.33a6 6 0 0 0 5 2.67h32a10 10 0 0 1 10 10ZM128 90a42 42 0 1 0 42 42a42 42 0 0 0-42-42m0 72a30 30 0 1 1 30-30a30 30 0 0 1-30 30", "stroke-width": "6.5", stroke: "#fff" }))
25576
+ );
25466
25577
  this.svgFullscreen = core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("svg", { onclick: () => {
25467
25578
  this.dispatch("fullscreen");
25468
25579
  }, style: "margin-left: 30px; cursor: pointer", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24" }, /* @__PURE__ */ jsx_default.h("path", { fill: "white", d: "M4 4h6v2H6v4H4zm10 0h6v6h-2V6h-4zM6 14v4h4v2H4v-6zm14 0v6h-6v-2h4v-4z" })));
@@ -25739,7 +25850,7 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
25739
25850
  const rightPanel = this.controls.rightControls ? this.controls.rightControls : (() => {
25740
25851
  this.controls.rightControls = core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("span", { class: "right-options" }));
25741
25852
  core_default.dom.append(this.svgSound, this.svgSound100);
25742
- core_default.dom.append(this.controls.rightControls, this.svgSound, this.playSpeed, this.svgFullscreen, this.svgOptions, this.optionsContent);
25853
+ core_default.dom.append(this.controls.rightControls, this.svgSound, this.playSpeed, this.svgSnapshot, this.svgFullscreen, this.optionsContent);
25743
25854
  return this.controls.rightControls;
25744
25855
  })();
25745
25856
  const barContent = this.controls.barContent ? this.controls.barContent : this.controls.barContent = core_default.dom.createByJsx(
@@ -26399,6 +26510,10 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
26399
26510
  barHandle.addEventListener("fullscreen", () => {
26400
26511
  fullscreen_default.toggle(markerHandle.GetPlayArea());
26401
26512
  });
26513
+ barHandle.addEventListener("snapshot", () => __async(this, null, function* () {
26514
+ const snapshotHandle = yield player.video.screenshot();
26515
+ snapshotHandle == null ? void 0 : snapshotHandle.download();
26516
+ }));
26402
26517
  markerHandle.addEventListener("jump", (params) => {
26403
26518
  barHandle.jumpToTargetSeconds(params);
26404
26519
  });
package/dist/main.es.js CHANGED
@@ -111,7 +111,7 @@ var __async = (__this, __arguments, generator) => {
111
111
  var define_processenv_default;
112
112
  var init_define_processenv = __esm({
113
113
  "<define:processenv>"() {
114
- define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.5", PROJECT_NAMESPACE: "bvplayer" };
114
+ define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.7", PROJECT_NAMESPACE: "bvplayer" };
115
115
  }
116
116
  });
117
117
 
@@ -15254,16 +15254,18 @@ function CreateIntercomUtils(intercomIns, type) {
15254
15254
  };
15255
15255
  return handle2;
15256
15256
  }
15257
- var _onIcon, _offIcon, _doingIcon, _isBusy, _talk, _intercom, _type, _onTalkStart, onTalkStart_fn, _onTalkEnd, onTalkEnd_fn;
15257
+ var _onIcon, _offIcon, _doingIcon, _currentIcon, _isBusy, _talk, _intercom, _type, _onTalkStart, onTalkStart_fn, _onTalkEnd, onTalkEnd_fn, _setIcon, setIcon_fn;
15258
15258
  var MikeButton = class extends HTMLElement {
15259
15259
  constructor() {
15260
15260
  super();
15261
15261
  __privateAdd(this, _onTalkStart);
15262
15262
  __privateAdd(this, _onTalkEnd);
15263
+ __privateAdd(this, _setIcon);
15263
15264
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields weakmep实现的私有变量
15264
15265
  __privateAdd(this, _onIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h(icons_default.MikeOn, null)));
15265
15266
  __privateAdd(this, _offIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h(icons_default.MikeOff, null)));
15266
15267
  __privateAdd(this, _doingIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h(icons_default.MikeDoing, null)));
15268
+ __privateAdd(this, _currentIcon, core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("span", null)));
15267
15269
  __privateAdd(this, _isBusy, false);
15268
15270
  //是否正在喊话
15269
15271
  __privateAdd(this, _talk, false);
@@ -15272,6 +15274,7 @@ var MikeButton = class extends HTMLElement {
15272
15274
  __privateAdd(this, _intercom, void 0);
15273
15275
  // 协议类型
15274
15276
  __privateAdd(this, _type, void 0);
15277
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "off");
15275
15278
  this.attachShadow({ mode: "open" });
15276
15279
  this.addEventListener("click", () => {
15277
15280
  if (!__privateGet(this, _isBusy)) {
@@ -15297,7 +15300,7 @@ var MikeButton = class extends HTMLElement {
15297
15300
  if (toast) {
15298
15301
  toast.error(e);
15299
15302
  }
15300
- __privateGet(this, _doingIcon).replaceWith(__privateGet(this, _offIcon));
15303
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "off");
15301
15304
  });
15302
15305
  pm.finally(() => {
15303
15306
  __privateSet(this, _isBusy, false);
@@ -15316,12 +15319,13 @@ var MikeButton = class extends HTMLElement {
15316
15319
  render() {
15317
15320
  if (!this.shadowRoot)
15318
15321
  return;
15319
- this.shadowRoot.appendChild(__privateGet(this, _talk) ? __privateGet(this, _onIcon) : __privateGet(this, _offIcon));
15322
+ this.shadowRoot.appendChild(__privateGet(this, _currentIcon));
15320
15323
  }
15321
15324
  };
15322
15325
  _onIcon = new WeakMap();
15323
15326
  _offIcon = new WeakMap();
15324
15327
  _doingIcon = new WeakMap();
15328
+ _currentIcon = new WeakMap();
15325
15329
  _isBusy = new WeakMap();
15326
15330
  _talk = new WeakMap();
15327
15331
  _intercom = new WeakMap();
@@ -15332,12 +15336,12 @@ onTalkStart_fn = function() {
15332
15336
  var _a;
15333
15337
  if (!__privateGet(this, _intercom))
15334
15338
  return;
15335
- __privateGet(this, _offIcon).replaceWith(__privateGet(this, _doingIcon));
15339
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "doing");
15336
15340
  if (!navigator.mediaDevices) {
15337
15341
  throw t("mei-you-mai-ke-feng-huo-zhe-mei-you-quan-xian");
15338
15342
  }
15339
15343
  yield (_a = __privateGet(this, _intercom)) == null ? void 0 : _a.open(void 0, __privateGet(this, _type));
15340
- __privateGet(this, _doingIcon).replaceWith(__privateGet(this, _onIcon));
15344
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "on");
15341
15345
  this.events.dispatch("intercomStart");
15342
15346
  });
15343
15347
  };
@@ -15345,15 +15349,36 @@ _onTalkEnd = new WeakSet();
15345
15349
  onTalkEnd_fn = function() {
15346
15350
  return __async(this, null, function* () {
15347
15351
  var _a;
15348
- __privateGet(this, _onIcon).replaceWith(__privateGet(this, _doingIcon));
15352
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "doing");
15349
15353
  yield (_a = __privateGet(this, _intercom)) == null ? void 0 : _a.close();
15350
15354
  yield new Promise((r) => {
15351
15355
  setTimeout(r, 1e3);
15352
15356
  });
15353
- __privateGet(this, _doingIcon).replaceWith(__privateGet(this, _offIcon));
15357
+ __privateMethod(this, _setIcon, setIcon_fn).call(this, "off");
15354
15358
  this.events.dispatch("intercomStop");
15355
15359
  });
15356
15360
  };
15361
+ _setIcon = new WeakSet();
15362
+ setIcon_fn = function(iconType) {
15363
+ core_default.dom.empty(__privateGet(this, _currentIcon));
15364
+ switch (iconType) {
15365
+ case "doing":
15366
+ {
15367
+ __privateGet(this, _currentIcon).appendChild(__privateGet(this, _doingIcon));
15368
+ }
15369
+ break;
15370
+ case "on":
15371
+ {
15372
+ __privateGet(this, _currentIcon).appendChild(__privateGet(this, _onIcon));
15373
+ }
15374
+ break;
15375
+ case "off":
15376
+ {
15377
+ __privateGet(this, _currentIcon).appendChild(__privateGet(this, _offIcon));
15378
+ }
15379
+ break;
15380
+ }
15381
+ };
15357
15382
  customElements.define("mike-button", MikeButton);
15358
15383
 
15359
15384
  // src/plugins/controller/index.tsx
@@ -22464,7 +22489,7 @@ var BvWebrtcInstance = class extends CommonInstance {
22464
22489
  logger_default.debug("BvWebrtcInstance close", `_dialogId: ${this._dialogId}`);
22465
22490
  this.player.mask.visible = true;
22466
22491
  this.player.mask.text = t("video-closed");
22467
- this.player.close();
22492
+ yield this.player.close();
22468
22493
  logger_default.debug(
22469
22494
  `BvWebrtcInstance close\uFF0C player closed\uFF0C\u68C0\u67E5 remoteSdpFetcher: `,
22470
22495
  this._remoteSdpFetcher
@@ -22552,10 +22577,10 @@ var BvWebrtc = (props) => {
22552
22577
  bvInstance.removeEventListener("close", handleClose);
22553
22578
  onClose && onClose();
22554
22579
  };
22555
- bvInstance.addEventListener("close", handleClose);
22556
22580
  const instance2 = {
22557
22581
  open: () => __async(void 0, null, function* () {
22558
22582
  logger_default.debug("BvWebrtc open");
22583
+ bvInstance.addEventListener("close", handleClose);
22559
22584
  yield bvInstance.open();
22560
22585
  }),
22561
22586
  setOption: (option) => {
@@ -22624,6 +22649,66 @@ var getUserMedia = () => __async(void 0, null, function* () {
22624
22649
  logger_default.debug("microphone audio tracks\uFF1A", audioTracks);
22625
22650
  return localStream;
22626
22651
  });
22652
+ function CreatePlayerCloseInterruptManager(player) {
22653
+ let isCloseEmit = false;
22654
+ function onCloseEmitHandle() {
22655
+ if (isCloseEmit == false) {
22656
+ setCloseEmited();
22657
+ }
22658
+ }
22659
+ let isBegin = false;
22660
+ let isEnd = false;
22661
+ const szInvoke = [];
22662
+ function invokeWaitResult() {
22663
+ szInvoke.forEach((item) => {
22664
+ try {
22665
+ item();
22666
+ } catch (e) {
22667
+ }
22668
+ });
22669
+ szInvoke.splice(0, szInvoke.length);
22670
+ }
22671
+ function setCloseEmited() {
22672
+ isCloseEmit = true;
22673
+ }
22674
+ return {
22675
+ WaitForClose() {
22676
+ return __async(this, null, function* () {
22677
+ setCloseEmited();
22678
+ return new Promise((r) => {
22679
+ if (!isBegin) {
22680
+ r();
22681
+ } else {
22682
+ szInvoke.push(r);
22683
+ }
22684
+ });
22685
+ });
22686
+ },
22687
+ Begin(notListenCloseEvent) {
22688
+ isBegin = true;
22689
+ isEnd = false;
22690
+ isCloseEmit = false;
22691
+ if (!notListenCloseEvent) {
22692
+ player.addEventListener("close", onCloseEmitHandle);
22693
+ }
22694
+ },
22695
+ Check() {
22696
+ if (isCloseEmit) {
22697
+ this.End();
22698
+ invokeWaitResult();
22699
+ throw "abort open";
22700
+ }
22701
+ },
22702
+ End() {
22703
+ isBegin = false;
22704
+ isEnd = true;
22705
+ try {
22706
+ player.removeEventListener("close", onCloseEmitHandle);
22707
+ } catch (e) {
22708
+ }
22709
+ }
22710
+ };
22711
+ }
22627
22712
  var AudioPlayer = (props) => {
22628
22713
  const {
22629
22714
  container,
@@ -22702,7 +22787,9 @@ var AudioPlayer = (props) => {
22702
22787
  onPcEventAdded: (pc) => __async(void 0, null, function* () {
22703
22788
  try {
22704
22789
  const localStream = yield getUserMedia();
22705
- localStream.getTracks().forEach((track) => pc.addTrack(track, localStream));
22790
+ localStream.getTracks().forEach((track) => {
22791
+ pc.addTrack(track, localStream);
22792
+ });
22706
22793
  releaseLocalStream();
22707
22794
  localStreamRelease = () => {
22708
22795
  localStream.getTracks().forEach((t2) => t2.stop());
@@ -22714,21 +22801,38 @@ var AudioPlayer = (props) => {
22714
22801
  //对讲和会议不启用控制器
22715
22802
  enableController: false
22716
22803
  });
22804
+ const player = bvWebrtcComponentInstance.__dangerGetPlayer();
22805
+ const playerCloseInteruptMgr = CreatePlayerCloseInterruptManager(player);
22717
22806
  const instance2 = __spreadProps(__spreadValues({}, bvWebrtcComponentInstance), {
22807
+ destroy() {
22808
+ return __async(this, null, function* () {
22809
+ yield instance2.close();
22810
+ bvWebrtcComponentInstance.destroy();
22811
+ });
22812
+ },
22813
+ close: () => __async(void 0, null, function* () {
22814
+ console.log("wait for close intercom");
22815
+ yield playerCloseInteruptMgr.WaitForClose();
22816
+ console.log("wait for close intercom do");
22817
+ bvWebrtcComponentInstance.close();
22818
+ }),
22718
22819
  open: (..._0) => __async(void 0, [..._0], function* (protocol = type, mikeButtonType) {
22719
- var _a, _b, _c;
22820
+ var _a2, _b, _c;
22720
22821
  if (mikeButtonType)
22721
22822
  protocol = mikeButtonType;
22722
- const player = bvWebrtcComponentInstance.__dangerGetPlayer();
22723
22823
  let hplayer = null;
22724
22824
  try {
22725
22825
  if (protocol === "ws-bvrtc") {
22726
22826
  throw "protocol == ws-bvrtc";
22727
22827
  }
22728
22828
  player.enableCanvas(false);
22829
+ playerCloseInteruptMgr.Begin(true);
22729
22830
  yield bvWebrtcComponentInstance.open();
22831
+ playerCloseInteruptMgr.Check();
22832
+ playerCloseInteruptMgr.End();
22730
22833
  } catch (e) {
22731
22834
  try {
22835
+ playerCloseInteruptMgr.Begin();
22732
22836
  logger_default.debug("error type", e.name, e instanceof OpenDialogError);
22733
22837
  if (e instanceof OpenDialogError || protocol === "webrtc")
22734
22838
  throw e;
@@ -22741,6 +22845,7 @@ var AudioPlayer = (props) => {
22741
22845
  hplayer.setPrefix(apiPrefix);
22742
22846
  }
22743
22847
  yield hplayer.open(5e3, 3, "");
22848
+ playerCloseInteruptMgr.Check();
22744
22849
  if (typeof (bvrtcConfig == null ? void 0 : bvrtcConfig.realTimeLevel) == "number") {
22745
22850
  if (bvrtcConfig.realTimeLevel >= 0 && bvrtcConfig.realTimeLevel <= 10) {
22746
22851
  yield hplayer.setRealTimeIndex(bvrtcConfig.realTimeLevel);
@@ -22765,16 +22870,18 @@ var AudioPlayer = (props) => {
22765
22870
  hplayer.close();
22766
22871
  throw new Error("ws-bvrtc create offer failed.");
22767
22872
  }
22768
- logger_default.debug("ws-bvrtc localSDP: ", (_a = res == null ? void 0 : res.data) == null ? void 0 : _a.sdp);
22873
+ logger_default.debug("ws-bvrtc localSDP: ", (_a2 = res == null ? void 0 : res.data) == null ? void 0 : _a2.sdp);
22874
+ playerCloseInteruptMgr.Check();
22769
22875
  yield dialog_default.closeDialogs(
22770
22876
  [sdpFetcher.dialogId || ""],
22771
22877
  sdpFetcher.token
22772
22878
  );
22773
22879
  yield new Promise((resolve) => {
22774
22880
  setTimeout(() => {
22775
- resolve(1);
22776
- }, 1e3);
22881
+ resolve();
22882
+ }, 0);
22777
22883
  });
22884
+ playerCloseInteruptMgr.Check();
22778
22885
  const dialog = isConference ? yield dialog_default.getConferenceBvrtc(
22779
22886
  {
22780
22887
  id,
@@ -22792,39 +22899,38 @@ var AudioPlayer = (props) => {
22792
22899
  );
22793
22900
  logger_default.debug("ws-bvrtc remoteSDP: ", dialog.sdp);
22794
22901
  hplayer.setRemoteSDP(dialog.dialogId, dialog.sdp);
22795
- let invokePomiseWaitResult = () => {
22796
- };
22797
- let rejectPomiseWaitResult = () => {
22798
- };
22799
- const promiseWaitResult = new Promise((r, j) => {
22800
- invokePomiseWaitResult = r;
22801
- rejectPomiseWaitResult = j;
22802
- });
22902
+ playerCloseInteruptMgr.Check();
22903
+ const {
22904
+ promise: promiseWaitResult,
22905
+ resolve: invokePomiseWaitResult,
22906
+ reject: rejectPomiseWaitResult
22907
+ } = Promise.withResolvers();
22803
22908
  hplayer.onevent = function(bCloseEvent, iResult) {
22804
- if (bCloseEvent !== 0) {
22805
- logger_default.debug("ws-bvrtc", "av channel be closed");
22806
- onDisConnected && onDisConnected();
22807
- } else if (iResult == 0) {
22808
- logger_default.debug("ws-bvrtc", "open av channel success ");
22809
- onConnected && onConnected();
22810
- invokePomiseWaitResult();
22811
- } else {
22812
- logger_default.debug("ws-bvrtc", "open av channel fail " + iResult);
22813
- onConnectedFailed && onConnectedFailed();
22814
- rejectPomiseWaitResult();
22815
- }
22909
+ return __async(this, null, function* () {
22910
+ if (bCloseEvent !== 0) {
22911
+ logger_default.debug("ws-bvrtc", "av channel be closed");
22912
+ onDisConnected && onDisConnected();
22913
+ } else if (iResult == 0) {
22914
+ logger_default.debug("ws-bvrtc", "open av channel success ");
22915
+ onConnected && onConnected();
22916
+ invokePomiseWaitResult();
22917
+ } else {
22918
+ logger_default.debug("ws-bvrtc", "open av channel fail " + iResult);
22919
+ onConnectedFailed && onConnectedFailed();
22920
+ rejectPomiseWaitResult();
22921
+ }
22922
+ });
22816
22923
  };
22817
22924
  yield promiseWaitResult;
22925
+ playerCloseInteruptMgr.End();
22818
22926
  player.spinner.spin = false;
22819
22927
  const closeHandle = () => __async(void 0, null, function* () {
22820
22928
  if (!hplayer)
22821
22929
  return;
22822
22930
  player.removeEventListener("close", closeHandle);
22931
+ const dialogId = hplayer.getDialogID();
22823
22932
  hplayer.close();
22824
- yield dialog_default.closeDialogs(
22825
- [hplayer.getDialogID()],
22826
- sdpFetcher.token
22827
- );
22933
+ yield dialog_default.closeDialogs([dialogId], sdpFetcher.token);
22828
22934
  });
22829
22935
  player.addEventListener("close", closeHandle);
22830
22936
  } catch (e2) {
@@ -24050,6 +24156,11 @@ var PuPlayer = (props) => {
24050
24156
  }
24051
24157
  }
24052
24158
  const dlgMgr = new DialogManager();
24159
+ if (player.mikeBtn) {
24160
+ player.mikeBtn.intercom = intercom == null ? void 0 : intercom.instance;
24161
+ } else {
24162
+ player.intercomUtils = CreateIntercomUtils(intercom == null ? void 0 : intercom.instance, (void 0).protocol);
24163
+ }
24053
24164
  const instance2 = {
24054
24165
  getVideoElement: () => {
24055
24166
  const el = player.video.getVideoEl();
@@ -24093,6 +24204,9 @@ var PuPlayer = (props) => {
24093
24204
  }
24094
24205
  player.enableCanvas(false);
24095
24206
  this.protocol = "webrtc";
24207
+ if (player.mikeBtn) {
24208
+ player.mikeBtn.type = this.protocol;
24209
+ }
24096
24210
  yield player.prepareWebrtc();
24097
24211
  if (dlgMgr.enterOpeningCanClose()) {
24098
24212
  return;
@@ -24101,12 +24215,6 @@ var PuPlayer = (props) => {
24101
24215
  audioWaveShow.setMediaStream(player.video.srcObject);
24102
24216
  audioWaveShow.setEle(playerEl);
24103
24217
  }
24104
- if (player.mikeBtn) {
24105
- player.mikeBtn.intercom = intercom == null ? void 0 : intercom.instance;
24106
- player.mikeBtn.type = this.protocol;
24107
- } else {
24108
- player.intercomUtils = CreateIntercomUtils(intercom == null ? void 0 : intercom.instance, this.protocol);
24109
- }
24110
24218
  } catch (e) {
24111
24219
  tokenFailDetect(e, () => {
24112
24220
  player.mask.visible = true;
@@ -24312,7 +24420,6 @@ var PuPlayer = (props) => {
24312
24420
  });
24313
24421
  }
24314
24422
  if (player.mikeBtn) {
24315
- player.mikeBtn.intercom = intercom == null ? void 0 : intercom.instance;
24316
24423
  player.mikeBtn.type = this.protocol;
24317
24424
  }
24318
24425
  } catch (e2) {
@@ -24416,14 +24523,15 @@ var PuPlayer = (props) => {
24416
24523
  yield player.close();
24417
24524
  useRecntMgr = void 0;
24418
24525
  reconnectMgr == null ? void 0 : reconnectMgr.cancelReconnect();
24419
- if (player.mikeBtn) {
24420
- player.mikeBtn.talking = false;
24421
- player.mikeBtn.intercom = void 0;
24422
- }
24423
24526
  }),
24424
24527
  render: player.init,
24425
24528
  destroy: () => __async(void 0, null, function* () {
24426
24529
  logger_default.debug("PuPlayer destroy");
24530
+ if (player.mikeBtn) {
24531
+ player.mikeBtn.talking = false;
24532
+ player.mikeBtn.intercom = void 0;
24533
+ intercom == null ? void 0 : intercom.instance.close();
24534
+ }
24427
24535
  intercom == null ? void 0 : intercom.instance.destroy();
24428
24536
  player.destroy();
24429
24537
  reconnectMgr == null ? void 0 : reconnectMgr.cancelReconnect();
@@ -25446,6 +25554,9 @@ var PlaybackBar = class extends Plugin {
25446
25554
  this.svgSound = core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("span", { class: "svg-sound" }, /* @__PURE__ */ jsx_default.h("input", { type: "range", className: "range-input", value: this.volumeCurrent, oninput: (e) => {
25447
25555
  this.onVolumeChange(e.target.value);
25448
25556
  } })));
25557
+ this.svgSnapshot = core_default.dom.createByJsx(
25558
+ /* @__PURE__ */ jsx_default.h("svg", { onclick: () => this.dispatch("snapshot"), style: "margin-left: 20px; cursor: pointer", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 256 256" }, /* @__PURE__ */ jsx_default.h("rect", { width: "256", height: "256", fill: "none" }), /* @__PURE__ */ jsx_default.h("path", { fill: "#fff", d: "M208 58h-28.79L165 36.67a6 6 0 0 0-5-2.67H96a6 6 0 0 0-5 2.67L76.78 58H48a22 22 0 0 0-22 22v112a22 22 0 0 0 22 22h160a22 22 0 0 0 22-22V80a22 22 0 0 0-22-22m10 134a10 10 0 0 1-10 10H48a10 10 0 0 1-10-10V80a10 10 0 0 1 10-10h32a6 6 0 0 0 5-2.67L99.21 46h57.57L171 67.33a6 6 0 0 0 5 2.67h32a10 10 0 0 1 10 10ZM128 90a42 42 0 1 0 42 42a42 42 0 0 0-42-42m0 72a30 30 0 1 1 30-30a30 30 0 0 1-30 30", "stroke-width": "6.5", stroke: "#fff" }))
25559
+ );
25449
25560
  this.svgFullscreen = core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("svg", { onclick: () => {
25450
25561
  this.dispatch("fullscreen");
25451
25562
  }, style: "margin-left: 30px; cursor: pointer", xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24" }, /* @__PURE__ */ jsx_default.h("path", { fill: "white", d: "M4 4h6v2H6v4H4zm10 0h6v6h-2V6h-4zM6 14v4h4v2H4v-6zm14 0v6h-6v-2h4v-4z" })));
@@ -25722,7 +25833,7 @@ var PlaybackBar = class extends Plugin {
25722
25833
  const rightPanel = this.controls.rightControls ? this.controls.rightControls : (() => {
25723
25834
  this.controls.rightControls = core_default.dom.createByJsx(/* @__PURE__ */ jsx_default.h("span", { class: "right-options" }));
25724
25835
  core_default.dom.append(this.svgSound, this.svgSound100);
25725
- core_default.dom.append(this.controls.rightControls, this.svgSound, this.playSpeed, this.svgFullscreen, this.svgOptions, this.optionsContent);
25836
+ core_default.dom.append(this.controls.rightControls, this.svgSound, this.playSpeed, this.svgSnapshot, this.svgFullscreen, this.optionsContent);
25726
25837
  return this.controls.rightControls;
25727
25838
  })();
25728
25839
  const barContent = this.controls.barContent ? this.controls.barContent : this.controls.barContent = core_default.dom.createByJsx(
@@ -26382,6 +26493,10 @@ var PlayBack = (props) => {
26382
26493
  barHandle.addEventListener("fullscreen", () => {
26383
26494
  fullscreen_default.toggle(markerHandle.GetPlayArea());
26384
26495
  });
26496
+ barHandle.addEventListener("snapshot", () => __async(this, null, function* () {
26497
+ const snapshotHandle = yield player.video.screenshot();
26498
+ snapshotHandle == null ? void 0 : snapshotHandle.download();
26499
+ }));
26385
26500
  markerHandle.addEventListener("jump", (params) => {
26386
26501
  barHandle.jumpToTargetSeconds(params);
26387
26502
  });
@@ -14,6 +14,7 @@ interface IPlaybackBarEventMap extends IPluginEventMap {
14
14
  playSpeedChange: {
15
15
  speed: number;
16
16
  };
17
+ snapshot: {};
17
18
  }
18
19
  declare class PlaybackBar extends Plugin<HTMLDivElement, IPlaybackBarEventMap> {
19
20
  private content;
@@ -52,6 +53,7 @@ declare class PlaybackBar extends Plugin<HTMLDivElement, IPlaybackBarEventMap> {
52
53
  private svgSoundZero;
53
54
  private svgSound100;
54
55
  private svgSound;
56
+ private svgSnapshot;
55
57
  private svgFullscreen;
56
58
  private optionsValues;
57
59
  private currenSpeed;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@besovideo/webrtc-player",
3
- "version": "0.10.5",
3
+ "version": "0.10.7",
4
4
  "description": "@besovideo/webrtc-player desc",
5
5
  "type": "module",
6
6
  "types": "./dist/types/main.d.ts",