roy-image-repository 0.1.0

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.
@@ -0,0 +1,60 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ import { Handler } from 'mitt';
4
+
5
+ export type ImageRepositoryEvents = {
6
+ /**
7
+ * 请求帧数据回调
8
+ */
9
+ ["requestFrame"]: {
10
+ /**
11
+ * 当前请求帧的时间戳,单位微秒
12
+ */
13
+ frameTimestampInMicroseconds: number;
14
+ /**
15
+ * 原生的事件对象
16
+ */
17
+ originalEvent: {
18
+ now: DOMHighResTimeStamp;
19
+ metadata: VideoFrameCallbackMetadata;
20
+ };
21
+ };
22
+ };
23
+ export declare class ImageRepository {
24
+ private readonly videoUrl;
25
+ private static _repositories;
26
+ private _isInited;
27
+ private _videoElement?;
28
+ /**
29
+ * 视频DOM元素,使用它来渲染画布
30
+ */
31
+ get videoElement(): HTMLVideoElement;
32
+ private _requestVideoFrameCallbackId?;
33
+ private _emitter;
34
+ private constructor();
35
+ static getRepository(videoUrl: string): Promise<ImageRepository>;
36
+ init(): Promise<void>;
37
+ uninit(): void;
38
+ /**
39
+ * 根据传入的微秒时间戳,获取指定位置的帧图片
40
+ * @param timstampInMicroseconds 微秒时间戳
41
+ */
42
+ getImage(timstampInMicroseconds: number): Promise<void>;
43
+ /**
44
+ * 开始播放连续帧图片
45
+ */
46
+ play(): Promise<void>;
47
+ /**
48
+ * 停止播放
49
+ */
50
+ stop(): void;
51
+ /**
52
+ * 暂停播放
53
+ */
54
+ pause(): void;
55
+ on<T extends keyof ImageRepositoryEvents>(eventName: T, handler: Handler<ImageRepositoryEvents[T]>): {
56
+ off: () => void;
57
+ };
58
+ }
59
+
60
+ export {};
@@ -0,0 +1 @@
1
+ var royImageRepository=(function(s){"use strict";async function d(o){return new Promise((i,t)=>{const e=document.createElement("video");e.muted=!0,e.crossOrigin="anonymous",e.preload="metadata",e.onloadedmetadata=()=>{e.width=e.videoWidth,e.height=e.videoHeight,i(e)},e.onerror=r=>{console.log("video load error",r),t(r)},e.src=o})}function l(o){return{all:o=o||new Map,on:function(i,t){var e=o.get(i);e?e.push(t):o.set(i,[t])},off:function(i,t){var e=o.get(i);e&&(t?e.splice(e.indexOf(t)>>>0,1):o.set(i,[]))},emit:function(i,t){var e=o.get(i);e&&e.slice().map(function(r){r(t)}),(e=o.get("*"))&&e.slice().map(function(r){r(i,t)})}}}function a(o){return o/1e6}function m(o){return o*1e6}class n{constructor(i){this.videoUrl=i}static _repositories={};_isInited=!1;_videoElement;get videoElement(){if(!this._videoElement)throw new Error("image repository is not inited!");return this._videoElement}_requestVideoFrameCallbackId;_emitter=l();static async getRepository(i){const t=i.toLowerCase().trim();return this._repositories[t]||(this._repositories[t]=new n(t),await this._repositories[t].init()),this._repositories[t]}async init(){if(this._isInited)return;this._isInited=!0,this._videoElement=await d(this.videoUrl);const i=(t,e)=>{this._emitter.emit("requestFrame",{frameTimestampInMicroseconds:m(e.mediaTime),originalEvent:{now:t,metadata:e}}),this._requestVideoFrameCallbackId=this._videoElement.requestVideoFrameCallback(i)};this._requestVideoFrameCallbackId=this._videoElement.requestVideoFrameCallback(i)}uninit(){this._isInited&&(this._isInited=!1,this._requestVideoFrameCallbackId&&(this._videoElement.cancelVideoFrameCallback(this._requestVideoFrameCallbackId),this._requestVideoFrameCallbackId=void 0),this._videoElement=void 0,this._emitter.all.clear())}async getImage(i){if(!this._videoElement)throw new Error("image repository is not inited!");this._videoElement.currentTime=a(i)}async play(){if(!this._videoElement)throw new Error("image repository is not inited!");return await this._videoElement.play()}stop(){if(!this._videoElement)throw new Error("image repository is not inited!");this.pause(),this._videoElement.currentTime=a(0)}pause(){if(!this._videoElement)throw new Error("image repository is not inited!");this._videoElement.pause()}on(i,t){return this._emitter.on(i,t),{off:()=>{this._emitter.off(i,t)}}}}return s.ImageRepository=n,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"}),s})({});
@@ -0,0 +1,114 @@
1
+ async function a(o) {
2
+ return new Promise((i, t) => {
3
+ const e = document.createElement("video");
4
+ e.muted = !0, e.crossOrigin = "anonymous", e.preload = "metadata", e.onloadedmetadata = () => {
5
+ e.width = e.videoWidth, e.height = e.videoHeight, i(e);
6
+ }, e.onerror = (r) => {
7
+ console.log("video load error", r), t(r);
8
+ }, e.src = o;
9
+ });
10
+ }
11
+ function d(o) {
12
+ return { all: o = o || /* @__PURE__ */ new Map(), on: function(i, t) {
13
+ var e = o.get(i);
14
+ e ? e.push(t) : o.set(i, [t]);
15
+ }, off: function(i, t) {
16
+ var e = o.get(i);
17
+ e && (t ? e.splice(e.indexOf(t) >>> 0, 1) : o.set(i, []));
18
+ }, emit: function(i, t) {
19
+ var e = o.get(i);
20
+ e && e.slice().map(function(r) {
21
+ r(t);
22
+ }), (e = o.get("*")) && e.slice().map(function(r) {
23
+ r(i, t);
24
+ });
25
+ } };
26
+ }
27
+ function s(o) {
28
+ return o / 1e6;
29
+ }
30
+ function l(o) {
31
+ return o * 1e6;
32
+ }
33
+ class n {
34
+ constructor(i) {
35
+ this.videoUrl = i;
36
+ }
37
+ static _repositories = {};
38
+ _isInited = !1;
39
+ _videoElement;
40
+ /**
41
+ * 视频DOM元素,使用它来渲染画布
42
+ */
43
+ get videoElement() {
44
+ if (!this._videoElement)
45
+ throw new Error("image repository is not inited!");
46
+ return this._videoElement;
47
+ }
48
+ _requestVideoFrameCallbackId;
49
+ _emitter = d();
50
+ static async getRepository(i) {
51
+ const t = i.toLowerCase().trim();
52
+ return this._repositories[t] || (this._repositories[t] = new n(t), await this._repositories[t].init()), this._repositories[t];
53
+ }
54
+ async init() {
55
+ if (this._isInited)
56
+ return;
57
+ this._isInited = !0, this._videoElement = await a(this.videoUrl);
58
+ const i = (t, e) => {
59
+ this._emitter.emit("requestFrame", {
60
+ frameTimestampInMicroseconds: l(e.mediaTime),
61
+ originalEvent: { now: t, metadata: e }
62
+ }), this._requestVideoFrameCallbackId = this._videoElement.requestVideoFrameCallback(i);
63
+ };
64
+ this._requestVideoFrameCallbackId = this._videoElement.requestVideoFrameCallback(i);
65
+ }
66
+ uninit() {
67
+ this._isInited && (this._isInited = !1, this._requestVideoFrameCallbackId && (this._videoElement.cancelVideoFrameCallback(
68
+ this._requestVideoFrameCallbackId
69
+ ), this._requestVideoFrameCallbackId = void 0), this._videoElement = void 0, this._emitter.all.clear());
70
+ }
71
+ /**
72
+ * 根据传入的微秒时间戳,获取指定位置的帧图片
73
+ * @param timstampInMicroseconds 微秒时间戳
74
+ */
75
+ async getImage(i) {
76
+ if (!this._videoElement)
77
+ throw new Error("image repository is not inited!");
78
+ this._videoElement.currentTime = s(i);
79
+ }
80
+ /**
81
+ * 开始播放连续帧图片
82
+ */
83
+ async play() {
84
+ if (!this._videoElement)
85
+ throw new Error("image repository is not inited!");
86
+ return await this._videoElement.play();
87
+ }
88
+ /**
89
+ * 停止播放
90
+ */
91
+ stop() {
92
+ if (!this._videoElement)
93
+ throw new Error("image repository is not inited!");
94
+ this.pause(), this._videoElement.currentTime = s(0);
95
+ }
96
+ /**
97
+ * 暂停播放
98
+ */
99
+ pause() {
100
+ if (!this._videoElement)
101
+ throw new Error("image repository is not inited!");
102
+ this._videoElement.pause();
103
+ }
104
+ on(i, t) {
105
+ return this._emitter.on(i, t), {
106
+ off: () => {
107
+ this._emitter.off(i, t);
108
+ }
109
+ };
110
+ }
111
+ }
112
+ export {
113
+ n as ImageRepository
114
+ };
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "roy-image-repository",
3
+ "author": "roy",
4
+ "version": "0.1.0",
5
+ "module": "./dist/roy-image-repository.js",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/roy-image-repository.js"
10
+ },
11
+ "./dist/": {
12
+ "import": "./dist/"
13
+ }
14
+ },
15
+ "types": "./dist/index.d.ts",
16
+ "devDependencies": {
17
+ "@types/jsdom": "^21.1.7",
18
+ "@types/node": "^24.0.10",
19
+ "@vitest/coverage-v8": "^3.2.4",
20
+ "copyfiles": "^2.4.1",
21
+ "dts-bundle-generator": "^9.5.1",
22
+ "eslint": "^9.30.1",
23
+ "eslint-config-prettier": "^10.1.5",
24
+ "eslint-plugin-prettier": "^5.5.1",
25
+ "husky": "^9.1.7",
26
+ "jiti": "^2.4.2",
27
+ "lint-staged": "^16.1.2",
28
+ "postcss": "^8.5.6",
29
+ "postcss-scss": "^4.0.9",
30
+ "prettier": "^3.6.2",
31
+ "rimraf": "^6.0.1",
32
+ "stylelint": "^16.21.1",
33
+ "stylelint-config-recommended": "^16.0.0",
34
+ "stylelint-config-sass-guidelines": "^12.1.0",
35
+ "stylelint-order": "^7.0.0",
36
+ "stylelint-prettier": "^5.0.3",
37
+ "ts-node": "^10.9.2",
38
+ "typescript": "^5.8.3",
39
+ "typescript-eslint": "^8.36.0",
40
+ "vite": "^7.0.3",
41
+ "vitest": "^3.2.4"
42
+ },
43
+ "dependencies": {
44
+ "mitt": "^3.0.1"
45
+ },
46
+ "scripts": {
47
+ "dev": "vite --host",
48
+ "build": "rm -drf build && tsc && vite build && dts-bundle-generator --config ./dts-bundle-generator.config.ts && copyfiles ./package.json build",
49
+ "test": "vitest",
50
+ "test:coverage": "vitest --coverage",
51
+ "lint:scripts": "eslint . --ext .ts",
52
+ "lint:styles": "stylelint ./**/*.{css,scss}",
53
+ "format:scripts": "prettier . --write",
54
+ "format:styles": "stylelint ./**/*.{css,scss} --fix",
55
+ "format": "npm run format:scripts && npm run format:styles",
56
+ "uninstall-husky": "npm uninstall husky --no-save && git config --unset core.hooksPath && npx rimraf .husky"
57
+ }
58
+ }