@ezuikit/player-theme 3.1.6-beta.1 → 3.1.7-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import EventEmitter from 'eventemitter3';
2
- import Picker from '@skax/picker';
3
- import I18n, { I18nTranslation } from '@ezuikit/utils-i18n';
2
+ import I18n, { TranslateVariables, I18nTranslation } from '@ezuikit/utils-i18n';
4
3
  import { LoggerCls, LoggerOptions } from '@ezuikit/utils-logger';
4
+ import Picker from '@skax/picker';
5
5
  import { BasePtzOptions } from '@ezuikit/control-ptz';
6
6
  import { RecListModalOptions } from '@ezuikit/control-rec-list-modal';
7
7
  import * as _ezuikit_utils_tools from '@ezuikit/utils-tools';
@@ -19,6 +19,74 @@ declare const THEME_SCALE_MODE_TYPE: {
19
19
  readonly fullAuto: 2;
20
20
  };
21
21
  declare const THEME_PROPS: readonly ["width", "height", "playing", "volume", "muted", "loading", "recType", "isCurrentFullscreen", "orientationAngle", "zooming", "zoom", "recording", "recordList", "speed", "urlInfo", "videoLevelList", "videoLevel", "recMonth", "url", "playbackRange"];
22
+ /**
23
+ * 全部播放类型:直播 + 三种回放
24
+ *
25
+ * 控件用静态属性 `supportedPlayTypes` 声明支持范围,默认取本数组(即全支持)。
26
+ * 与 {@link REC_GROUP} 的区别:REC_GROUP 是「回放类型切换控件的 iconId 分组」,
27
+ * 这里是「播放地址实际解析出的播放类型」,两者取值恰好在回放侧重合。
28
+ */
29
+ declare const PLAY_TYPES: readonly ["live", "rec", "cloudRec", "cloudRecord"];
30
+ /**
31
+ * 控件初始化完成事件名
32
+ *
33
+ * 键与 `Controls`(`src/Controls/index.ts`)的键一一对应,值为 `Control.<键>ControlInit`,
34
+ * 在控件实例创建成功后由 `_renderTheme` 派发一次,无载荷。
35
+ *
36
+ * 这些成员会被展开进 {@link EVENTS}.control,因此既可以 `EVENTS.control.playControlInit`
37
+ * 这样按名取用,也可以在只拿到 `iconId` 的场合用 `CONTROL_INIT_EVENTS[iconId]` 查表。
38
+ *
39
+ * @remarks `changeTheme` 会先卸载旧控件并重置 `theme.controls`,因此切换主题时这些事件会再次派发;
40
+ * 同一次渲染内则由 `!theme.controls.xxxControl` 守卫保证只派发一次。
41
+ */
42
+ declare const CONTROL_INIT_EVENTS: {
43
+ /** 播放/暂停控件初始化完成 */
44
+ readonly playControlInit: "Control.playControlInit";
45
+ /** 音量控件初始化完成 */
46
+ readonly volumeControlInit: "Control.volumeControlInit";
47
+ /** 设备信息控件初始化完成 */
48
+ readonly deviceControlInit: "Control.deviceControlInit";
49
+ /** 截图控件初始化完成 */
50
+ readonly capturePictureControlInit: "Control.capturePictureControlInit";
51
+ /** 云台控件初始化完成 */
52
+ readonly ptzControlInit: "Control.ptzControlInit";
53
+ /** 录制控件初始化完成 */
54
+ readonly recordControlInit: "Control.recordControlInit";
55
+ /** 对讲控件初始化完成 */
56
+ readonly talkControlInit: "Control.talkControlInit";
57
+ /** 语音广播控件初始化完成 */
58
+ readonly broadcastControlInit: "Control.broadcastControlInit";
59
+ /** AI 对话控件初始化完成 */
60
+ readonly aiChatControlInit: "Control.aiChatControlInit";
61
+ /** 直播按钮控件初始化完成 */
62
+ readonly liveControlInit: "Control.liveControlInit";
63
+ /** 回放下拉控件初始化完成 */
64
+ readonly recDropdownControlInit: "Control.recDropdownControlInit";
65
+ /** 录像列表控件初始化完成 */
66
+ readonly recListControlInit: "Control.recListControlInit";
67
+ /** 告警消息控件初始化完成 */
68
+ readonly alarmMessageControlInit: "Control.alarmMessageControlInit";
69
+ /** 电子放大控件初始化完成 */
70
+ readonly zoomControlInit: "Control.zoomControlInit";
71
+ /** 清晰度控件初始化完成 */
72
+ readonly definitionControlInit: "Control.definitionControlInit";
73
+ /** web 全屏控件初始化完成 */
74
+ readonly fullscreenControlInit: "Control.fullscreenControlInit";
75
+ /** 全局全屏控件初始化完成 */
76
+ readonly globalFullscreenControlInit: "Control.globalFullscreenControlInit";
77
+ /** 回放类型控件初始化完成 */
78
+ readonly recControlInit: "Control.recControlInit";
79
+ /** 倍速控件初始化完成 */
80
+ readonly speedControlInit: "Control.speedControlInit";
81
+ /** 日历控件初始化完成 */
82
+ readonly dateControlInit: "Control.dateControlInit";
83
+ /** 时间选择控件初始化完成 */
84
+ readonly timeControlInit: "Control.timeControlInit";
85
+ /** 时间轴控件初始化完成 */
86
+ readonly timeLineControlInit: "Control.timeLineControlInit";
87
+ /** 回放片段进度条控件初始化完成 */
88
+ readonly segmentProgressControlInit: "Control.segmentProgressControlInit";
89
+ };
22
90
  /**
23
91
  *
24
92
  * 事件名
@@ -224,7 +292,7 @@ declare const EVENTS: {
224
292
  /** 日期面板展示的年份变化 */
225
293
  readonly datePanelYearChange: "Control.datePanelYearChange";
226
294
  /** 日期销毁 */
227
- readonly dateDestroy: "Control.datePanelDestroy";
295
+ readonly dateDestroy: "Control.dateDestroy";
228
296
  /** 时间面板展示隐藏变换 */
229
297
  readonly timePanelOpenChange: "Control.timePanelOpenChange";
230
298
  /** 时间改变 */
