@besovideo/webrtc-player 0.10.26 → 0.10.28
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 +109 -4
- package/dist/main.browser.css +12 -0
- package/dist/main.browser.js +109 -7
- package/dist/main.es.css +12 -0
- package/dist/main.es.js +109 -7
- package/dist/types/components/global.config.d.ts +2 -0
- package/dist/types/components/playBack.d.ts +2 -0
- package/dist/types/components/puPlayer.d.ts +2 -0
- package/dist/types/main.d.ts +1 -0
- package/dist/types/plugins/player/index.d.ts +3 -0
- package/dist/types/plugins/watermark.d.ts +28 -0
- package/package.json +1 -1
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
|
```
|
package/dist/main.browser.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.browser.js
CHANGED
|
@@ -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.
|
|
127
|
+
define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.28", 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.
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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) => {
|
|
@@ -34816,6 +34911,7 @@ registerProcessor('bv-audio-processor', BVAudioProcessor);
|
|
|
34816
34911
|
}
|
|
34817
34912
|
}
|
|
34818
34913
|
} catch (e) {
|
|
34914
|
+
console.error(e);
|
|
34819
34915
|
}
|
|
34820
34916
|
try {
|
|
34821
34917
|
if (!mediaStream && !!openParams.beCall) {
|
|
@@ -36010,6 +36106,7 @@ a=fmtp:${pt} x-google-start-bitrate=${bitrate}`
|
|
|
36010
36106
|
disableAudio: !!!params.audio
|
|
36011
36107
|
});
|
|
36012
36108
|
if (resultResult.code != "SUCCESS") {
|
|
36109
|
+
processHandle.invoke();
|
|
36013
36110
|
return {
|
|
36014
36111
|
code: resultResult.code,
|
|
36015
36112
|
message: resultResult.message
|
|
@@ -37062,7 +37159,8 @@ a=fmtp:${pt} x-google-start-bitrate=${bitrate}`
|
|
|
37062
37159
|
zIndexMenu,
|
|
37063
37160
|
displayMode,
|
|
37064
37161
|
playbackUrl,
|
|
37065
|
-
cryptkey
|
|
37162
|
+
cryptkey,
|
|
37163
|
+
watermark
|
|
37066
37164
|
} = __spreadValues(__spreadValues({}, defaultProps3), props);
|
|
37067
37165
|
i18n_default(locale);
|
|
37068
37166
|
let hplayer = void 0;
|
|
@@ -37106,7 +37204,11 @@ a=fmtp:${pt} x-google-start-bitrate=${bitrate}`
|
|
|
37106
37204
|
"mike"
|
|
37107
37205
|
],
|
|
37108
37206
|
enableController: false
|
|
37109
|
-
}
|
|
37207
|
+
},
|
|
37208
|
+
watermark: mergeWatermarkConfig(
|
|
37209
|
+
globalConfigHandler.getDefaultProps().watermark,
|
|
37210
|
+
watermark
|
|
37211
|
+
)
|
|
37110
37212
|
});
|
|
37111
37213
|
const barHandle = new PlaybackBar();
|
|
37112
37214
|
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.
|
|
121
|
+
define_processenv_default = { NODE_ENV: "production", SH_LIB_NAME: "@besovideo/webrtc-player", SH_LIB_VERSION: "0.10.28", 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.
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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) => {
|
|
@@ -34798,6 +34893,7 @@ function MediaEndPoint(params) {
|
|
|
34798
34893
|
}
|
|
34799
34894
|
}
|
|
34800
34895
|
} catch (e) {
|
|
34896
|
+
console.error(e);
|
|
34801
34897
|
}
|
|
34802
34898
|
try {
|
|
34803
34899
|
if (!mediaStream && !!openParams.beCall) {
|
|
@@ -35992,6 +36088,7 @@ function pushLocalMedia(params) {
|
|
|
35992
36088
|
disableAudio: !!!params.audio
|
|
35993
36089
|
});
|
|
35994
36090
|
if (resultResult.code != "SUCCESS") {
|
|
36091
|
+
processHandle.invoke();
|
|
35995
36092
|
return {
|
|
35996
36093
|
code: resultResult.code,
|
|
35997
36094
|
message: resultResult.message
|
|
@@ -37044,7 +37141,8 @@ var PlayBack = (props) => {
|
|
|
37044
37141
|
zIndexMenu,
|
|
37045
37142
|
displayMode,
|
|
37046
37143
|
playbackUrl,
|
|
37047
|
-
cryptkey
|
|
37144
|
+
cryptkey,
|
|
37145
|
+
watermark
|
|
37048
37146
|
} = __spreadValues(__spreadValues({}, defaultProps3), props);
|
|
37049
37147
|
i18n_default(locale);
|
|
37050
37148
|
let hplayer = void 0;
|
|
@@ -37088,7 +37186,11 @@ var PlayBack = (props) => {
|
|
|
37088
37186
|
"mike"
|
|
37089
37187
|
],
|
|
37090
37188
|
enableController: false
|
|
37091
|
-
}
|
|
37189
|
+
},
|
|
37190
|
+
watermark: mergeWatermarkConfig(
|
|
37191
|
+
globalConfigHandler.getDefaultProps().watermark,
|
|
37192
|
+
watermark
|
|
37193
|
+
)
|
|
37092
37194
|
});
|
|
37093
37195
|
const barHandle = new PlaybackBar();
|
|
37094
37196
|
this.emitClick = () => {
|
|
@@ -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)[];
|
package/dist/types/main.d.ts
CHANGED
|
@@ -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;
|