@besovideo/webrtc-player 0.10.26 → 0.10.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -33,7 +33,8 @@ import {
33
33
  IPuPlayerProps,
34
34
  IPuPlayerInstance,
35
35
  clearAllDialog,
36
- callEndPointUtils
36
+ callEndPointUtils,
37
+ globalConfigHandler
37
38
  } from "@besovideo/webrtc-player";
38
39
  import "@besovideo/webrtc-player/dist/main.es.css";
39
40
 
@@ -98,6 +99,10 @@ const { instance } = PuPlayer({
98
99
  localRecordCfg?: {
99
100
  //多久产生一个录像文件 5 - 60, 默认 20
100
101
  minuteOneFile ?: number;
102
+ },
103
+ // (可选) 播放窗口水印配置,支持 string 或 string[] 多行水印
104
+ watermark?: {
105
+ text: "测试水印",
101
106
  }
102
107
  });
103
108
 
@@ -465,7 +470,11 @@ const { instance } = PlayBack({
465
470
  zIndexMenu?: number,
466
471
 
467
472
  //(可选) 控制是否显示弹幕,默认显示
468
- displayMode?: 'playback'
473
+ displayMode?: 'playback',
474
+ //(可选)播放窗口水印配置,支持全局配置和实例覆盖
475
+ watermark?: {
476
+ text: "测试水印",
477
+ }
469
478
  })
470
479
 
471
480
  // 打开回放
@@ -473,6 +482,104 @@ instance.open()
473
482
 
474
483
  ```
475
484
 
485
+ **水印配置**
486
+
487
+ `PuPlayer` 和 `PlayBack` 支持水印层。水印是播放窗口上的 DOM/CSS 叠层,不会写入本地录像文件。
488
+
489
+ ```typescript
490
+ import { globalConfigHandler, PuPlayer, PlayBack } from "@besovideo/webrtc-player";
491
+
492
+ interface IWatermarkConfig {
493
+ // 是否启用水印
494
+ enable?: boolean;
495
+ // 水印文本;数组会按多行显示
496
+ text?: string | string[];
497
+ // 水印透明度
498
+ opacity?: number;
499
+ // 字号
500
+ fontSize?: number;
501
+ // 字重
502
+ fontWeight?: number | string;
503
+ // 文字颜色
504
+ color?: string;
505
+ // 描边颜色
506
+ strokeColor?: string;
507
+ // 描边宽度
508
+ strokeWidth?: number;
509
+ // 旋转角度
510
+ rotate?: number;
511
+ // 最小横向间距
512
+ gapX?: number;
513
+ // 最小纵向间距
514
+ gapY?: number;
515
+ // 大屏自适应密度:最多显示的列数
516
+ maxColumns?: number;
517
+ // 大屏自适应密度:最多显示的行数
518
+ maxRows?: number;
519
+ // 可选,水印层级;默认不设置
520
+ zIndex?: number;
521
+ }
522
+
523
+ // 全局配置:影响之后创建的 PuPlayer 和 PlayBack 实例
524
+ globalConfigHandler.setDefaultProps({
525
+ watermark: {
526
+ // 支持 string 或 string[],数组会按多行显示
527
+ text: ["测试水印", "仅供内部使用"],
528
+ // 是否启用水印,默认 true;设置为 false 可关闭
529
+ enable: true,
530
+ // 水印透明度,默认 0.28
531
+ opacity: 0.28,
532
+ // 字号,默认 16
533
+ fontSize: 16,
534
+ // 字重,默认 normal
535
+ fontWeight: "normal",
536
+ // 文字颜色,默认 #fff
537
+ color: "#fff",
538
+ // 描边颜色,默认 #000,用于提升浅色/复杂画面上的可读性
539
+ strokeColor: "#000",
540
+ // 描边宽度,默认 2
541
+ strokeWidth: 2,
542
+ // 旋转角度,默认 -20
543
+ rotate: -20,
544
+ // 最小横向间距,默认 180
545
+ gapX: 180,
546
+ // 最小纵向间距,默认 120
547
+ gapY: 120,
548
+ // 大屏自适应密度:最多约 4 列,默认 4
549
+ maxColumns: 4,
550
+ // 大屏自适应密度:最多约 3 行,默认 3
551
+ maxRows: 3,
552
+ // 可选,水印层级;默认不设置,位于视频上方、遮罩和控制层下方
553
+ // zIndex: 1,
554
+ },
555
+ });
556
+
557
+ // 单实例覆盖全局配置
558
+ PuPlayer({
559
+ // ...
560
+ watermark: {
561
+ text: "当前设备水印",
562
+ maxColumns: 3,
563
+ maxRows: 2,
564
+ },
565
+ });
566
+
567
+ // 单实例关闭水印
568
+ PlayBack({
569
+ // ...
570
+ watermark: {
571
+ enable: false,
572
+ },
573
+ });
574
+ ```
575
+
576
+ 水印间距会根据播放窗口大小自动调整。`gapX` / `gapY` 表示最小间距,`maxColumns` / `maxRows` 用于限制大屏下最多显示的水印密度:
577
+
578
+ ```typescript
579
+ 实际横向间距 = Math.max(gapX, 播放窗口宽度 / maxColumns)
580
+ 实际纵向间距 = Math.max(gapY, 播放窗口高度 / maxRows)
581
+ ```
582
+
476
583
  ***媒体流推送***
477
584
  ``` typescript