@@ -235,6 +303,8 @@ declare const EVENTS: {
235
303
  readonly timeLinePanelOpenChange: "Control.timeLinePanelOpenChange";
236
304
  /** 时间轴控件销毁 */
237
305
  readonly timeLineDestroy: "Control.timeLineDestroy";
306
+ /** 控件不支持当前播放类型(仅提示,控件仍会渲染) */
307
+ readonly unsupportedPlayType: "Control.unsupportedPlayType";
238
308
  /** 主题控件挂载前 切换新的主题也会触发,如果想首次获取需要在 onInitializing 回调中进行监听 */
239
309
  readonly beforeMountControls: "Control.beforeMountControls";
240
310
  /** 主题控件挂载完成, 切换新的主题也会触发,如果想首次获取需要在 onInitializing 回调中进行监听 */
@@ -253,6 +323,52 @@ declare const EVENTS: {
253
323
  readonly contentDestroy: "Control.contentDestroy";
254
324
  /** 播放器内容区域重新渲染 */
255
325
  readonly contentRerender: "Control.contentRerender";
326
+ /** 播放/暂停控件初始化完成 */
327
+ readonly playControlInit: "Control.playControlInit";
328
+ /** 音量控件初始化完成 */
329
+ readonly volumeControlInit: "Control.volumeControlInit";
330
+ /** 设备信息控件初始化完成 */
331
+ readonly deviceControlInit: "Control.deviceControlInit";
332
+ /** 截图控件初始化完成 */
333
+ readonly capturePictureControlInit: "Control.capturePictureControlInit";
334
+ /** 云台控件初始化完成 */
335
+ readonly ptzControlInit: "Control.ptzControlInit";
336
+ /** 录制控件初始化完成 */
337
+ readonly recordControlInit: "Control.recordControlInit";
338
+ /** 对讲控件初始化完成 */
339
+ readonly talkControlInit: "Control.talkControlInit";
340
+ /** 语音广播控件初始化完成 */
341
+ readonly broadcastControlInit: "Control.broadcastControlInit";
342
+ /** AI 对话控件初始化完成 */
343
+ readonly aiChatControlInit: "Control.aiChatControlInit";
344
+ /** 直播按钮控件初始化完成 */
345
+ readonly liveControlInit: "Control.liveControlInit";
346
+ /** 回放下拉控件初始化完成 */
347
+ readonly recDropdownControlInit: "Control.recDropdownControlInit";
348
+ /** 录像列表控件初始化完成 */
349
+ readonly recListControlInit: "Control.recListControlInit";
350
+ /** 告警消息控件初始化完成 */
351
+ readonly alarmMessageControlInit: "Control.alarmMessageControlInit";
352
+ /** 电子放大控件初始化完成 */
353
+ readonly zoomControlInit: "Control.zoomControlInit";
354
+ /** 清晰度控件初始化完成 */
355
+ readonly definitionControlInit: "Control.definitionControlInit";
356
+ /** web 全屏控件初始化完成 */
357
+ readonly fullscreenControlInit: "Control.fullscreenControlInit";
358
+ /** 全局全屏控件初始化完成 */
359
+ readonly globalFullscreenControlInit: "Control.globalFullscreenControlInit";
360
+ /** 回放类型控件初始化完成 */
361
+ readonly recControlInit: "Control.recControlInit";
362
+ /** 倍速控件初始化完成 */
363
+ readonly speedControlInit: "Control.speedControlInit";
364
+ /** 日历控件初始化完成 */
365
+ readonly dateControlInit: "Control.dateControlInit";
366
+ /** 时间选择控件初始化完成 */
367
+ readonly timeControlInit: "Control.timeControlInit";
368
+ /** 时间轴控件初始化完成 */
369
+ readonly timeLineControlInit: "Control.timeLineControlInit";
370
+ /** 回放片段进度条控件初始化完成 */
371
+ readonly segmentProgressControlInit: "Control.segmentProgressControlInit";
256
372
  };
257
373
  /**
258
374
  * 主题控件相关
@@ -271,201 +387,129 @@ declare const EVENTS: {
271
387
  };
272
388
 
273
389
  /**
274
- * 控件基类配置项
275
- */
276
- interface ControlOptions {
277
- /** 播放器窗口节点 */
278
- rootContainer?: HTMLElement;
279
- /** 挂载节点 player id, 默认挂载 body 上 */
280
- getPopupContainer?: () => HTMLElement;
281
- /** 给控件新增自定义类名 */
282
- className?: string;
283
- /** 语言数据 */
284
- locale?: Record<string, string>;
285
- /** 样式类后缀 */
286
- classNameSuffix?: string;
287
- /**
288
- * 渲染节点标签
289
- */
290
- tagName?: 'div' | 'span';
291
- /**
292
- * 控件类型, 默认 button
293
- */
294
- controlType?: 'button' | 'text' | 'block';
295
- /**
296
- * 当前语言
297
- */
298
- language?: 'zh' | 'en' | string;
299
- /**
300
- * 所有语言数据
301
- */
302
- locales?: Record<string, Record<string | number, string | number>>;
303
- /** 点击控件时的回调 */
304
- onClick?: (e: Event) => void;
305
- /**
306
- * ----- 播放器状态 -------
307
- * 窗口宽度 width?: number;
308
- * 窗口高度 height?: number;
309
- * 窗口是否全屏 isCurrentFullscreen?: boolean;
310
- * 播放器是否播放中 playing?: boolean;
311
- * 音量大小 0-1 volume?: number;
312
- * 是否静音 muted?: boolean;
313
- * 浏览器选择角度 0 | 90 | 180 | 270 orientationAngle?: number;
314
- * 所有属性值来源 constant.ts 文中 THEME_PROPS
315
- */
316
- props?: Record<(typeof THEME_PROPS)[number], number | string | Record<string, unknown>>;
317
- [key: string]: any;
318
- }
319
- /**
320
- * 不允许控件自定义的参数
321
- * @typeParam T - 控件配置项
390
+ * 控件类型(iconId)不可以重复
322
391
  */
323
- type OmitControlOptions<T extends ControlOptions> = Omit<T, 'rootContainer' | 'getPopupContainer' | 'classNameSuffix' | 'type' | 'tagName' | 'controlType'>;
392
+ type ControlType =
393
+ /** 播放/暂停 */
394
+ 'play'
395
+ /** 音量, 兼容 sound */
396
+ | 'volume'
397
+ /** 截图 */
398
+ | 'capturePicture'
399
+ /** ptz 云台, 兼容 pantile */
400
+ | 'ptz'
401
+ /** 录制, 兼容 recordvideo */
402
+ | 'record'
403
+ /** 对讲 */
404
+ | 'talk'
405
+ /** 语音广播 */
406
+ | 'broadcast'
407
+ /** AI对话 */
408
+ | 'aiChat'
409
+ /** 直播按钮 */
410
+ | 'live'
411
+ /** 回放下拉 */
412
+ | 'recDropdown'
413
+ /** 录像列表 */
414
+ | 'recList'
415
+ /** 告警消息 */
416
+ | 'alarmMessage'
417
+ /** 电子放大 */
418
+ | 'zoom'
419
+ /** 清晰度, 兼容 hd */
420
+ | 'definition'
421
+ /** web 全屏, 兼容 webExtend */
422
+ | 'fullscreen'
423
+ /** 全局全屏, 兼容 extend */
424
+ | 'globalFullscreen'
425
+ /** 倍速 */
426
+ | 'speed'
427
+ /** 日期选择 */
428
+ | 'date'
429
+ /** 时间选择 */
430
+ | 'time'
431
+ /** 时间轴 */
432
+ | 'timeLine'
433
+ /** 回放片段进度条(移动端,播放区间约束下渲染) */
434
+ | 'segmentProgress';
435
+ type MergeControlType =
436
+ /** 设备序列号 */
437
+ 'deviceID'
438
+ /** 设备名称 */
439
+ | 'deviceName'
440
+ /** 云存储 */
441
+ | 'cloudRec'
442
+ /** 云录制 */
443
+ | 'cloudRecord'
444
+ /** 本地存储 sdk */
445
+ | 'rec';
324
446
  /**
325
- * 控件基类
326
- * @category Control
327
- * @example
328
- * ```ts
329
- * // 创建控件
330
- * class MyControl extends Control {}
331
- *
332
- * // 使用控件
333
- * const myControl = new MyControl({})
334
- * ```
447
+ * 控件
335
448
  */
336
- declare class Control extends EventEmitter {
337
- /**
338
- * 控件内容
339
- */
340
- $container: HTMLDivElement | HTMLSpanElement;
341
- /**
342
- * 控件挂载的节点
343
- */
344
- $popupContainer: HTMLElement;
345
- /** 具体语言对应的值 */
346
- locale: Record<string | number, string> | null;
347
- protected __options: ControlOptions;
348
- protected _disabled: boolean;
349
- protected _active: boolean;
350
- private readonly _camelCaseName;
351
- /** click 监听引用,销毁时需显式移除 */
352
- private _onClickHandler;
353
- constructor(options: Partial<ControlOptions>);
354
- /**
355
- * 是否激活
356
- */
357
- get active(): boolean;
358
- set active(active: boolean);
359
- /**
360
- * 是否禁用
361
- */
362
- get disabled(): boolean;
363
- set disabled(disabled: boolean);
364
- /**
365
- * 重置整个控件
366
- */
367
- reset(hide?: boolean): void;
368
- /**
369
- * 重置控件挂载节点
370
- * @param popupContainer 重新挂载的节点
371
- * @param append 添加的方式, 默认 append
372
- * @param element 当 append = before 时 需要 element, 插入 element 前
373
- *
374
- * | prepend | append |
375
- * |:-------------:|:---------------:|
376
- * | 插入第一个位置 | 追加在末尾 |
377
- */
378
- resetPopupContainer(popupContainer: Element, append?: 'prepend' | 'append' | 'before', element?: Element): void;
449
+ interface ControlItem {
379
450
  /**
380
- * 隐藏整个控件
451
+ * 控件id
381
452
  */
382
- hide(): void;
453
+ iconId: ControlType | MergeControlType;
383
454
  /**
384
- * 销毁控件
455
+ * 控件位置
456
+ * | left | right |
457
+ * |:-----------:|:------------:|
458
+ * | 控件栏的左部 | 控件栏的右部 |
385
459
  */
386
- destroy(): void;
387
- protected _updateDisabledState(disabled: boolean): void;
388
- protected _updateActiveState(active: boolean): void;
460
+ part: 'left' | 'right';
461
+ /** 是否激活 0 否 1 是 默认是 0 */
389
462
  /**
390
- * 当点击 Control 时 触发子类的 _onControlClick
463
+ * 是否渲染 0 否 1 是 默认是 undefined, 0 不渲染, 非 0 渲染
391
464
  */
392
- protected _onClick(): void;
393
- protected _onDBlClick(e: Event): void;
465
+ isrender?: 0 | 1;
466
+ }
467
+ interface IThemeDataItem {
394
468
  /**
395
- * 点击 Control 控件触发
396
- * @param {Event} e
397
- * @returns {void}
469
+ * 控件按钮或文本颜色
470
+ * @since 0.0.1
471
+ * @deprecated 从 0.0.1 开始不再推荐, 字体和图标颜色, 推荐 css 变量 --ezplayer-default-color
398
472
  */
399
- protected _onControlClick(e: Event): void;
400
- }
401
-
402
- /**
403
- * 加载动画控件配置项
404
- */
405
- interface LoadingOptions extends Omit<ControlOptions, 'tagName' | 'controlType'> {
473
+ color?: string;
406
474
  /**
407
- * 自定义加载动画的 HTML 结构, 当 theme.loading = true 时展示
408
- * @returns HTML 字符串
475
+ * 控件栏(header/footer)背景颜色
476
+ * @since 0.0.1
477
+ * @deprecated 由于header/footer高度变化, 从 0.0.1 开始不再推荐, 可以通过 className 覆盖样式
409
478
  */
410
- render?: () => string;
411
- }
412
- /**
413
- * 加载动画控件
414
- * @category Control
415
- */
416
- declare class Loading extends Control {
417
- private readonly _options;
418
- constructor(options?: Partial<LoadingOptions>);
419
- private _html;
479
+ backgroundColor?: string;
420
480
  /**
421
- * 动画展示
422
- * @param html 自定义动画内容, 如果不存在则使用默认动画
481
+ * 控件激活后的颜色
482
+ * @since 0.0.1
483
+ * @deprecated 从 0.0.1 开始不再推荐,可以通过 className 覆盖样式,推荐 css 变量 --ezplayer-active-color
423
484
  */
424
- show(html?: string): void;
485
+ activeColor?: string;
425
486
  /**
426
- * 隐藏动画
487
+ * 控件列表
488
+ * @remarks
489
+ * 控件列表, 按照 iconId 顺序渲染, 需要注意的是, 控件类型(iconId)不可以重复;
490
+ * 注意 ⚠️: deviceID, deviceName, rec, cloudRec, cloudRecord 这五个控件特殊处理, deviceID 和 deviceName 是一组, rec、 cloudRec 和 cloudRecord 是一组
491
+ *
492
+ * @since 0.0.1
427
493
  */
428
- hide(): void;
494
+ btnList?: ControlItem[];
429
495
  }
430
-
431
496
  /**
432
- * 封面控件配置项
497
+ * 主题数据, 优先级最高, 支持用户自定义
433
498
  */
434
- interface PosterOptions extends Omit<ControlOptions, 'tagName'> {
435
- /** 默认封面 */
499
+ interface IThemeData {
500
+ /** 控件展示时长,默认自动聚焦持续 3s , 单位秒 0 表示一直展示 */
501
+ autoFocus?: number;
502
+ /** 优先级高于初始化 posterOptions.poster */
436
503
  poster?: string;
437
- /** 封面加载失败回调 */
438
- onLoadImgError?: (src: string) => void;
439
- }
440
- /**
441
- * 封面控件
442
- * @category Control
443
- */
444
- declare class Poster extends Control {
445
- private readonly _options;
446
- constructor(options?: Partial<PosterOptions>);
447
- /**
448
- * 封面图片加载失败
449
- * @param error
450
- */
451
- private _imgLoadErrorEvent;
452
- /**
453
- * 设置封面 这里不对 poster 进行缓存,如果有值优先使用,如果没有值优先使用 初始化传入的值
454
- * @param {string} poster 封面地址或 base64 数据
455
- */
456
- setPoster(poster?: string): void;
457
- /**
458
- * 展示封面 这里不对 poster 进行缓存, 如果有值优先使用, 如果没有值优先使用 初始化传入的值
459
- */
460
- show(): void;
504
+ themeType?: 'webLive' | 'webRec' | 'mobileLive' | 'mobileRec';
461
505
  /**
462
- * 隐藏封面
506
+ * 头部工具栏
463
507
  */
464
- hide(): void;
508
+ header?: Partial<IThemeDataItem> | null;
465
509
  /**
466
- * 销毁
510
+ * 底部工具栏
467
511
  */
468
- destroy(): void;
512
+ footer?: Partial<IThemeDataItem> | null;
469
513
  }
470
514
 
471
515
  /**
@@ -519,75 +563,65 @@ declare class Message extends Control {
519
563
  * error 错误消息, 内容默认字体红色
520
564
  * @param {string} msg 消息内容
521
565
  * @param {number=} duration 认自动关闭延时,单位秒, 默认 0 不关闭, 需手动 调用 hide()
522
- */
523
- error(msg: string, duration?: number): void;
524
- private _toast;
525
- /**
526
- * 展示消息,如果同时调用多次只展示最后一次的消息
527
- * @param {string} msg 消息内容, 支持 html dom 字符串
528
- * @param {number} duration 认自动关闭延时,单位秒, 默认 0 不关闭 需手动 调用 hide()
529
- * @param {MessageType} type 消息类型
530
- */
531
- private _show;
532
- /**
533
- * 销毁
534
- */
535
- destroy(): void;
536
- /**
537
- * 隐藏消息, 并清空消息内容
538
- */
539
- hide(): void;
540
- private _getIcon;
541
- }
542
-
543
- /**
544
- * Header/Footer 的父组件
545
- */
546
- interface ComponentOptions {
547
- /** 挂载节点 player id, 默认挂载 body 上 */
548
- getPopupContainer?: () => HTMLElement;
549
- /** 自定义类名 */
550
- className?: string;
551
- /** 文字/图标默认颜色(兼容老版本和平台配置) */
552
- color?: string;
553
- /** 文字/图标激活态颜色(兼容老版本和平台配置) */
554
- activeColor?: string;
555
- /** 背景色,支持 Hex / rgb / rgba,会自动转换为渐变背景(兼容老版本和平台配置) */
556
- backgroundColor?: string;
557
- /** 组件类型, header 或 footer */
558
- cType: 'header' | 'footer';
559
- }
560
- /**
561
- * Header
562
- */
563
- declare class Component {
564
- $container: HTMLDivElement;
565
- $popupContainer: HTMLElement;
566
- private readonly _options;
567
- private readonly _defaultClass;
568
- $left: HTMLDivElement;
569
- $right: HTMLDivElement;
570
- constructor(options?: Partial<ComponentOptions>);
566
+ */
567
+ error(msg: string, duration?: number): void;
568
+ private _toast;
571
569
  /**
572
- * 销毁 header
570
+ * 展示消息,如果同时调用多次只展示最后一次的消息
571
+ * @param {string} msg 消息内容, 支持 html dom 字符串
572
+ * @param {number} duration 认自动关闭延时,单位秒, 默认 0 不关闭 需手动 调用 hide()
573
+ * @param {MessageType} type 消息类型
574
+ */
575
+ private _show;
576
+ /**
577
+ * 销毁
573
578
  */
574
579
  destroy(): void;
580
+ /**
581
+ * 隐藏消息, 并清空消息内容
582
+ */
583
+ hide(): void;
584
+ private _getIcon;
575
585
  }
576
586
 
577
587
  /**
578
- * Footer options
588
+ * 封面控件配置项
579
589
  */
580
- type FooterOptions = ComponentOptions;
581
- declare class Footer extends Component {
582
- constructor(options?: Partial<FooterOptions>);
590
+ interface PosterOptions extends Omit<ControlOptions, 'tagName'> {
591
+ /** 默认封面 */
592
+ poster?: string;
593
+ /** 封面加载失败回调 */
594
+ onLoadImgError?: (src: string) => void;
583
595
  }
584
-
585
596
  /**
586
- * Header options
597
+ * 封面控件
598
+ * @category Control
587
599
  */
588
- type HeaderOptions = ComponentOptions;
589
- declare class Header extends Component {
590
- constructor(options?: Partial<HeaderOptions>);
600
+ declare class Poster extends Control {
601
+ private readonly _options;
602
+ constructor(options?: Partial<PosterOptions>);
603
+ /**
604
+ * 封面图片加载失败
605
+ * @param error
606
+ */
607
+ private _imgLoadErrorEvent;
608
+ /**
609
+ * 设置封面 这里不对 poster 进行缓存,如果有值优先使用,如果没有值优先使用 初始化传入的值
610
+ * @param {string} poster 封面地址或 base64 数据
611
+ */
612
+ setPoster(poster?: string): void;
613
+ /**
614
+ * 展示封面 这里不对 poster 进行缓存, 如果有值优先使用, 如果没有值优先使用 初始化传入的值
615
+ */
616
+ show(): void;
617
+ /**
618
+ * 隐藏封面
619
+ */
620
+ hide(): void;
621
+ /**
622
+ * 销毁
623
+ */
624
+ destroy(): void;
591
625
  }
592
626
 
593
627
  /**
@@ -987,132 +1021,6 @@ declare class Fullscreen extends Control {
987
1021
  private _event;
988
1022
  }
989
1023
 
990
- /**
991
- * 控件类型(iconId)不可以重复
992
- */
993
- type ControlType =
994
- /** 播放/暂停 */
995
- 'play'
996
- /** 音量, 兼容 sound */
997
- | 'volume'
998
- /** 截图 */
999
- | 'capturePicture'
1000
- /** ptz 云台, 兼容 pantile */
1001
- | 'ptz'
1002
- /** 录制, 兼容 recordvideo */
1003
- | 'record'
1004
- /** 对讲 */
1005
- | 'talk'
1006
- /** 语音广播 */
1007
- | 'broadcast'
1008
- /** AI对话 */
1009
- | 'aiChat'
1010
- /** 直播按钮 */
1011
- | 'live'
1012
- /** 回放下拉 */
1013
- | 'recDropdown'
1014
- /** 录像列表 */
1015
- | 'recList'
1016
- /** 告警消息 */
1017
- | 'alarmMessage'
1018
- /** 电子放大 */
1019
- | 'zoom'
1020
- /** 清晰度, 兼容 hd */
1021
- | 'definition'
1022
- /** web 全屏, 兼容 webExtend */
1023
- | 'fullscreen'
1024
- /** 全局全屏, 兼容 extend */
1025
- | 'globalFullscreen'
1026
- /** 倍速 */
1027
- | 'speed'
1028
- /** 日期选择 */
1029
- | 'date'
1030
- /** 时间选择 */
1031
- | 'time'
1032
- /** 时间轴 */
1033
- | 'timeLine'
1034
- /** 回放片段进度条(移动端,播放区间约束下渲染) */
1035
- | 'segmentProgress';
1036
- type MergeControlType =
1037
- /** 设备序列号 */
1038
- 'deviceID'
1039
- /** 设备名称 */
1040
- | 'deviceName'
1041
- /** 云存储 */
1042
- | 'cloudRec'
1043
- /** 云录制 */
1044
- | 'cloudRecord'
1045
- /** 本地存储 sdk */
1046
- | 'rec';
1047
- /**
1048
- * 控件
1049
- */
1050
- interface ControlItem {
1051
- /**
1052
- * 控件id
1053
- */
1054
- iconId: ControlType | MergeControlType;
1055
- /**
1056
- * 控件位置
1057
- * | left | right |
1058
- * |:-----------:|:------------:|
1059
- * | 控件栏的左部 | 控件栏的右部 |
1060
- */
1061
- part: 'left' | 'right';
1062
- /** 是否激活 0 否 1 是 默认是 0 */
1063
- /**
1064
- * 是否渲染 0 否 1 是 默认是 undefined, 0 不渲染, 非 0 渲染
1065
- */
1066
- isrender?: 0 | 1;
1067
- }
1068
- interface IThemeDataItem {
1069
- /**
1070
- * 控件按钮或文本颜色
1071
- * @since 0.0.1
1072
- * @deprecated 从 0.0.1 开始不再推荐, 字体和图标颜色, 推荐 css 变量 --ezplayer-default-color
1073
- */
1074
- color?: string;
1075
- /**
1076
- * 控件栏(header/footer)背景颜色
1077
- * @since 0.0.1
1078
- * @deprecated 由于header/footer高度变化, 从 0.0.1 开始不再推荐, 可以通过 className 覆盖样式
1079
- */
1080
- backgroundColor?: string;
1081
- /**
1082
- * 控件激活后的颜色
1083
- * @since 0.0.1
1084
- * @deprecated 从 0.0.1 开始不再推荐,可以通过 className 覆盖样式,推荐 css 变量 --ezplayer-active-color
1085
- */
1086
- activeColor?: string;
1087
- /**
1088
- * 控件列表
1089
- * @remarks
1090
- * 控件列表, 按照 iconId 顺序渲染, 需要注意的是, 控件类型(iconId)不可以重复;
1091
- * 注意 ⚠️: deviceID, deviceName, rec, cloudRec, cloudRecord 这五个控件特殊处理, deviceID 和 deviceName 是一组, rec、 cloudRec 和 cloudRecord 是一组
1092
- *
1093
- * @since 0.0.1
1094
- */
1095
- btnList?: ControlItem[];
1096
- }
1097
- /**
1098
- * 主题数据, 优先级最高, 支持用户自定义
1099
- */
1100
- interface IThemeData {
1101
- /** 控件展示时长,默认自动聚焦持续 3s , 单位秒 0 表示一直展示 */
1102
- autoFocus?: number;
1103
- /** 优先级高于初始化 posterOptions.poster */
1104
- poster?: string;
1105
- themeType?: 'webLive' | 'webRec' | 'mobileLive' | 'mobileRec';
1106
- /**
1107
- * 头部工具栏
1108
- */
1109
- header?: Partial<IThemeDataItem> | null;
1110
- /**
1111
- * 底部工具栏
1112
- */
1113
- footer?: Partial<IThemeDataItem> | null;
1114
- }
1115
-
1116
1024
  /**
1117
1025
  * 全屏控件配置
1118
1026
  */
@@ -1223,6 +1131,45 @@ type DefinitionOptions = Omit<SelectOptions, 'list' | 'fieldNames'> & {
1223
1131
  interface PtzOptions extends Omit<ControlOptions, 'tagName'>, BasePtzOptions {
1224
1132
  }
1225
1133
 
1134
+ /**
1135
+ * 回放控件配置项
1136
+ */
1137
+ interface RecOptions extends Omit<ControlOptions, 'tagName'> {
1138
+ /** 点击控件时的回调 */
1139
+ onClick?: (e: Event) => void;
1140
+ /** 回放类型切换时的回调 */
1141
+ onChange?: (type: ThemeRecType) => void;
1142
+ /** 默认回放类型, 默认 'rec' */
1143
+ recType?: ThemeRecType;
1144
+ }
1145
+ /**
1146
+ * 回放类型切换(本地回放(sdk 卡), 云存储回放, 云录制回放)控件
1147
+ * @category Control
1148
+ */
1149
+ declare class Rec extends Control {
1150
+ /** 回放类型切换组,本身就是三种回放之间的切换入口,直播下无意义 */
1151
+ static supportedPlayTypes: ThemePlayType[];
1152
+ private readonly _options;
1153
+ private _delegation;
1154
+ private recType;
1155
+ constructor(options: RecOptions);
1156
+ /**
1157
+ * 销毁
1158
+ */
1159
+ destroy(): void;
1160
+ /**
1161
+ * 添加回放类型图标
1162
+ * @param {string} id 回放类型 'rec' | 'cloudRec' | 'cloudRecord'
1163
+ */
1164
+ addRecType(id: string): void;
1165
+ private _activeIcon;
1166
+ private _onClickIcon;
1167
+ /**
1168
+ * 点击 Control 会触发
1169
+ */
1170
+ protected _onControlClick(e: Event): void;
1171
+ }
1172
+
1226
1173
  /**
1227
1174
  * 录像列表按钮控件配置项
1228
1175
  */
@@ -1287,7 +1234,57 @@ declare class Pause extends Control {
1287
1234
  * 销毁
1288
1235
  */
1289
1236
  destroy(): void;
1290
- protected _onControlClick(e: Event): void;
1237
+ protected _onControlClick(e: Event): void;
1238
+ }
1239
+
1240
+ /**
1241
+ * Header/Footer 的父组件
1242
+ */
1243
+ interface ComponentOptions {
1244
+ /** 挂载节点 player id, 默认挂载 body 上 */
1245
+ getPopupContainer?: () => HTMLElement;
1246
+ /** 自定义类名 */
1247
+ className?: string;
1248
+ /** 文字/图标默认颜色(兼容老版本和平台配置) */
1249
+ color?: string;
1250
+ /** 文字/图标激活态颜色(兼容老版本和平台配置) */
1251
+ activeColor?: string;
1252
+ /** 背景色,支持 Hex / rgb / rgba,会自动转换为渐变背景(兼容老版本和平台配置) */
1253
+ backgroundColor?: string;
1254
+ /** 组件类型, header 或 footer */
1255
+ cType: 'header' | 'footer';
1256
+ }
1257
+ /**
1258
+ * Header
1259
+ */
1260
+ declare class Component {
1261
+ $container: HTMLDivElement;
1262
+ $popupContainer: HTMLElement;
1263
+ private readonly _options;
1264
+ private readonly _defaultClass;
1265
+ $left: HTMLDivElement;
1266
+ $right: HTMLDivElement;
1267
+ constructor(options?: Partial<ComponentOptions>);
1268
+ /**
1269
+ * 销毁 header
1270
+ */
1271
+ destroy(): void;
1272
+ }
1273
+
1274
+ /**
1275
+ * Footer options
1276
+ */
1277
+ type FooterOptions = ComponentOptions;
1278
+ declare class Footer extends Component {
1279
+ constructor(options?: Partial<FooterOptions>);
1280
+ }
1281
+
1282
+ /**
1283
+ * Header options
1284
+ */
1285
+ type HeaderOptions = ComponentOptions;
1286
+ declare class Header extends Component {
1287
+ constructor(options?: Partial<HeaderOptions>);
1291
1288
  }
1292
1289
 
1293
1290
  /**
@@ -1502,7 +1499,7 @@ declare class Theme extends EventEmitter {
1502
1499
  readonly volumechange: "volumechange";
1503
1500
  readonly zoomChange: "zoomChange";
1504
1501
  readonly zoomingChange: "zoomingChange";
1505
- readonly zoomTranslateChange: "zoomTranslateChange";
1502
+ readonly zoomTranslateChange: "zoomTranslateChange"; /** resizeObserver 监听销毁 */
1506
1503
  readonly audioInfo: "audioInfo";
1507
1504
  readonly videoInfo: "videoInfo";
1508
1505
  readonly firstFrameDisplay: "firstFrameDisplay";
@@ -1515,7 +1512,7 @@ declare class Theme extends EventEmitter {
1515
1512
  readonly changeTheme: "changeTheme";
1516
1513
  readonly recTypeChange: "recTypeChange";
1517
1514
  readonly definitionChange: "definitionChange";
1518
- readonly speedChange: "speedChange";
1515
+ readonly speedChange: "speedChange"; /** 倍速 @private */
1519
1516
  readonly recordingChange: "recordingChange";
1520
1517
  readonly talkingChange: "talkingChange";
1521
1518
  readonly talkVolumeChange: "talkVolumeChange";
@@ -1525,11 +1522,7 @@ declare class Theme extends EventEmitter {
1525
1522
  readonly recDropdownChange: "recDropdownChange";
1526
1523
  readonly recListChange: "recListChange";
1527
1524
  readonly alarmMessageChange: "alarmMessageChange";
1528
- readonly setLoggerOptions: "setLoggerOptions"; /**
1529
- * 更多控件(footer more)
1530
- * @since 0.0.1
1531
- * @private
1532
- */
1525
+ readonly setLoggerOptions: "setLoggerOptions";
1533
1526
  readonly records: "records";
1534
1527
  readonly ptzSpeedChange: "ptzSpeedChange";
1535
1528
  readonly setVideoLevelList: "setVideoLevelList";
@@ -1594,21 +1587,50 @@ declare class Theme extends EventEmitter {
1594
1587
  readonly dateMonthChange: "Control.dateMonthChange";
1595
1588
  readonly datePanelMonthChange: "Control.datePanelMonthChange";
1596
1589
  readonly datePanelYearChange: "Control.datePanelYearChange";
1597
- readonly dateDestroy: "Control.datePanelDestroy";
1590
+ readonly dateDestroy: "Control.dateDestroy";
1598
1591
  readonly timePanelOpenChange: "Control.timePanelOpenChange";
1599
1592
  readonly timeChange: "Control.timeChange";
1600
1593
  readonly timeLineChange: "Control.timeLineChange";
1601
1594
  readonly timeLinePanelOpenChange: "Control.timeLinePanelOpenChange";
1602
1595
  readonly timeLineDestroy: "Control.timeLineDestroy";
1596
+ readonly unsupportedPlayType: "Control.unsupportedPlayType";
1603
1597
  readonly beforeMountControls: "Control.beforeMountControls";
1604
1598
  readonly mountedControls: "Control.mountedControls";
1605
- readonly beforeUnmountControls: "Control.beforeUnmountControls";
1599
+ readonly beforeUnmountControls: "Control.beforeUnmountControls"; /**
1600
+ * 容器的宽(单位 px)
1601
+ * ```ts
1602
+ * theme.width // number
1603
+ * ```
1604
+ */
1606
1605
  readonly unmountedControls: "Control.unmountedControls";
1607
1606
  readonly posterDestroy: "Control.posterDestroy";
1608
1607
  readonly loadingDestroy: "Control.loadingDestroy";
1609
1608
  readonly messageDestroy: "Control.messageDestroy";
1610
1609
  readonly contentDestroy: "Control.contentDestroy";
1611
1610
  readonly contentRerender: "Control.contentRerender";
1611
+ readonly playControlInit: "Control.playControlInit";
1612
+ readonly volumeControlInit: "Control.volumeControlInit";
1613
+ readonly deviceControlInit: "Control.deviceControlInit";
1614
+ readonly capturePictureControlInit: "Control.capturePictureControlInit";
1615
+ readonly ptzControlInit: "Control.ptzControlInit";
1616
+ readonly recordControlInit: "Control.recordControlInit";
1617
+ readonly talkControlInit: "Control.talkControlInit";
1618
+ readonly broadcastControlInit: "Control.broadcastControlInit";
1619
+ readonly aiChatControlInit: "Control.aiChatControlInit";
1620
+ readonly liveControlInit: "Control.liveControlInit";
1621
+ readonly recDropdownControlInit: "Control.recDropdownControlInit";
1622
+ readonly recListControlInit: "Control.recListControlInit";
1623
+ readonly alarmMessageControlInit: "Control.alarmMessageControlInit";
1624
+ readonly zoomControlInit: "Control.zoomControlInit";
1625
+ readonly definitionControlInit: "Control.definitionControlInit";
1626
+ readonly fullscreenControlInit: "Control.fullscreenControlInit";
1627
+ readonly globalFullscreenControlInit: "Control.globalFullscreenControlInit";
1628
+ readonly recControlInit: "Control.recControlInit";
1629
+ readonly speedControlInit: "Control.speedControlInit";
1630
+ readonly dateControlInit: "Control.dateControlInit";
1631
+ readonly timeControlInit: "Control.timeControlInit";
1632
+ readonly timeLineControlInit: "Control.timeLineControlInit";
1633
+ readonly segmentProgressControlInit: "Control.segmentProgressControlInit";
1612
1634
  };
1613
1635
  readonly theme: {
1614
1636
  readonly beforeDestroy: "Theme.beforeDestroy";
@@ -1774,6 +1796,7 @@ declare class Theme extends EventEmitter {
1774
1796
  MAX_SPEED_LIMIT: string;
1775
1797
  MIN_SPEED_LIMIT: string;
1776
1798
  SPEED_SWITCH_ERRROR: string;
1799
+ /** 播放器配置项 */
1777
1800
  SPEED_SWITCH_NOT_SUPPORT: string;
1778
1801
  SEEK_CANNOT_CROSS_DAYS: string;
1779
1802
  SEEK_TIMEFORMAT_ERROR: string;
@@ -1786,14 +1809,14 @@ declare class Theme extends EventEmitter {
1786
1809
  NO_CLOUD_RECORD: string;
1787
1810
  CHANGE_VIDEO_LEVEL: string;
1788
1811
  CHANGE_VIDEO_LEVEL_FAIL: string;
1789
- GET_VIDEO_LEVEL_LIST: string; /** 消息提示控件 @since 0.0.1 @private */
1812
+ GET_VIDEO_LEVEL_LIST: string;
1790
1813
  PLEASE_INPUT_RIGHT_VIDEO_LEVEL: string;
1791
1814
  VIDEO_LEVEL_NOT_SUPPORT: string;
1792
1815
  VIDEO_LEVEL_AUTO: string;
1793
1816
  VIDEO_LEVEL_FLUENT: string;
1794
1817
  VIDEO_LEVEL_STANDARD: string;
1795
1818
  VIDEO_LEVEL_HEIGH: string;
1796
- VIDEO_LEVEL_SUPER: string;
1819
+ VIDEO_LEVEL_SUPER: string; /** 封面控件 @since 0.0.1 @private */
1797
1820
  VIDEO_LEVEL_EXTREME: string;
1798
1821
  VIDEO_LEVEL_3K: string;
1799
1822
  VIDEO_LEVEL_4k: string;
@@ -1810,28 +1833,32 @@ declare class Theme extends EventEmitter {
1810
1833
  BTN_LIVE: string;
1811
1834
  BTN_REC_DROPDOWN: string;
1812
1835
  BTN_ALARM_MESSAGE: string;
1813
- REC_DROPDOWN_CLOUD_REC: string;
1836
+ REC_DROPDOWN_CLOUD_REC: string; /**
1837
+ * 更多控件(footer more)
1838
+ * @since 0.0.1
1839
+ * @private
1840
+ */
1814
1841
  REC_DROPDOWN_CLOUD_RECORD: string;
1815
1842
  REC_DROPDOWN_LOCAL_REC: string;
1816
1843
  BTN_ZOOM: string;
1817
1844
  BTN_3D_ZOOM: string;
1818
1845
  BTN_PTZ: string;
1819
- BTN_GLOBAL_FULLSCREEN: string; /**
1820
- * 移动端扩展容器, 扩展的控件渲染在指定容器以外, 仅只用端适用, 为了可以放置大的控件和方便开发接入
1821
- * @private
1822
- */
1846
+ BTN_GLOBAL_FULLSCREEN: string;
1823
1847
  BTN_EXIT_GLOBAL_FULLSCREEN: string;
1824
1848
  BTN_FULLSCREEN: string;
1825
1849
  BTN_EXIR_FULLSCREEN: string;
1826
1850
  BTN_HD: string;
1827
1851
  BTN_SPEED: string;
1828
- BTN_CLOUDREC: string;
1852
+ BTN_CLOUDREC: string; /**
1853
+ * 移动端扩展容器, 扩展的控件渲染在指定容器以外, 仅只用端适用, 为了可以放置大的控件和方便开发接入
1854
+ * @private
1855
+ */
1829
1856
  BTN_CLOUDRECORD: string;
1830
1857
  BTN_REC: string;
1831
1858
  BTN_CALENDAR: string;
1832
1859
  BTN_TIME: string;
1833
1860
  BTN_MORE: string;
1834
- DEVICE_NAME: string;
1861
+ DEVICE_NAME: string; /** @since 0.0.1 @private */
1835
1862
  DEVICE_ID: string;
1836
1863
  CAPTURE_SUCCESS: string;
1837
1864
  CAPTURE_FAILED: string;
@@ -1843,17 +1870,17 @@ declare class Theme extends EventEmitter {
1843
1870
  RECORDS: string;
1844
1871
  OPEN_SOUND: string;
1845
1872
  CLOSE_SOUND: string;
1846
- SOUND_OPENED: string; /** 容器的宽 */
1873
+ SOUND_OPENED: string;
1874
+ /** resizeObserver 监听销毁 */
1847
1875
  ZOOM: string;
1848
1876
  START_ZOOM: string;
1849
- /** 容器的高 */
1850
1877
  CLOSE_ZOOM: string;
1851
1878
  ZOOM_ADD: string;
1852
1879
  ZOOM_SUB: string;
1853
1880
  ZOOM_ADD_MAX: string;
1854
1881
  ZOOM_SUB_MIN: string;
1855
1882
  ZOOM_LIMIT_MAX: string;
1856
- ZOOM_LIMIT_MIN: string;
1883
+ ZOOM_LIMIT_MIN: string; /** 当前容器的全屏状态 true: 全屏, false: 非全屏 */
1857
1884
  ZOOM_NOT_ENABLED: string;
1858
1885
  '3D_ZOOM': string;
1859
1886
  '3D_ZOOM_DISABLE': string;
@@ -1871,25 +1898,18 @@ declare class Theme extends EventEmitter {
1871
1898
  WEB_FULLSCREEN: string;
1872
1899
  WEB_FULLSCREEN_EXIT: string;
1873
1900
  DESTROY: string;
1874
- /** 回放片段列表 */
1875
1901
  GET_CAPACITY: string;
1876
- GET_PTZ_STATUS: string;
1902
+ GET_PTZ_STATUS: string; /** 录制中 @private */
1877
1903
  GET_PTZ_STATUS_FAILED: string;
1878
- MOBILE_HIDE_PTZ: string;
1904
+ MOBILE_HIDE_PTZ: string; /** 倍速 @private */
1879
1905
  OPTION_PTZ_FAILED: string;
1880
1906
  MOBILE_PTZ_TIPS: string;
1881
- PTZ_FAST: string; /** 窗口尺寸变化时,设置窗口超出隐藏,防止出现滚动条 */
1907
+ PTZ_FAST: string;
1882
1908
  PTZ_MID: string;
1883
1909
  PTZ_SLOW: string;
1884
1910
  PTZ_SPEED: string;
1885
1911
  DEVICE_ZOOM: string;
1886
- /**
1887
- * 录像回放的月份列表 @private
1888
- */
1889
1912
  DEVICE_FOCUS: string;
1890
- /**
1891
- * 录像回放的月份列表 @private
1892
- */
1893
1913
  NOT_SUPPORT_DEVICE_ZOOM: string;
1894
1914
  NOT_SUPPORT_FOCUS: string;
1895
1915
  MIRROR: string;
@@ -1910,6 +1930,11 @@ declare class Theme extends EventEmitter {
1910
1930
  ok: string;
1911
1931
  close: string;
1912
1932
  BTN_REC_LIST_TITLE: string;
1933
+ UNKOWN_ISSUE: string; /**
1934
+ * 首帧同步 Live/RecDropdown 激活态的监听器引用。
1935
+ * 每次 `_renderTheme` 重新绑定前需先移除旧引用,避免 changeTheme 累积监听。
1936
+ * @private
1937
+ */
1913
1938
  };
1914
1939
  en: {
1915
1940
  391001: string;
@@ -1958,7 +1983,7 @@ declare class Theme extends EventEmitter {
1958
1983
  395562: string;
1959
1984
  395563: string;
1960
1985
  395564: string;
1961
- 395566: string;
1986
+ 395566: string; /** 所有私有流的模板 @since 0.0.1 */
1962
1987
  395567: string;
1963
1988
  395568: string;
1964
1989
  395569: string;
@@ -1990,9 +2015,10 @@ declare class Theme extends EventEmitter {
1990
2015
  396506: string;
1991
2016
  396508: string;
1992
2017
  396509: string;
1993
- 396510: string; /** 静音 */
2018
+ 396510: string;
1994
2019
  396511: string;
1995
2020
  396512: string;
2021
+ /** 静音 */
1996
2022
  396513: string;
1997
2023
  396514: string;
1998
2024
  396515: string;
@@ -2000,17 +2026,8 @@ declare class Theme extends EventEmitter {
2000
2026
  396517: string;
2001
2027
  396518: string;
2002
2028
  396519: string;
2003
- /**
2004
- * 录像回放的月份列表 @private
2005
- */
2006
2029
  396520: string;
2007
- /**
2008
- * 录像回放的月份列表 @private
2009
- */
2010
2030
  396700: string;
2011
- /**
2012
- * 录像回放的月份列表 @private
2013
- */
2014
2031
  396701: string;
2015
2032
  397001: string;
2016
2033
  397002: string;
@@ -2091,6 +2108,9 @@ declare class Theme extends EventEmitter {
2091
2108
  VIDEO_LEVEL_NOT_SUPPORT: string;
2092
2109
  VIDEO_LEVEL_AUTO: string;
2093
2110
  VIDEO_LEVEL_FLUENT: string;
2111
+ /**
2112
+ * url 信息 播放地址信息
2113
+ */
2094
2114
  VIDEO_LEVEL_STANDARD: string;
2095
2115
  VIDEO_LEVEL_HEIGH: string;
2096
2116
  VIDEO_LEVEL_SUPER: string;
@@ -2163,7 +2183,13 @@ declare class Theme extends EventEmitter {
2163
2183
  '3D_ZOOM_NOT_ACTIVED': string;
2164
2184
  '3D_ZOOM_CLOSED': string;
2165
2185
  CHANGE_ZOOM_TYPE: string;
2166
- FULLSCREEN: string;
2186
+ FULLSCREEN: string; /**
2187
+ * 加载状态
2188
+ * ```ts
2189
+ * // 事件监听
2190
+ * theme.on(Theme.EVENTS.loading, (loading: boolean) => {})
2191
+ * ```
2192
+ */
2167
2193
  FULLSCREEN_EXIT: string;
2168
2194
  GET_WEB_FULLSCREEN_STATUS: string;
2169
2195
  WEB_FULLSCREEN: string;
@@ -2175,9 +2201,7 @@ declare class Theme extends EventEmitter {
2175
2201
  MOBILE_HIDE_PTZ: string;
2176
2202
  OPTION_PTZ_FAILED: string;
2177
2203
  MOBILE_PTZ_TIPS: string;
2178
- PTZ_FAST: string; /**
2179
- * 是否在缩放中
2180
- */
2204
+ PTZ_FAST: string;
2181
2205
  PTZ_MID: string;
2182
2206
  PTZ_SLOW: string;
2183
2207
  PTZ_SPEED: string;
@@ -2203,6 +2227,7 @@ declare class Theme extends EventEmitter {
2203
2227
  ok: string;
2204
2228
  close: string;
2205
2229
  BTN_REC_LIST_TITLE: string;
2230
+ UNKOWN_ISSUE: string;
2206
2231
  };
2207
2232
  };
2208
2233
  /** 版本号 @since 0.0.1 */
@@ -2290,6 +2315,8 @@ declare class Theme extends EventEmitter {
2290
2315
  private _volume;
2291
2316
  /** 静音 */
2292
2317
  private _muted;
2318
+ /** 正在兜底的原始 scope,非 null 表示处于兜底取值中(用于避免 customizeMissing 无限递归) */
2319
+ private _missingScope;
2293
2320
  /** 电子放大倍数 @private */
2294
2321
  _zoom: number;
2295
2322
  /** 放大中 true: 可缩放状态,false: 禁止缩放状态(不能缩放) @private */
@@ -2346,6 +2373,22 @@ declare class Theme extends EventEmitter {
2346
2373
  * url 信息 播放地址信息
2347
2374
  */
2348
2375
  get urlInfo(): Partial<_ezuikit_utils_tools.EzopenURL>;
2376
+ /**
2377
+ * 当前播放类型,由播放地址解析得出
2378
+ *
2379
+ * 取值 `'live' | 'rec' | 'cloudRec' | 'cloudRecord'`,无法判定时为空字符串 `''`。
2380
+ *
2381
+ * 与 {@link recType} 的关系:`recType` 只覆盖三种回放,直播时为空串;
2382
+ * 本 getter 把直播也纳入同一个枚举,作为「当前播放类型」的统一出口。
2383
+ *
2384
+ * @remarks 空串表示无法从地址判定(如 rtmp、webrtc、地址未设置)。
2385
+ * 此时控件支持性校验会整体跳过,避免对判不出类型的地址误报。
2386
+ * @since 3.1.7
2387
+ * ```ts
2388
+ * theme.playType // 'cloudRec'
2389
+ * ```
2390
+ */
2391
+ get playType(): ThemePlayType | '';
2349
2392
  /**
2350
2393
  * 容器的宽(单位 px)
2351
2394
  * ```ts
@@ -2631,6 +2674,37 @@ declare class Theme extends EventEmitter {
2631
2674
  * @param {0 | 1 | 2} scaleMode - 缩放模式, 0: 窗口铺满, 1: 等比缩放大边铺满, 2: 等比缩放小边铺满
2632
2675
  */
2633
2676
  setScaleMode(scaleMode: ThemeOptions['scaleMode']): void;
2677
+ /**
2678
+ * 获取多语言文案
2679
+ *
2680
+ * 相比直接用 `theme.i18n.t()`:返回类型收窄为 `string`(底层签名是 `string | number`,
2681
+ * 调用处不必再写 `as string`)。缺失 key 的兜底由 i18n 实例上的 `customizeMissing`
2682
+ * 统一处理,因此两者在兜底行为上一致。
2683
+ * @param scope 多语言 key
2684
+ * @param variables 插值变量,如 `{ zoom: 8 }`;传 `defaultvalue` 可指定自己的兜底文案
2685
+ * @returns 文案;scope 不存在时返回「未知问题 【scope】」
2686
+ * @example
2687
+ * ```ts
2688
+ * theme.t('ZOOM_LIMIT_MAX', { zoom: 8 });
2689
+ * theme.t('NOT_EXIST_KEY'); // 未知问题 【NOT_EXIST_KEY】
2690
+ * theme.t('NOT_EXIST_KEY', { defaultvalue: '自定义兜底' }); // 自定义兜底
2691
+ * ```
2692
+ */
2693
+ t(scope: string | number, variables?: TranslateVariables): string;
2694
+ /**
2695
+ * 语言包缺 key 时的兜底文案(`customizeMissing` 的实现)
2696
+ *
2697
+ * 注意底层是把本方法的返回值「原样返回」、不再做插值,所以这里借
2698
+ * `i18n.t(UNKOWN_ISSUE)` 完成插值。而这一次取值本身也可能缺失
2699
+ * (如 `language` 传了不存在的语言,当前语言包整体不存在),
2700
+ * 那会再次回调到这里造成无限递归,因此用重入标记兜住,退化为直接返回原始 scope。
2701
+ *
2702
+ * 注:`options.locales` 与内置语言包是深合并,无法移除内置的 UNKOWN_ISSUE,
2703
+ * 因此正常配置下不会走到退化分支。
2704
+ * @param scope 缺失的多语言 key
2705
+ * @param variables 原始插值变量
2706
+ */
2707
+ private _missingText;
2634
2708
  /**
2635
2709
  * 销毁包括事件、控件 ...
2636
2710
  *
@@ -2893,44 +2967,202 @@ interface ThemeVideoInfo {
2893
2967
  * @since 0.0.1
2894
2968
  */
2895
2969
  type ThemeRecType = 'rec' | 'cloudRec' | 'cloudRecord';
2970
+ /**
2971
+ * 播放类型:直播 + 三种回放
2972
+ *
2973
+ * 由播放地址解析得出,见 `theme.playType`。控件通过静态属性 `supportedPlayTypes`
2974
+ * 声明自己支持哪几种,渲染时不匹配只提示、不阻止渲染。
2975
+ *
2976
+ * 类型直接由 `PLAY_TYPES` 常量推导,保证值与类型不会漂移。
2977
+ * @since 3.1.7
2978
+ */
2979
+ type ThemePlayType = (typeof PLAY_TYPES)[number];
2896
2980
 
2897
2981
  /**
2898
- * 回放控件配置项
2982
+ * 控件基类配置项
2899
2983
  */
2900
- interface RecOptions extends Omit<ControlOptions, 'tagName'> {
2984
+ interface ControlOptions {
2985
+ /** 播放器窗口节点 */
2986
+ rootContainer?: HTMLElement;
2987
+ /** 挂载节点 player id, 默认挂载 body 上 */
2988
+ getPopupContainer?: () => HTMLElement;
2989
+ /** 给控件新增自定义类名 */
2990
+ className?: string;
2991
+ /** 语言数据 */
2992
+ locale?: Record<string, string>;
2993
+ /** 样式类后缀 */
2994
+ classNameSuffix?: string;
2995
+ /**
2996
+ * 渲染节点标签
2997
+ */
2998
+ tagName?: 'div' | 'span';
2999
+ /**
3000
+ * 控件类型, 默认 button
3001
+ */
3002
+ controlType?: 'button' | 'text' | 'block';
3003
+ /**
3004
+ * 当前语言
3005
+ */
3006
+ language?: 'zh' | 'en' | string;
3007
+ /**
3008
+ * 所有语言数据
3009
+ */
3010
+ locales?: Record<string, Record<string | number, string | number>>;
2901
3011
  /** 点击控件时的回调 */
2902
3012
  onClick?: (e: Event) => void;
2903
- /** 回放类型切换时的回调 */
2904
- onChange?: (type: ThemeRecType) => void;
2905
- /** 默认回放类型, 默认 'rec' */
2906
- recType?: ThemeRecType;
3013
+ /**
3014
+ * ----- 播放器状态 -------
3015
+ * 窗口宽度 width?: number;
3016
+ * 窗口高度 height?: number;
3017
+ * 窗口是否全屏 isCurrentFullscreen?: boolean;
3018
+ * 播放器是否播放中 playing?: boolean;
3019
+ * 音量大小 0-1 volume?: number;
3020
+ * 是否静音 muted?: boolean;
3021
+ * 浏览器选择角度 0 | 90 | 180 | 270 orientationAngle?: number;
3022
+ * 所有属性值来源 constant.ts 文中 THEME_PROPS
3023
+ */
3024
+ props?: Record<(typeof THEME_PROPS)[number], number | string | Record<string, unknown>>;
3025
+ [key: string]: any;
2907
3026
  }
2908
3027
  /**
2909
- * 回放类型切换(本地回放(sdk 卡), 云存储回放, 云录制回放)控件
3028
+ * 不允许控件自定义的参数
3029
+ * @typeParam T - 控件配置项
3030
+ */
3031
+ type OmitControlOptions<T extends ControlOptions> = Omit<T, 'rootContainer' | 'getPopupContainer' | 'classNameSuffix' | 'type' | 'tagName' | 'controlType'>;
3032
+ /**
3033
+ * 控件基类
2910
3034
  * @category Control
3035
+ * @example
3036
+ * ```ts
3037
+ * // 创建控件
3038
+ * class MyControl extends Control {}
3039
+ *
3040
+ * // 使用控件
3041
+ * const myControl = new MyControl({})
3042
+ * ```
2911
3043
  */
2912
- declare class Rec extends Control {
2913
- private readonly _options;
2914
- private _delegation;
2915
- private recType;
2916
- constructor(options: RecOptions);
3044
+ declare class Control extends EventEmitter {
2917
3045
  /**
2918
- * 销毁
3046
+ * 该控件支持的播放类型,默认全支持
3047
+ *
3048
+ * 子类用 `static supportedPlayTypes = [...]` 覆盖来收窄范围。声明是**静态**的,
3049
+ * 因为渲染层需要在不实例化控件的前提下就能读到(`Controls[iconId].supportedPlayTypes`)。
3050
+ *
3051
+ * 渲染时会拿 `theme.playType` 与此比对,不匹配只发警告与 `Control.unsupportedPlayType`
3052
+ * 事件,**不阻止渲染**,控件照常创建、照常可交互,行为是否生效由 SDK 层与设备能力决定。
3053
+ *
3054
+ * @since 3.1.7
3055
+ * @example
3056
+ * ```ts
3057
+ * class MyControl extends Control {
3058
+ * // 只在云存储回放下有意义
3059
+ * static supportedPlayTypes: ThemePlayType[] = ['cloudRec'];
3060
+ * }
3061
+ * ```
3062
+ */
3063
+ static supportedPlayTypes: ThemePlayType[];
3064
+ /**
3065
+ * 判断某个播放类型是否被本控件支持
3066
+ *
3067
+ * @param playType 播放类型;传空串(无法从地址判定)时一律返回 `true`,避免误报
3068
+ * @returns 是否支持
3069
+ * @since 3.1.7
3070
+ */
3071
+ static supportsPlayType(playType: ThemePlayType | ''): boolean;
3072
+ /**
3073
+ * 控件内容
3074
+ */
3075
+ $container: HTMLDivElement | HTMLSpanElement;
3076
+ /**
3077
+ * 控件挂载的节点
3078
+ */
3079
+ $popupContainer: HTMLElement;
3080
+ /** 具体语言对应的值 */
3081
+ locale: Record<string | number, string> | null;
3082
+ protected __options: ControlOptions;
3083
+ protected _disabled: boolean;
3084
+ protected _active: boolean;
3085
+ private readonly _camelCaseName;
3086
+ /** click 监听引用,销毁时需显式移除 */
3087
+ private _onClickHandler;
3088
+ constructor(options: Partial<ControlOptions>);
3089
+ /**
3090
+ * 是否激活
3091
+ */
3092
+ get active(): boolean;
3093
+ set active(active: boolean);
3094
+ /**
3095
+ * 是否禁用
3096
+ */
3097
+ get disabled(): boolean;
3098
+ set disabled(disabled: boolean);
3099
+ /**
3100
+ * 重置整个控件
3101
+ */
3102
+ reset(hide?: boolean): void;
3103
+ /**
3104
+ * 重置控件挂载节点
3105
+ * @param popupContainer 重新挂载的节点
3106
+ * @param append 添加的方式, 默认 append
3107
+ * @param element 当 append = before 时 需要 element, 插入 element 前
3108
+ *
3109
+ * | prepend | append |
3110
+ * |:-------------:|:---------------:|
3111
+ * | 插入第一个位置 | 追加在末尾 |
3112
+ */
3113
+ resetPopupContainer(popupContainer: Element, append?: 'prepend' | 'append' | 'before', element?: Element): void;
3114
+ /**
3115
+ * 隐藏整个控件
3116
+ */
3117
+ hide(): void;
3118
+ /**
3119
+ * 销毁控件
2919
3120
  */
2920
3121
  destroy(): void;
3122
+ protected _updateDisabledState(disabled: boolean): void;
3123
+ protected _updateActiveState(active: boolean): void;
2921
3124
  /**
2922
- * 添加回放类型图标
2923
- * @param {string} id 回放类型 'rec' | 'cloudRec' | 'cloudRecord'
3125
+ * 当点击 Control 时 触发子类的 _onControlClick
2924
3126
  */
2925
- addRecType(id: string): void;
2926
- private _activeIcon;
2927
- private _onClickIcon;
3127
+ protected _onClick(): void;
3128
+ protected _onDBlClick(e: Event): void;
2928
3129
  /**
2929
- * 点击 Control 会触发
3130
+ * 点击 Control 控件触发
3131
+ * @param {Event} e
3132
+ * @returns {void}
2930
3133
  */
2931
3134
  protected _onControlClick(e: Event): void;
2932
3135
  }
2933
3136
 
3137
+ /**
3138
+ * 加载动画控件配置项
3139
+ */
3140
+ interface LoadingOptions extends Omit<ControlOptions, 'tagName' | 'controlType'> {
3141
+ /**
3142
+ * 自定义加载动画的 HTML 结构, 当 theme.loading = true 时展示
3143
+ * @returns HTML 字符串
3144
+ */
3145
+ render?: () => string;
3146
+ }
3147
+ /**
3148
+ * 加载动画控件
3149
+ * @category Control
3150
+ */
3151
+ declare class Loading extends Control {
3152
+ private readonly _options;
3153
+ constructor(options?: Partial<LoadingOptions>);
3154
+ private _html;
3155
+ /**
3156
+ * 动画展示
3157
+ * @param html 自定义动画内容, 如果不存在则使用默认动画
3158
+ */
3159
+ show(html?: string): void;
3160
+ /**
3161
+ * 隐藏动画
3162
+ */
3163
+ hide(): void;
3164
+ }
3165
+
2934
3166
  /**
2935
3167
  * 屏幕旋转方向
2936
3168
  */
@@ -3075,7 +3307,16 @@ interface PtzErrorInfo {
3075
3307
  * 可用于给 eventemitter3 提供泛型:`class Theme extends EventEmitter<ThemeEventMap>`,
3076
3308
  * 或直接查询单个事件的处理函数类型:`ThemeEventMap['play']`。
3077
3309
  */
3078
- interface ThemeEventMap {
3310
+ /**
3311
+ * 各控件初始化完成事件的载荷(统一为无参)。
3312
+ *
3313
+ * 由 `CONTROL_INIT_EVENTS` 的值映射生成,新增控件只需往常量里加一项,
3314
+ * 类型侧自动跟上,无需在 {@link ThemeEventMap} 里手写。
3315
+ */
3316
+ type ControlInitEventMap = {
3317
+ [K in (typeof CONTROL_INIT_EVENTS)[keyof typeof CONTROL_INIT_EVENTS]]: () => void;
3318
+ };
3319
+ interface ThemeEventMap extends ControlInitEventMap {
3079
3320
  /** 加载状态变化 */
3080
3321
  loading: (loading: boolean) => void;
3081
3322
  /** 播放/暂停状态变化 */
@@ -3156,6 +3397,14 @@ interface ThemeEventMap {
3156
3397
  }) => void;
3157
3398
  /** 统一消息提示入口(duration 单位秒) */
3158
3399
  message: (message: string, type: string, duration?: number) => void;
3400
+ /**
3401
+ * 控件不支持当前播放类型(仅提示,控件仍会渲染)
3402
+ *
3403
+ * @param iconId 控件 iconId
3404
+ * @param playType 当前播放类型
3405
+ * @param supportedPlayTypes 该控件声明支持的播放类型
3406
+ */
3407
+ 'Control.unsupportedPlayType': (iconId: string, playType: ThemePlayType, supportedPlayTypes: ThemePlayType[]) => void;
3159
3408
  /** 控件挂载前 */
3160
3409
  'Control.beforeMountControls': () => void;
3161
3410
  /** 控件挂载完成 */
@@ -3227,8 +3476,8 @@ interface ThemeEventMap {
3227
3476
  'Control.datePanelMonthChange': (date: Date, month: string) => void;
3228
3477
  /** 日历面板展示的年份变化,`year` 格式 `YYYY` */
3229
3478
  'Control.datePanelYearChange': (date: Date, year: string) => void;
3230
- /** 日历控件销毁(注意其字符串值为 `Control.datePanelDestroy`) */
3231
- 'Control.datePanelDestroy': () => void;
3479
+ /** 日历控件销毁 */
3480
+ 'Control.dateDestroy': () => void;
3232
3481
  'Control.timePanelOpenChange': (open: boolean, time: string) => void;
3233
3482
  'Control.timeChange': (time: string) => void;
3234
3483
  'Control.timeLineChange': (date: Date | string) => void;
@@ -3249,5 +3498,5 @@ type ThemeEventHandler<K extends ThemeEventName> = K extends keyof ThemeEventMap
3249
3498
  /** 单个事件的参数元组,如 `ThemeEventArgs<'volumechange'>` = `[number, boolean]` */
3250
3499
  type ThemeEventArgs<K extends ThemeEventName> = K extends keyof ThemeEventMap ? Parameters<ThemeEventMap[K]> : unknown[];
3251
3500
 
3252
- export { Control, EVENTS, Fullscreen, Loading, Message, Play, Poster, Rec, Theme, Utils, Volume };
3253
- export type { AudioInfo, CleanUpResizeObserver, CleanUpScreenOrientationFun, ControlEventName, ControlItem, ControlOptions, FooterOptions, FullscreenChangeInfo, FullscreenOptions, HeaderOptions, IThemeData, IThemeDataItem, LoadingOptions, MessageOptions, OrientationAngle, PlayOptions, PosterOptions, PtzErrorInfo, RecOptions, ResizeInfo, ScreenOrientation, ThemeEventArgs, ThemeEventHandler, ThemeEventMap, ThemeEventName, ThemeLifecycleEventName, ThemeOptions, ThemeOuterEventName, VideoInfo, VolumeOptions };
3501
+ export { CONTROL_INIT_EVENTS, Control, EVENTS, Fullscreen, Loading, Message, Play, Poster, Rec, Theme, Utils, Volume };
3502
+ export type { AudioInfo, CleanUpResizeObserver, CleanUpScreenOrientationFun, ControlEventName, ControlInitEventMap, ControlItem, ControlOptions, FooterOptions, FullscreenChangeInfo, FullscreenOptions, HeaderOptions, IThemeData, IThemeDataItem, LoadingOptions, MessageOptions, OrientationAngle, PlayOptions, PosterOptions, PtzErrorInfo, RecOptions, ResizeInfo, ScreenOrientation, ThemeEventArgs, ThemeEventHandler, ThemeEventMap, ThemeEventName, ThemeLifecycleEventName, ThemeOptions, ThemeOuterEventName, VideoInfo, VolumeOptions };