sample-xmonitor-js 0.0.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.
- package/lib/DefaultMonitor.d.ts +19 -0
- package/lib/DefaultMonitor.js +140 -0
- package/lib/Monitor.d.ts +130 -0
- package/lib/Monitor.js +129 -0
- package/lib/index.d.ts +47 -0
- package/lib/index.js +124 -0
- package/package.json +36 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Monitor, { DefaultSetup, MObject, MonitorOptions } from "./Monitor";
|
|
2
|
+
declare class DefaultMonitor extends Monitor {
|
|
3
|
+
private stream;
|
|
4
|
+
private active;
|
|
5
|
+
constructor(options: MonitorOptions);
|
|
6
|
+
protected getMedia(setup: DefaultSetup): any;
|
|
7
|
+
start(): Promise<any>;
|
|
8
|
+
stop(): Promise<any>;
|
|
9
|
+
}
|
|
10
|
+
export declare class DesktopMonitor extends DefaultMonitor {
|
|
11
|
+
constructor(object: MObject, element: HTMLDivElement, setup?: DefaultSetup);
|
|
12
|
+
start(): Promise<any>;
|
|
13
|
+
protected getMedia(setup: DefaultSetup): any;
|
|
14
|
+
}
|
|
15
|
+
export declare class CameraMonitor extends DefaultMonitor {
|
|
16
|
+
constructor(object: MObject, element: HTMLDivElement, setup?: DefaultSetup);
|
|
17
|
+
protected getMedia(setup: DefaultSetup): any;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import Monitor, { NotSupportError, ScreenTypeError } from "./Monitor";
|
|
11
|
+
let win = window;
|
|
12
|
+
const navigator = win.navigator;
|
|
13
|
+
if (!navigator.mediaDevices) {
|
|
14
|
+
navigator["mediaDevices"] = {
|
|
15
|
+
getUserMedia: (constraints) => {
|
|
16
|
+
return navigator.getUserMedia ? new Promise((resolve, reject) => {
|
|
17
|
+
navigator.getUserMedia(constraints, resolve, reject);
|
|
18
|
+
}) : Promise.reject(new NotSupportError('This browser not support getUserMedia'));
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
const { mediaDevices } = navigator;
|
|
23
|
+
if (!mediaDevices.getDisplayMedia) {
|
|
24
|
+
mediaDevices.getDisplayMedia = (options) => {
|
|
25
|
+
return Promise.reject(new NotSupportError('This browser not support getDisplayMedia'));
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
class DefaultMonitor extends Monitor {
|
|
29
|
+
constructor(options) {
|
|
30
|
+
super(options);
|
|
31
|
+
this.active = false;
|
|
32
|
+
let video = document.createElement('video');
|
|
33
|
+
video.setAttribute('autoplay', 'true');
|
|
34
|
+
// 该属性的作用是在ios下video可以播放 否则会显示黑屏
|
|
35
|
+
video.setAttribute('playsinline', '');
|
|
36
|
+
video.style.width = "100%";
|
|
37
|
+
video.style.height = "100%";
|
|
38
|
+
options.element.appendChild(video);
|
|
39
|
+
this.element = video;
|
|
40
|
+
}
|
|
41
|
+
getMedia(setup) { }
|
|
42
|
+
start() {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
if (this.active)
|
|
45
|
+
return;
|
|
46
|
+
let stream;
|
|
47
|
+
try {
|
|
48
|
+
stream = yield this.getMedia(Object.assign({ audio: false, video: true }, this.options.setup));
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
/*
|
|
52
|
+
* AbortError[中止错误]
|
|
53
|
+
* 尽管用户和操作系统都授予了访问设备硬件的权利,而且未出现可能抛出NotReadableError异常的硬件问题,但仍然有一些问题的出现导致了设备无法被使用。
|
|
54
|
+
* NotAllowedError[拒绝错误]
|
|
55
|
+
* 用户拒绝了当前的浏览器实例的访问请求;或者用户拒绝了当前会话的访问;或者用户在全局范围内拒绝了所有媒体访问请求。
|
|
56
|
+
* NotFoundError[找不到错误]
|
|
57
|
+
* 找不到满足请求参数的媒体类型。
|
|
58
|
+
* NotReadableError[无法读取错误]
|
|
59
|
+
* 尽管用户已经授权使用相应的设备,操作系统上某个硬件、浏览器或者网页层面发生的错误导致设备无法被访问。
|
|
60
|
+
* OverconstrainedError[无法满足要求错误]
|
|
61
|
+
* 指定的要求无法被设备满足,此异常是一个类型为OverconstrainedError的对象,拥有一个constraint属性,这个属性包含了当前无法被满足的constraint对象,还拥有一个message属性,包含了阅读友好的字符串用来说明情况。
|
|
62
|
+
*SecurityError[安全错误]
|
|
63
|
+
* 在getUserMedia() 被调用的 Document 上面,使用设备媒体被禁止。这个机制是否开启或者关闭取决于单个用户的偏好设置。
|
|
64
|
+
* TypeError[类型错误]
|
|
65
|
+
*constraints 对象未设置[空],或者都被设置为false。
|
|
66
|
+
*
|
|
67
|
+
* */
|
|
68
|
+
if (!(e instanceof NotSupportError)) {
|
|
69
|
+
this.dispatchEvent('error', void 0, e);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw e;
|
|
73
|
+
}
|
|
74
|
+
let { element } = this;
|
|
75
|
+
element.srcObject = stream;
|
|
76
|
+
this.stream = stream;
|
|
77
|
+
let track = stream.getTracks()[0];
|
|
78
|
+
if (this.options.type === 'default:desktop' && !/^screen/i.test(track.label)) {
|
|
79
|
+
yield this.stop();
|
|
80
|
+
this.dispatchEvent('error', null, new ScreenTypeError('Screen share type error', 'ScreenTypeError'));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
track.onended = e => {
|
|
84
|
+
this.active = false;
|
|
85
|
+
this.dispatchEvent('cancel');
|
|
86
|
+
};
|
|
87
|
+
element.onloadedmetadata = () => {
|
|
88
|
+
element.play();
|
|
89
|
+
this.dispatchEvent('start');
|
|
90
|
+
};
|
|
91
|
+
element.onplaying = () => {
|
|
92
|
+
this.active = true;
|
|
93
|
+
};
|
|
94
|
+
element.onended = () => {
|
|
95
|
+
this.active = false;
|
|
96
|
+
this.dispatchEvent('stop');
|
|
97
|
+
};
|
|
98
|
+
return track;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
stop() {
|
|
102
|
+
const _super = Object.create(null, {
|
|
103
|
+
stop: { get: () => super.stop }
|
|
104
|
+
});
|
|
105
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
this.active = false;
|
|
107
|
+
if (this.stream) {
|
|
108
|
+
this.element.pause();
|
|
109
|
+
this.stream.getTracks().forEach((track) => track.stop());
|
|
110
|
+
this.stream = void 0;
|
|
111
|
+
}
|
|
112
|
+
this.element.remove();
|
|
113
|
+
_super.stop.call(this);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export class DesktopMonitor extends DefaultMonitor {
|
|
118
|
+
constructor(object, element, setup) {
|
|
119
|
+
super({ type: 'default:desktop', object, element, setup });
|
|
120
|
+
}
|
|
121
|
+
start() {
|
|
122
|
+
const _super = Object.create(null, {
|
|
123
|
+
start: { get: () => super.start }
|
|
124
|
+
});
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
return _super.start.call(this);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
getMedia(setup) {
|
|
130
|
+
return mediaDevices.getDisplayMedia(setup);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export class CameraMonitor extends DefaultMonitor {
|
|
134
|
+
constructor(object, element, setup) {
|
|
135
|
+
super({ type: 'default:camera', element, object, setup });
|
|
136
|
+
}
|
|
137
|
+
getMedia(setup) {
|
|
138
|
+
return mediaDevices.getUserMedia(setup);
|
|
139
|
+
}
|
|
140
|
+
}
|
package/lib/Monitor.d.ts
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export declare interface Setup {
|
|
2
|
+
/**
|
|
3
|
+
*控制视频截图清晰度
|
|
4
|
+
*/
|
|
5
|
+
sharpness?: number;
|
|
6
|
+
/**
|
|
7
|
+
* 图像分类
|
|
8
|
+
*/
|
|
9
|
+
classify?: string;
|
|
10
|
+
/**
|
|
11
|
+
* 其他参数
|
|
12
|
+
*/
|
|
13
|
+
[key: string]: any;
|
|
14
|
+
}
|
|
15
|
+
export declare interface DefaultSetup extends Setup {
|
|
16
|
+
audio: false;
|
|
17
|
+
/**
|
|
18
|
+
* [点击文档](https://developer.mozilla.org/zh-CN/docs/Web/API/MediaDevices/getUserMedia)
|
|
19
|
+
* 视频配置信息
|
|
20
|
+
* min: 最小画像宽度 max 最大画像宽度 ideal: 推荐的理想画质宽度
|
|
21
|
+
*
|
|
22
|
+
* user: 前置摄像头 environment:后置摄像头
|
|
23
|
+
* frameRate: 设置帧率 ideal 推荐帧率 max 最大帧率 受限带宽传输时,低帧率可能更适宜 eg: frameRate: { ideal: 10, max: 15 }
|
|
24
|
+
*/
|
|
25
|
+
video: true | {
|
|
26
|
+
frameRate: {
|
|
27
|
+
ideal: number;
|
|
28
|
+
max: number;
|
|
29
|
+
};
|
|
30
|
+
facingMode: 'user' | 'environment';
|
|
31
|
+
width: number | {
|
|
32
|
+
min: number;
|
|
33
|
+
ideal: number;
|
|
34
|
+
max: number;
|
|
35
|
+
};
|
|
36
|
+
height: number | {
|
|
37
|
+
min: number;
|
|
38
|
+
ideal: number;
|
|
39
|
+
max: number;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
declare class Watcher {
|
|
44
|
+
private readonly monitor;
|
|
45
|
+
private readonly driver;
|
|
46
|
+
private readonly name;
|
|
47
|
+
constructor(monitor: Monitor);
|
|
48
|
+
clean(): Promise<unknown>;
|
|
49
|
+
shot(sharpness?: number): Promise<any>;
|
|
50
|
+
select(): any;
|
|
51
|
+
}
|
|
52
|
+
export type NotSupportType = 'device' | 'browser' | 'element';
|
|
53
|
+
export declare class NotSupportError extends Error {
|
|
54
|
+
readonly code: string;
|
|
55
|
+
constructor(message: any, code?: any);
|
|
56
|
+
}
|
|
57
|
+
export declare class ScreenTypeError extends Error {
|
|
58
|
+
readonly code: string;
|
|
59
|
+
constructor(message: any, code?: any);
|
|
60
|
+
}
|
|
61
|
+
export type MonitorType = 'default:desktop' | 'default:camera';
|
|
62
|
+
/**
|
|
63
|
+
* cancel 用户取消 不给授权 禁用摄像头
|
|
64
|
+
* start 开始录制
|
|
65
|
+
* pause 暂停录制
|
|
66
|
+
* shot 截图
|
|
67
|
+
* stop 录制停止
|
|
68
|
+
* error 发生错误
|
|
69
|
+
* changed 状态改变
|
|
70
|
+
*/
|
|
71
|
+
export type MonitorEvent = 'cancel' | 'start' | 'playing' | 'pause' | 'shot' | 'stop' | 'error' | 'changed';
|
|
72
|
+
export declare const MonitorEvents: Array<string>;
|
|
73
|
+
export type MonitorEventObject = {
|
|
74
|
+
event: MonitorEvent;
|
|
75
|
+
target: Monitor;
|
|
76
|
+
data?: any;
|
|
77
|
+
error?: any;
|
|
78
|
+
};
|
|
79
|
+
export declare class MObject {
|
|
80
|
+
/**
|
|
81
|
+
* 所属活动
|
|
82
|
+
*/
|
|
83
|
+
readonly activity: string;
|
|
84
|
+
/**
|
|
85
|
+
* 所属房间
|
|
86
|
+
*/
|
|
87
|
+
readonly room: string;
|
|
88
|
+
/**
|
|
89
|
+
* 所属ID
|
|
90
|
+
*/
|
|
91
|
+
readonly id: string;
|
|
92
|
+
private constructor();
|
|
93
|
+
static create({ room, id, activity }: Record<string, any>): MObject;
|
|
94
|
+
toString(): string;
|
|
95
|
+
}
|
|
96
|
+
export interface MonitorEventListener {
|
|
97
|
+
(evt: MonitorEventObject): void;
|
|
98
|
+
}
|
|
99
|
+
export type MonitorOptions = {
|
|
100
|
+
object: MObject;
|
|
101
|
+
type: MonitorType;
|
|
102
|
+
element: HTMLDivElement;
|
|
103
|
+
setup?: DefaultSetup;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* 监视器
|
|
107
|
+
*/
|
|
108
|
+
export default class Monitor {
|
|
109
|
+
readonly options: MonitorOptions;
|
|
110
|
+
readonly no: string;
|
|
111
|
+
element: HTMLVideoElement;
|
|
112
|
+
readonly type: MonitorType;
|
|
113
|
+
readonly watcher: Watcher;
|
|
114
|
+
private eventPool;
|
|
115
|
+
constructor(options: MonitorOptions);
|
|
116
|
+
isPaused(): boolean;
|
|
117
|
+
shot(): Promise<any>;
|
|
118
|
+
/**
|
|
119
|
+
* 启动监控
|
|
120
|
+
*/
|
|
121
|
+
start(): any;
|
|
122
|
+
/**
|
|
123
|
+
* 停止监控
|
|
124
|
+
*/
|
|
125
|
+
stop(): any;
|
|
126
|
+
addEventListener(event: MonitorEvent, listener: MonitorEventListener): void;
|
|
127
|
+
protected dispatchEvent(event: MonitorEvent, data?: any, error?: any): void;
|
|
128
|
+
removeEventListener(event: MonitorEvent): void;
|
|
129
|
+
}
|
|
130
|
+
export {};
|
package/lib/Monitor.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import Driver from 'xdriver';
|
|
2
|
+
class Watcher {
|
|
3
|
+
constructor(monitor) {
|
|
4
|
+
this.monitor = monitor;
|
|
5
|
+
this.name = monitor.type;
|
|
6
|
+
let driver = new Driver('x-monitor');
|
|
7
|
+
driver.initialize(() => {
|
|
8
|
+
driver.createTables(['desktop', 'camera'], {
|
|
9
|
+
primaryKey: 'id',
|
|
10
|
+
autoIncrement: true
|
|
11
|
+
});
|
|
12
|
+
}).open().then(() => {
|
|
13
|
+
console.debug('Shot');
|
|
14
|
+
});
|
|
15
|
+
this.driver = driver;
|
|
16
|
+
}
|
|
17
|
+
clean() {
|
|
18
|
+
return this.driver.drop();
|
|
19
|
+
}
|
|
20
|
+
shot(sharpness = 0.3) {
|
|
21
|
+
var _a;
|
|
22
|
+
if (sharpness > 1)
|
|
23
|
+
sharpness = 1;
|
|
24
|
+
if (sharpness < 0)
|
|
25
|
+
sharpness = 0.1;
|
|
26
|
+
let { videoWidth, videoHeight } = this.monitor.element;
|
|
27
|
+
let name = Date.now() + '.jpg';
|
|
28
|
+
let canvas = document.createElement("canvas");
|
|
29
|
+
canvas.width = videoWidth * sharpness;
|
|
30
|
+
canvas.height = videoHeight * sharpness;
|
|
31
|
+
canvas.getContext('2d').drawImage(this.monitor.element, 0, 0, videoWidth * sharpness, videoHeight * sharpness);
|
|
32
|
+
let img = { name };
|
|
33
|
+
Object.defineProperty(img, "blob", {
|
|
34
|
+
get() {
|
|
35
|
+
return new Promise((resolve) => {
|
|
36
|
+
canvas.toBlob((blob) => {
|
|
37
|
+
resolve(blob);
|
|
38
|
+
}, this.type, sharpness);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
img.no = this.monitor.no;
|
|
43
|
+
img.name = name;
|
|
44
|
+
img.data = canvas.toDataURL('jpg');
|
|
45
|
+
img.type = this.name;
|
|
46
|
+
img.classify = (_a = this.monitor.options.setup) === null || _a === void 0 ? void 0 : _a.classify;
|
|
47
|
+
let table = this.name;
|
|
48
|
+
if (table.indexOf(':') !== -1) {
|
|
49
|
+
table = table.split(':')[1];
|
|
50
|
+
}
|
|
51
|
+
return this.driver.insert(table, [img]).then(res => img);
|
|
52
|
+
}
|
|
53
|
+
select() {
|
|
54
|
+
return this.driver.query(this.name);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export class NotSupportError extends Error {
|
|
58
|
+
constructor(message, code) {
|
|
59
|
+
super(message);
|
|
60
|
+
this.code = code;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export class ScreenTypeError extends Error {
|
|
64
|
+
constructor(message, code) {
|
|
65
|
+
super(message);
|
|
66
|
+
this.code = code;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export const MonitorEvents = ['cancel', 'start', 'playing', 'pause', 'shot', 'stop', 'error', 'changed'];
|
|
70
|
+
export class MObject {
|
|
71
|
+
constructor(room, id, activity = 'default') {
|
|
72
|
+
this.activity = activity;
|
|
73
|
+
this.room = room;
|
|
74
|
+
this.id = id;
|
|
75
|
+
}
|
|
76
|
+
static create({ room, id, activity }) {
|
|
77
|
+
return new MObject(room, id, activity);
|
|
78
|
+
}
|
|
79
|
+
toString() {
|
|
80
|
+
return `${this.activity}-${this.room}-${this.id}`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 监视器
|
|
85
|
+
*/
|
|
86
|
+
export default class Monitor {
|
|
87
|
+
constructor(options) {
|
|
88
|
+
this.eventPool = new Map();
|
|
89
|
+
this.options = options;
|
|
90
|
+
this.type = options.type;
|
|
91
|
+
this.no = `${options.object}`;
|
|
92
|
+
this.element = document.createElement('video');
|
|
93
|
+
this.watcher = new Watcher(this);
|
|
94
|
+
}
|
|
95
|
+
isPaused() {
|
|
96
|
+
return this.element.paused;
|
|
97
|
+
}
|
|
98
|
+
shot() {
|
|
99
|
+
var _a;
|
|
100
|
+
return this.watcher.shot((_a = this.options.setup) === null || _a === void 0 ? void 0 : _a.sharpness).then(img => {
|
|
101
|
+
this.dispatchEvent('shot', img);
|
|
102
|
+
return img;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 启动监控
|
|
107
|
+
*/
|
|
108
|
+
start() {
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 停止监控
|
|
112
|
+
*/
|
|
113
|
+
stop() {
|
|
114
|
+
this.dispatchEvent('stop');
|
|
115
|
+
}
|
|
116
|
+
addEventListener(event, listener) {
|
|
117
|
+
this.eventPool.set(event, listener);
|
|
118
|
+
}
|
|
119
|
+
dispatchEvent(event, data, error) {
|
|
120
|
+
let listener = this.eventPool.get(event);
|
|
121
|
+
if (listener) {
|
|
122
|
+
return listener({ event, target: this, data, error });
|
|
123
|
+
}
|
|
124
|
+
console.log(event, data, error);
|
|
125
|
+
}
|
|
126
|
+
removeEventListener(event) {
|
|
127
|
+
this.eventPool.delete(event);
|
|
128
|
+
}
|
|
129
|
+
}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import Monitor, { DefaultSetup, MObject, MonitorEvent, MonitorEventListener, MonitorType, Setup } from "./Monitor";
|
|
2
|
+
export default class MonitorFactory {
|
|
3
|
+
/**
|
|
4
|
+
* 监控
|
|
5
|
+
*/
|
|
6
|
+
static INSTANCE: MonitorFactory;
|
|
7
|
+
private readonly MonitorFactory;
|
|
8
|
+
private readonly pointer;
|
|
9
|
+
private readonly eventPool;
|
|
10
|
+
private intervalId;
|
|
11
|
+
constructor(pointer: MObject);
|
|
12
|
+
/**
|
|
13
|
+
* 添加事件监听
|
|
14
|
+
* 必须在start之前调用
|
|
15
|
+
* @param {MonitorEvent} event
|
|
16
|
+
* @param {Function} handler
|
|
17
|
+
*/
|
|
18
|
+
on(event: MonitorEvent, handler: MonitorEventListener): this;
|
|
19
|
+
/**
|
|
20
|
+
* 初始化监视器
|
|
21
|
+
* @param {MonitorType} type 监视器类型
|
|
22
|
+
* @param {HTMLDivElement} element 视频所在div元素
|
|
23
|
+
* @param {any} setup 监视器相关的参数
|
|
24
|
+
*/
|
|
25
|
+
init(type: MonitorType, element: HTMLDivElement, setup?: Setup): Monitor;
|
|
26
|
+
/**
|
|
27
|
+
* 启动所有监视器
|
|
28
|
+
*/
|
|
29
|
+
start(interval?: number): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* 停用监视器
|
|
32
|
+
*/
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* 初始化监控
|
|
37
|
+
*/
|
|
38
|
+
export declare function getInstance(options?: {
|
|
39
|
+
id: any;
|
|
40
|
+
room: any;
|
|
41
|
+
activity: any;
|
|
42
|
+
monitors: Array<{
|
|
43
|
+
type: MonitorType;
|
|
44
|
+
element: any;
|
|
45
|
+
setup?: DefaultSetup;
|
|
46
|
+
}>;
|
|
47
|
+
}): MonitorFactory;
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { MObject, MonitorEvents } from "./Monitor";
|
|
11
|
+
import { CameraMonitor, DesktopMonitor } from "./DefaultMonitor";
|
|
12
|
+
export default class MonitorFactory {
|
|
13
|
+
constructor(pointer) {
|
|
14
|
+
this.MonitorFactory = new Map();
|
|
15
|
+
this.eventPool = new Map();
|
|
16
|
+
this.intervalId = 0;
|
|
17
|
+
this.pointer = pointer;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 添加事件监听
|
|
21
|
+
* 必须在start之前调用
|
|
22
|
+
* @param {MonitorEvent} event
|
|
23
|
+
* @param {Function} handler
|
|
24
|
+
*/
|
|
25
|
+
on(event, handler) {
|
|
26
|
+
this.eventPool.set(event, handler);
|
|
27
|
+
return this;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 初始化监视器
|
|
31
|
+
* @param {MonitorType} type 监视器类型
|
|
32
|
+
* @param {HTMLDivElement} element 视频所在div元素
|
|
33
|
+
* @param {any} setup 监视器相关的参数
|
|
34
|
+
*/
|
|
35
|
+
init(type, element, setup) {
|
|
36
|
+
let monitor;
|
|
37
|
+
switch (type) {
|
|
38
|
+
case "default:camera":
|
|
39
|
+
monitor = new CameraMonitor(this.pointer, element, setup);
|
|
40
|
+
break;
|
|
41
|
+
case "default:desktop":
|
|
42
|
+
monitor = new DesktopMonitor(this.pointer, element, setup);
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
throw new Error(`Not support monitor type ${type}`);
|
|
46
|
+
}
|
|
47
|
+
MonitorEvents.forEach((evt) => {
|
|
48
|
+
monitor.addEventListener(evt, event => {
|
|
49
|
+
var _a;
|
|
50
|
+
// 监视器截图
|
|
51
|
+
(_a = this.eventPool.get(evt)) === null || _a === void 0 ? void 0 : _a.call(monitor, event);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
this.MonitorFactory.set(type, monitor);
|
|
55
|
+
return monitor;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* 启动所有监视器
|
|
59
|
+
*/
|
|
60
|
+
start() {
|
|
61
|
+
return __awaiter(this, arguments, void 0, function* (interval = 10000) {
|
|
62
|
+
if (interval < 5000) {
|
|
63
|
+
throw new Error('定时捕捉画面时间间隔不能少于5秒');
|
|
64
|
+
}
|
|
65
|
+
// 启动所有监视器
|
|
66
|
+
for (let [, monitor] of this.MonitorFactory) {
|
|
67
|
+
yield monitor.start();
|
|
68
|
+
}
|
|
69
|
+
clearInterval(this.intervalId);
|
|
70
|
+
// 启动timer定时截图
|
|
71
|
+
this.intervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
try {
|
|
73
|
+
// 调用所有监视器截图
|
|
74
|
+
for (let [, monitor] of this.MonitorFactory) {
|
|
75
|
+
if (monitor.isPaused())
|
|
76
|
+
continue;
|
|
77
|
+
yield monitor.shot();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
console.log(e);
|
|
82
|
+
}
|
|
83
|
+
}), interval);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 停用监视器
|
|
88
|
+
*/
|
|
89
|
+
stop() {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
91
|
+
clearInterval(this.intervalId);
|
|
92
|
+
// 启动所有监视器
|
|
93
|
+
for (let [, monitor] of this.MonitorFactory) {
|
|
94
|
+
yield monitor.stop();
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* 初始化监控
|
|
101
|
+
*/
|
|
102
|
+
export function getInstance(options) {
|
|
103
|
+
if (!MonitorFactory.INSTANCE) {
|
|
104
|
+
if (!options) {
|
|
105
|
+
throw new Error('实例尚未创建,参数不能为空');
|
|
106
|
+
}
|
|
107
|
+
let factory = new MonitorFactory(MObject.create(options));
|
|
108
|
+
const types = [];
|
|
109
|
+
for (let { element, type, setup } of options.monitors) {
|
|
110
|
+
if (typeof element === 'string') {
|
|
111
|
+
element = document.getElementById(element);
|
|
112
|
+
}
|
|
113
|
+
if (types.indexOf(type) !== -1) {
|
|
114
|
+
throw new Error(`重复的监视器类型 ${type}`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
types.push(type);
|
|
118
|
+
}
|
|
119
|
+
factory.init(type, element, setup);
|
|
120
|
+
}
|
|
121
|
+
MonitorFactory.INSTANCE = factory;
|
|
122
|
+
}
|
|
123
|
+
return MonitorFactory.INSTANCE;
|
|
124
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sample-xmonitor-js",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "./lib/index",
|
|
6
|
+
"files": [
|
|
7
|
+
"lib/"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"build:babel": "tsc && babel lib --out-dir dist && cd lib && del *.js*",
|
|
12
|
+
"build:webpack": "tsc && webpack --mode production"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git@codeup.aliyun.com:60b0836844816b8ed2335ed6/ui-modules/xmonitor.git"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"monitor"
|
|
20
|
+
],
|
|
21
|
+
"author": "xs",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^16.11.15",
|
|
25
|
+
"babel-cli": "^6.26.0",
|
|
26
|
+
"babel-preset-env": "^1.7.0",
|
|
27
|
+
"babel-preset-es2015": "^6.24.1",
|
|
28
|
+
"babel-preset-stage-2": "^6.24.1",
|
|
29
|
+
"uglifyjs-webpack-plugin": "^2.2.0",
|
|
30
|
+
"webpack": "^5.64.2",
|
|
31
|
+
"webpack-cli": "^4.9.1"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"xdriver": "^1.1.1"
|
|
35
|
+
}
|
|
36
|
+
}
|