478
585
  const callEndPointUtils: {
@@ -665,8 +772,6 @@ yarn start
665
772
  yarn version
666
773
  yarn build
667
774
  yarn publish
668
- # 版本号按照 Major.Minor.Patch 规范
669
- # 可参考https://www.jianshu.com/p/c675121a8bfd
670
775
 
671
776
 
672
777
  ```
@@ -521,6 +521,18 @@
521
521
  width: 100%;
522
522
  height: 100%;
523
523
  }
524
+ .bvplayer-watermark {
525
+ position: absolute;
526
+ top: 0;
527
+ right: 0;
528
+ bottom: 0;
529
+ left: 0;
530
+ width: 100%;
531
+ height: 100%;
532
+ overflow: hidden;
533
+ pointer-events: none;
534
+ background-repeat: repeat;
535
+ }
524
536
  .bvplayer-controller {
525
537
  position: absolute;
526
538
  bottom: 0;
@@ -124,7 +124,7 @@ var bvPlayerCore = (() => {
124
124
  var define_processenv_default;
125
125
  var init_define_processenv = __esm({
126
126
  "<define:processenv>"() {
127
- define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.26", PROJECT_NAMESPACE: "bvplayer" };
127
+ define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.27", PROJECT_NAMESPACE: "bvplayer" };
128
128
  }
129
129
  });
130
130
 
@@ -21890,10 +21890,7 @@ padding: 2px 5px;
21890
21890
  return glbConfig;
21891
21891
  },
21892
21892
  setDefaultProps: function(props) {
21893
- Object.keys(props).forEach((itemKey) => {
21894
- const key = itemKey;
21895
- glbConfig[key] = props[key];
21896
- });
21893
+ Object.assign(glbConfig, props);
21897
21894
  }
21898
21895
  };
21899
21896
 
@@ -29083,6 +29080,96 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
29083
29080
  };
29084
29081
  var recordState_default = RecordStatePlugin;
29085
29082
 
29083
+ // src/plugins/watermark.ts
29084
+ init_define_processenv();
29085
+ init_jsx_shim();
29086
+ var PLUGIN_NAME_WATERMARK = "watermark";
29087
+ var defaultWatermarkConfig = {
29088
+ enable: true,
29089
+ opacity: 0.28,
29090
+ fontSize: 16,
29091
+ fontWeight: "normal",
29092
+ color: "#fff",
29093
+ strokeColor: "#000",
29094
+ strokeWidth: 2,
29095
+ rotate: -20,
29096
+ gapX: 180,
29097
+ gapY: 120,
29098
+ maxColumns: 4,
29099
+ maxRows: 3
29100
+ };
29101
+ var escapeXml = (text2) => text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
29102
+ var normalizeText = (text2) => {
29103
+ if (typeof text2 === "string")
29104
+ return text2 ? [text2] : [];
29105
+ return (text2 || []).filter((item) => item);
29106
+ };
29107
+ var createWatermarkSvg = (config) => {
29108
+ const lineHeight = Math.round(config.fontSize * 1.5);
29109
+ const startY = config.gapY / 2 - (config.text.length - 1) * lineHeight / 2;
29110
+ const textNodes = config.text.map((item, index) => {
29111
+ const y2 = startY + index * lineHeight;
29112
+ return `<text x="50%" y="${y2}" text-anchor="middle">${escapeXml(item)}</text>`;
29113
+ }).join("");
29114
+ return `
29115
+ <svg xmlns="http://www.w3.org/2000/svg" width="${config.gapX}" height="${config.gapY}" viewBox="0 0 ${config.gapX} ${config.gapY}">
29116
+ <g transform="rotate(${config.rotate} ${config.gapX / 2} ${config.gapY / 2})" fill="${escapeXml(config.color)}" fill-opacity="${config.opacity}" stroke="${escapeXml(config.strokeColor)}" stroke-opacity="${config.opacity}" stroke-width="${config.strokeWidth}" paint-order="stroke" font-size="${config.fontSize}" font-weight="${escapeXml(`${config.fontWeight}`)}" font-family="Arial, sans-serif">
29117
+ ${textNodes}
29118
+ </g>
29119
+ </svg>`;
29120
+ };
29121
+ var mergeWatermarkConfig = (...configs) => {
29122
+ return configs.reduce((result, config) => {
29123
+ if (!config)
29124
+ return result;
29125
+ return __spreadValues(__spreadValues({}, result), config);
29126
+ }, {});
29127
+ };
29128
+ var WatermarkPlugin = class extends Plugin {
29129
+ constructor(config) {
29130
+ super(PLUGIN_NAME_WATERMARK, "div");
29131
+ this._config = config || {};
29132
+ }
29133
+ init(_container) {
29134
+ this.render();
29135
+ if (this.el && window.ResizeObserver) {
29136
+ this._resizeObserver = new ResizeObserver(() => {
29137
+ this.render();
29138
+ });
29139
+ this._resizeObserver.observe(this.el);
29140
+ }
29141
+ return this.el;
29142
+ }
29143
+ beforeDestroy() {
29144
+ var _a;
29145
+ (_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
29146
+ }
29147
+ render() {
29148
+ if (!this.el)
29149
+ return;
29150
+ const config = __spreadProps(__spreadValues(__spreadValues({}, defaultWatermarkConfig), this._config), {
29151
+ text: normalizeText(this._config.text)
29152
+ });
29153
+ if (!config.enable || !config.text.length) {
29154
+ this.el.style.display = "none";
29155
+ this.el.style.backgroundImage = "";
29156
+ return;
29157
+ }
29158
+ const gapX = config.maxColumns > 0 ? Math.max(config.gapX, this.el.clientWidth / config.maxColumns) : config.gapX;
29159
+ const gapY = config.maxRows > 0 ? Math.max(config.gapY, this.el.clientHeight / config.maxRows) : config.gapY;
29160
+ const renderConfig = __spreadProps(__spreadValues({}, config), {
29161
+ gapX,
29162
+ gapY
29163
+ });
29164
+ const svg = createWatermarkSvg(renderConfig);
29165
+ this.el.style.display = "block";
29166
+ this.el.style.zIndex = typeof config.zIndex === "number" ? `${config.zIndex}` : "";
29167
+ this.el.style.backgroundImage = `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}")`;
29168
+ this.el.style.backgroundSize = `${gapX}px ${gapY}px`;
29169
+ }
29170
+ };
29171
+ var watermark_default = WatermarkPlugin;
29172
+
29086
29173
  // src/plugins/player/index.tsx
29087
29174
  var DIRECT_SUPPORT_TYPES = /* @__PURE__ */ ((DIRECT_SUPPORT_TYPES2) => {
29088
29175
  DIRECT_SUPPORT_TYPES2["MP4"] = "MP4";
@@ -29122,6 +29209,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
29122
29209
  this._spinner = new spinner_default({ spin: false });
29123
29210
  this._toast = new toast_default();
29124
29211
  this._mask = new mask_default({ visible: false });
29212
+ this._watermark = new watermark_default(options == null ? void 0 : options.watermark);
29125
29213
  this._infoModal = new ModalPlugin({
29126
29214
  container: this.el,
29127
29215
  title: t("info"),
@@ -29172,6 +29260,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
29172
29260
  const spinnerEl = this._spinner.init();
29173
29261
  const toastEl = this._toast.init();
29174
29262
  const maskEl = this._mask.init();
29263
+ const watermarkEl = this._watermark.init();
29175
29264
  const panelEls = this._panel ? this._panel.init() : [];
29176
29265
  const infoModalEl = this._infoModal.init();
29177
29266
  const ptzEl = this.ptz.init();
@@ -29179,6 +29268,7 @@ ${event.candidate ? event.candidate.candidate : "(null)"}`
29179
29268
  core_default.dom.append(
29180
29269
  this.el,
29181
29270
  videoEl,
29271
+ watermarkEl,
29182
29272
  spinnerEl,
29183
29273
  maskEl,
29184
29274
  infoModalEl,
@@ -33511,6 +33601,7 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
33511
33601
  puOption,
33512
33602
  defaultMediaOption = { audio: true, video: true },
33513
33603
  testUrl,
33604
+ watermark,
33514
33605
  videoFit = "fill",
33515
33606
  muted,
33516
33607
  apiPrefix,
@@ -33630,6 +33721,10 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
33630
33721
  enableController,
33631
33722
  disabledControls
33632
33723
  },
33724
+ watermark: mergeWatermarkConfig(
33725
+ globalConfigHandler.getDefaultProps().watermark,
33726
+ watermark
33727
+ ),
33633
33728
  recorderConfig: localRecordCfg
33634
33729
  });
33635
33730
  player.addEventListener("init", (e) => {
@@ -37062,7 +37157,8 @@ a=fmtp:${pt} x-google-start-bitrate=${bitrate}`
37062
37157
  zIndexMenu,
37063
37158
  displayMode,
37064
37159
  playbackUrl,
37065
- cryptkey
37160
+ cryptkey,
37161
+ watermark
37066
37162
  } = __spreadValues(__spreadValues({}, defaultProps3), props);
37067
37163
  i18n_default(locale);
37068
37164
  let hplayer = void 0;
@@ -37106,7 +37202,11 @@ a=fmtp:${pt} x-google-start-bitrate=${bitrate}`
37106
37202
  "mike"
37107
37203
  ],
37108
37204
  enableController: false
37109
- }
37205
+ },
37206
+ watermark: mergeWatermarkConfig(
37207
+ globalConfigHandler.getDefaultProps().watermark,
37208
+ watermark
37209
+ )
37110
37210
  });
37111
37211
  const barHandle = new PlaybackBar();
37112
37212
  this.emitClick = () => {
package/dist/main.es.css CHANGED
@@ -521,6 +521,18 @@
521
521
  width: 100%;
522
522
  height: 100%;
523
523
  }
524
+ .bvplayer-watermark {
525
+ position: absolute;
526
+ top: 0;
527
+ right: 0;
528
+ bottom: 0;
529
+ left: 0;
530
+ width: 100%;
531
+ height: 100%;
532
+ overflow: hidden;
533
+ pointer-events: none;
534
+ background-repeat: repeat;
535
+ }
524
536
  .bvplayer-controller {
525
537
  position: absolute;
526
538
  bottom: 0;
package/dist/main.es.js CHANGED
@@ -118,7 +118,7 @@ var __async = (__this, __arguments, generator) => {
118
118
  var define_processenv_default;
119
119
  var init_define_processenv = __esm({
120
120
  "<define:processenv>"() {
121
- define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.26", PROJECT_NAMESPACE: "bvplayer" };
121
+ define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.27", PROJECT_NAMESPACE: "bvplayer" };
122
122
  }
123
123
  });
124
124
 
@@ -21872,10 +21872,7 @@ var globalConfigHandler = {
21872
21872
  return glbConfig;
21873
21873
  },
21874
21874
  setDefaultProps: function(props) {
21875
- Object.keys(props).forEach((itemKey) => {
21876
- const key = itemKey;
21877
- glbConfig[key] = props[key];
21878
- });
21875
+ Object.assign(glbConfig, props);
21879
21876
  }
21880
21877
  };
21881
21878
 
@@ -29065,6 +29062,96 @@ var RecordStatePlugin = class extends Plugin {
29065
29062
  };
29066
29063
  var recordState_default = RecordStatePlugin;
29067
29064
 
29065
+ // src/plugins/watermark.ts
29066
+ init_define_processenv();
29067
+ init_jsx_shim();
29068
+ var PLUGIN_NAME_WATERMARK = "watermark";
29069
+ var defaultWatermarkConfig = {
29070
+ enable: true,
29071
+ opacity: 0.28,
29072
+ fontSize: 16,
29073
+ fontWeight: "normal",
29074
+ color: "#fff",
29075
+ strokeColor: "#000",
29076
+ strokeWidth: 2,
29077
+ rotate: -20,
29078
+ gapX: 180,
29079
+ gapY: 120,
29080
+ maxColumns: 4,
29081
+ maxRows: 3
29082
+ };
29083
+ var escapeXml = (text2) => text2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
29084
+ var normalizeText = (text2) => {
29085
+ if (typeof text2 === "string")
29086
+ return text2 ? [text2] : [];
29087
+ return (text2 || []).filter((item) => item);
29088
+ };
29089
+ var createWatermarkSvg = (config) => {
29090
+ const lineHeight = Math.round(config.fontSize * 1.5);
29091
+ const startY = config.gapY / 2 - (config.text.length - 1) * lineHeight / 2;
29092
+ const textNodes = config.text.map((item, index) => {
29093
+ const y2 = startY + index * lineHeight;
29094
+ return `<text x="50%" y="${y2}" text-anchor="middle">${escapeXml(item)}</text>`;
29095
+ }).join("");
29096
+ return `
29097
+ <svg xmlns="http://www.w3.org/2000/svg" width="${config.gapX}" height="${config.gapY}" viewBox="0 0 ${config.gapX} ${config.gapY}">
29098
+ <g transform="rotate(${config.rotate} ${config.gapX / 2} ${config.gapY / 2})" fill="${escapeXml(config.color)}" fill-opacity="${config.opacity}" stroke="${escapeXml(config.strokeColor)}" stroke-opacity="${config.opacity}" stroke-width="${config.strokeWidth}" paint-order="stroke" font-size="${config.fontSize}" font-weight="${escapeXml(`${config.fontWeight}`)}" font-family="Arial, sans-serif">
29099
+ ${textNodes}
29100
+ </g>
29101
+ </svg>`;
29102
+ };
29103
+ var mergeWatermarkConfig = (...configs) => {
29104
+ return configs.reduce((result, config) => {
29105
+ if (!config)
29106
+ return result;
29107
+ return __spreadValues(__spreadValues({}, result), config);
29108
+ }, {});
29109
+ };
29110
+ var WatermarkPlugin = class extends Plugin {
29111
+ constructor(config) {
29112
+ super(PLUGIN_NAME_WATERMARK, "div");
29113
+ this._config = config || {};
29114
+ }
29115
+ init(_container) {
29116
+ this.render();
29117
+ if (this.el && window.ResizeObserver) {
29118
+ this._resizeObserver = new ResizeObserver(() => {
29119
+ this.render();
29120
+ });
29121
+ this._resizeObserver.observe(this.el);
29122
+ }
29123
+ return this.el;
29124
+ }
29125
+ beforeDestroy() {
29126
+ var _a;
29127
+ (_a = this._resizeObserver) == null ? void 0 : _a.disconnect();
29128
+ }
29129
+ render() {
29130
+ if (!this.el)
29131
+ return;
29132
+ const config = __spreadProps(__spreadValues(__spreadValues({}, defaultWatermarkConfig), this._config), {
29133
+ text: normalizeText(this._config.text)
29134
+ });
29135
+ if (!config.enable || !config.text.length) {
29136
+ this.el.style.display = "none";
29137
+ this.el.style.backgroundImage = "";
29138
+ return;
29139
+ }
29140
+ const gapX = config.maxColumns > 0 ? Math.max(config.gapX, this.el.clientWidth / config.maxColumns) : config.gapX;
29141
+ const gapY = config.maxRows > 0 ? Math.max(config.gapY, this.el.clientHeight / config.maxRows) : config.gapY;
29142
+ const renderConfig = __spreadProps(__spreadValues({}, config), {
29143
+ gapX,
29144
+ gapY
29145
+ });
29146
+ const svg = createWatermarkSvg(renderConfig);
29147
+ this.el.style.display = "block";
29148
+ this.el.style.zIndex = typeof config.zIndex === "number" ? `${config.zIndex}` : "";
29149
+ this.el.style.backgroundImage = `url("data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}")`;
29150
+ this.el.style.backgroundSize = `${gapX}px ${gapY}px`;
29151
+ }
29152
+ };
29153
+ var watermark_default = WatermarkPlugin;
29154
+
29068
29155
  // src/plugins/player/index.tsx
29069
29156
  var DIRECT_SUPPORT_TYPES = /* @__PURE__ */ ((DIRECT_SUPPORT_TYPES2) => {
29070
29157
  DIRECT_SUPPORT_TYPES2["MP4"] = "MP4";
@@ -29104,6 +29191,7 @@ var PlayerPlugin = class extends Plugin {
29104
29191
  this._spinner = new spinner_default({ spin: false });
29105
29192
  this._toast = new toast_default();
29106
29193
  this._mask = new mask_default({ visible: false });
29194
+ this._watermark = new watermark_default(options == null ? void 0 : options.watermark);
29107
29195
  this._infoModal = new ModalPlugin({
29108
29196
  container: this.el,
29109
29197
  title: t("info"),
@@ -29154,6 +29242,7 @@ var PlayerPlugin = class extends Plugin {
29154
29242
  const spinnerEl = this._spinner.init();
29155
29243
  const toastEl = this._toast.init();
29156
29244
  const maskEl = this._mask.init();
29245
+ const watermarkEl = this._watermark.init();
29157
29246
  const panelEls = this._panel ? this._panel.init() : [];
29158
29247
  const infoModalEl = this._infoModal.init();
29159
29248
  const ptzEl = this.ptz.init();
@@ -29161,6 +29250,7 @@ var PlayerPlugin = class extends Plugin {
29161
29250
  core_default.dom.append(
29162
29251
  this.el,
29163
29252
  videoEl,
29253
+ watermarkEl,
29164
29254
  spinnerEl,
29165
29255
  maskEl,
29166
29256
  infoModalEl,
@@ -33493,6 +33583,7 @@ var PuPlayer = (props) => {
33493
33583
  puOption,
33494
33584
  defaultMediaOption = { audio: true, video: true },
33495
33585
  testUrl,
33586
+ watermark,
33496
33587
  videoFit = "fill",
33497
33588
  muted,
33498
33589
  apiPrefix,
@@ -33612,6 +33703,10 @@ var PuPlayer = (props) => {
33612
33703
  enableController,
33613
33704
  disabledControls
33614
33705
  },
33706
+ watermark: mergeWatermarkConfig(
33707
+ globalConfigHandler.getDefaultProps().watermark,
33708
+ watermark
33709
+ ),
33615
33710
  recorderConfig: localRecordCfg
33616
33711
  });
33617
33712
  player.addEventListener("init", (e) => {
@@ -37044,7 +37139,8 @@ var PlayBack = (props) => {
37044
37139
  zIndexMenu,
37045
37140
  displayMode,
37046
37141
  playbackUrl,
37047
- cryptkey
37142
+ cryptkey,
37143
+ watermark
37048
37144
  } = __spreadValues(__spreadValues({}, defaultProps3), props);
37049
37145
  i18n_default(locale);
37050
37146
  let hplayer = void 0;
@@ -37088,7 +37184,11 @@ var PlayBack = (props) => {
37088
37184
  "mike"
37089
37185
  ],
37090
37186
  enableController: false
37091
- }
37187
+ },
37188
+ watermark: mergeWatermarkConfig(
37189
+ globalConfigHandler.getDefaultProps().watermark,
37190
+ watermark
37191
+ )
37092
37192
  });
37093
37193
  const barHandle = new PlaybackBar();
37094
37194
  this.emitClick = () => {
@@ -1,5 +1,7 @@
1
+ import { IWatermarkConfig } from "../plugins/watermark";
1
2
  export interface IGlobalConfig {
2
3
  bNotSendHost?: boolean;
4
+ watermark?: IWatermarkConfig;
3
5
  }
4
6
  export declare const globalConfigHandler: {
5
7
  getDefaultProps: () => Partial<IGlobalConfig>;
@@ -1,6 +1,7 @@
1
1
  import { SFC, Props, IComponentInstance } from "../core/types";
2
2
  import { IVideoFits } from "../plugins/player";
3
3
  import initI18n from "../locales/i18n";
4
+ import { IWatermarkConfig } from "../plugins/watermark";
4
5
  type Container = HTMLElement | Element | Node | null;
5
6
  interface IPlaybackProps extends Props {
6
7
  fileID: string;
@@ -26,6 +27,7 @@ interface IPlaybackProps extends Props {
26
27
  zIndexMenu?: number;
27
28
  displayMode?: 'playback';
28
29
  cryptkey?: string;
30
+ watermark?: IWatermarkConfig;
29
31
  }
30
32
  type IPlaybackPlayType = "ws-bvrtc" | "web" | "auto";
31
33
  interface IPlaybackInstance extends IComponentInstance {
@@ -4,6 +4,7 @@ import { IPuOption } from "./types";
4
4
  import { IControlPluginMap } from "../plugins/controller";
5
5
  import { MikeButton } from "./subComponent/mikeButton";
6
6
  import { CreatePlayerState } from "./subComponent/playState";
7
+ import { IWatermarkConfig } from "../plugins/watermark";
7
8
  type Container = HTMLElement | Element | Node | null;
8
9
  type helperFunc = {
9
10
  getDefaultProps: () => Partial<IPuPlayerProps>;
@@ -26,6 +27,7 @@ export interface IPuPlayerProps extends Props {
26
27
  videoFit?: keyof IVideoFits;
27
28
  apiPrefix?: string;
28
29
  testUrl?: string;
30
+ watermark?: IWatermarkConfig;
29
31
  fullScreenOnDblclick?: boolean;
30
32
  enableController?: boolean;
31
33
  disabledControls?: (keyof IControlPluginMap)[];
@@ -10,3 +10,4 @@ declare const clearAllDialog: (token: string) => Promise<void>;
10
10
  import "./styles/main.scss";
11
11
  import { globalConfigHandler } from "./components/global.config";
12
12
  export { globalConfigHandler, PlayBack, PuPlayer, Intercom, Conference, IPuPlayerProps, IPuPlayerInstance, IIntercomProps, IIntercomInstance, IConferenceProps, IConferenceInstance, IPuOption, IConfOption, RemoteSdpFetcher, clearAllDialog, CreateCallEndPoint, callEndPointUtils };
13
+ export type { IWatermarkConfig } from "./plugins/watermark";
@@ -12,6 +12,7 @@ import PtzPlugin from "../ptz";
12
12
  import { CreateIntercomUtils, MikeButton } from "../../components/subComponent/mikeButton";
13
13
  import { IPuOption } from "../../main";
14
14
  import { IRecorderConfig } from "src/utils/webmContainerUtils";
15
+ import { IWatermarkConfig } from "../watermark";
15
16
  export declare enum PLAYER_MODES {
16
17
  DIRECT = "direct",
17
18
  PLUGIN = "plugin",
@@ -52,6 +53,7 @@ export interface IPlayerPluginOptions {
52
53
  direct: string;
53
54
  puOptions: IPuOption;
54
55
  recorderConfig?: IRecorderConfig;
56
+ watermark?: IWatermarkConfig;
55
57
  }
56
58
  declare class PlayerPlugin extends Plugin<HTMLDivElement, IPlayerPluginEventMap> {
57
59
  private _mode;
@@ -63,6 +65,7 @@ declare class PlayerPlugin extends Plugin<HTMLDivElement, IPlayerPluginEventMap>
63
65
  private _spinner;
64
66
  private _toast;
65
67
  private _mask;
68
+ private _watermark;
66
69
  private _panel?;
67
70
  private _infoModal;
68
71
  private _recordState;
@@ -0,0 +1,28 @@
1
+ import { RenderTarget } from "../core/types";
2
+ import { Plugin } from "./types";
3
+ export interface IWatermarkConfig {
4
+ enable?: boolean;
5
+ text?: string | string[];
6
+ opacity?: number;
7
+ fontSize?: number;
8
+ fontWeight?: number | string;
9
+ color?: string;
10
+ strokeColor?: string;
11
+ strokeWidth?: number;
12
+ rotate?: number;
13
+ gapX?: number;
14
+ gapY?: number;
15
+ maxColumns?: number;
16
+ maxRows?: number;
17
+ zIndex?: number;
18
+ }
19
+ export declare const mergeWatermarkConfig: (...configs: Array<IWatermarkConfig | undefined>) => IWatermarkConfig;
20
+ declare class WatermarkPlugin extends Plugin<HTMLDivElement> {
21
+ private _config;
22
+ private _resizeObserver?;
23
+ constructor(config?: IWatermarkConfig);
24
+ init(_container?: RenderTarget): RenderTarget;
25
+ protected beforeDestroy(): void;
26
+ render(): void;
27
+ }
28
+ export default WatermarkPlugin;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@besovideo/webrtc-player",
3
- "version": "0.10.26",
3
+ "version": "0.10.27",
4
4
  "description": "@besovideo/webrtc-player desc",
5
5
  "type": "module",
6
6
  "types": "./dist/types/main.d.ts",