@vtx/player 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.
Files changed (71) hide show
  1. package/.eslintignore +11 -0
  2. package/.eslintrc.js +31 -0
  3. package/.prettierignore +10 -0
  4. package/.prettierrc.js +22 -0
  5. package/.storybook/main.js +58 -0
  6. package/.storybook/manager.js +7 -0
  7. package/.storybook/preview-head.html +5 -0
  8. package/.storybook/preview.js +9 -0
  9. package/.storybook/proxy.js +6 -0
  10. package/.storybook/theme.js +8 -0
  11. package/.stylelintrc.json +13 -0
  12. package/.vscode/extensions.json +10 -0
  13. package/.vscode/settings.json +16 -0
  14. package/README.md +3 -0
  15. package/commitlint.config.js +10 -0
  16. package/package.json +98 -0
  17. package/public/h5player.min.js +311 -0
  18. package/public/playctrl1/AudioRenderer.js +225 -0
  19. package/public/playctrl1/DecodeWorker.js +711 -0
  20. package/public/playctrl1/Decoder.js +1 -0
  21. package/public/playctrl1/SuperRender_10.js +396 -0
  22. package/public/playctrl2/Decoder.js +21 -0
  23. package/public/playctrl2/Decoder.wasm +0 -0
  24. package/public/playctrl2/Decoder.worker.js +1 -0
  25. package/public/playctrl3/Decoder.js +21 -0
  26. package/public/playctrl3/Decoder.wasm +0 -0
  27. package/public/playctrl3/Decoder.worker.js +1 -0
  28. package/rollup.config.js +52 -0
  29. package/src/api/fetch.ts +50 -0
  30. package/src/api/index.ts +44 -0
  31. package/src/api/types.ts +141 -0
  32. package/src/components/bill-player/index.less +58 -0
  33. package/src/components/bill-player/index.stories.mdx +24 -0
  34. package/src/components/bill-player/index.stories.tsx +14 -0
  35. package/src/components/bill-player/index.tsx +269 -0
  36. package/src/components/controls/images/arrow.png +0 -0
  37. package/src/components/controls/images/error.png +0 -0
  38. package/src/components/controls/index.less +182 -0
  39. package/src/components/controls/index.tsx +312 -0
  40. package/src/components/history-control/images/collapse.png +0 -0
  41. package/src/components/history-control/index.less +211 -0
  42. package/src/components/history-control/index.stories.mdx +64 -0
  43. package/src/components/history-control/index.stories.tsx +140 -0
  44. package/src/components/history-control/index.tsx +344 -0
  45. package/src/components/history-player/index.less +98 -0
  46. package/src/components/history-player/index.stories.mdx +38 -0
  47. package/src/components/history-player/index.stories.tsx +12 -0
  48. package/src/components/history-player/index.tsx +205 -0
  49. package/src/components/live-channel-player/index.stories.mdx +29 -0
  50. package/src/components/live-channel-player/index.stories.tsx +11 -0
  51. package/src/components/live-channel-player/index.tsx +79 -0
  52. package/src/components/live-control/index.less +65 -0
  53. package/src/components/live-control/index.stories.mdx +66 -0
  54. package/src/components/live-control/index.stories.tsx +69 -0
  55. package/src/components/live-control/index.tsx +255 -0
  56. package/src/components/live-player/index.less +71 -0
  57. package/src/components/live-player/index.stories.mdx +35 -0
  58. package/src/components/live-player/index.stories.tsx +12 -0
  59. package/src/components/live-player/index.tsx +118 -0
  60. package/src/components/player/index.ts +293 -0
  61. package/src/context/index.ts +13 -0
  62. package/src/hooks/useSettings.tsx +14 -0
  63. package/src/icons/index.less +27 -0
  64. package/src/icons/index.tsx +518 -0
  65. package/src/main.ts +9 -0
  66. package/src/stories/intro.stories.mdx +16 -0
  67. package/src/typings/@vtx/utils/index.d.ts +27 -0
  68. package/src/typings/h5player.d.ts +133 -0
  69. package/src/utils/index.ts +177 -0
  70. package/src/vite-env.d.ts +1 -0
  71. package/tsconfig.json +24 -0
@@ -0,0 +1,133 @@
1
+ import { CSSProperties } from 'react';
2
+
3
+ declare global {
4
+ declare class JSPlugin {
5
+ constructor(params: JSPluginConstructorParams);
6
+ /** 设置回调方法 */
7
+ JS_SetWindowControlCallback(params: JSPluginCallbackParams);
8
+ /**
9
+ * 开始播放
10
+ * @param url 流媒体地址
11
+ * @param config 播放参数
12
+ * @param windowIndex 当前窗口下标
13
+ * @param startTime 开始时间
14
+ * @param endTime 结束时间
15
+ */
16
+ JS_Play(
17
+ url: string,
18
+ config: PlayConfig,
19
+ windowIndex: number,
20
+ startTime?: string,
21
+ endTime?: string
22
+ ): Promise<void>;
23
+
24
+ /**
25
+ * 停止播放
26
+ * @param windowIndex 窗口下标
27
+ */
28
+ JS_Stop(windowIndex: number): Promise<void>;
29
+ /**
30
+ * 截图
31
+ * @param windowIndex 当前窗口
32
+ * @param fileName 文件名称
33
+ * @param fileType 文件类型
34
+ * @param callback 回调
35
+ */
36
+ JS_CapturePicture(
37
+ windowIndex: number,
38
+ fileName: string,
39
+ fileType: 'JPEG' | 'PNG',
40
+ callback?: () => void
41
+ );
42
+ /**
43
+ * 设置窗口大小
44
+ * @param iWidth 宽度
45
+ * @param iHeight 高度
46
+ */
47
+ JS_Resize(iWidth?: number, iHeight?: number);
48
+ /**
49
+ * 设置音量
50
+ * @param windowIndex 当前窗口
51
+ * @param value 音量
52
+ */
53
+ JS_SetVolume(windowIndex: number, value: number);
54
+ /**
55
+ * 跳转到
56
+ * @param windowIndex 当前窗口
57
+ * @param startTime 开始时间
58
+ * @param endTime 结束时间
59
+ */
60
+ JS_Seek(windowIndex: number, startTime: string, endTime: string): Promise<void>;
61
+ /**
62
+ * 暂停播放
63
+ * @param windowIndex 当前窗口
64
+ */
65
+ JS_Pause(windowIndex: number): Promise<void>;
66
+ /**
67
+ * 恢复播放
68
+ * @param windowIndex 当前窗口
69
+ */
70
+ JS_Resume(windowIndex: number): Promise<void>;
71
+ /**
72
+ * 调节播放倍速为当前播放速度的2倍,最大为8倍
73
+ * @param windowIndex 当前窗口
74
+ */
75
+ JS_Fast(windowIndex: number): Promise<void>;
76
+ /**
77
+ * 调节播放倍速为当前播放速度的1/2倍,最小为1/8倍
78
+ * @param windowIndex 当前窗口
79
+ */
80
+ JS_Slow(windowIndex: number): Promise<void>;
81
+ /**
82
+ * 开始对讲
83
+ * @param url 对讲地址
84
+ */
85
+ JS_StartTalk(url: string): Promise<void>;
86
+ /** 结束对讲 */
87
+ JS_StopTalk(): Promise<void>;
88
+ }
89
+ }
90
+ type JSPluginConstructorParams = {
91
+ /** 容器ID */
92
+ szId: string;
93
+ /** h5player.min.js引用路径 */
94
+ szBasePath: string;
95
+ /** 最大分屏数 */
96
+ iMaxSplit: number;
97
+ /** 当前分屏数 */
98
+ iCurrentSplit: number;
99
+ /** 开启调试模式 */
100
+ openDebug?: boolean;
101
+ /** 样式 */
102
+ oStyle?: CSSProperties;
103
+ /** 宽度 */
104
+ iWidth?: number;
105
+ /** 高度 */
106
+ iHeight?: number;
107
+ };
108
+
109
+ type JSPluginCallbackParams = {
110
+ /** 插件选中窗口回调 */
111
+ windowEventSelect: (index: number) => void;
112
+ /** 插件错误回调 */
113
+ pluginErrorHandler: (index: number, code: string, error: object) => void;
114
+ /** 鼠标移过回调 */
115
+ windowEventOver: (index: number) => void;
116
+ /** 鼠标移出回调 */
117
+ windowEventOut: (index: number) => void;
118
+ /** 鼠标mouseup事件回调 */
119
+ windowEventUp: (index: number) => void;
120
+ /** 全屏切换回调 */
121
+ windowFullCcreenChange: (full: boolean) => void;
122
+ /** 首帧显示回调 */
123
+ firstFrameDisplay: (index: number, width: number, height: number) => void;
124
+ /** 性能不足回调 */
125
+ performanceLack: () => void;
126
+ };
127
+
128
+ type PlayConfig = {
129
+ /** 播放地址 */
130
+ playURL: string;
131
+ /** 0=普通模式; 1=高级模式 默认为0 */
132
+ mode: 0 | 1;
133
+ };
@@ -0,0 +1,177 @@
1
+ import { Base64 } from 'js-base64';
2
+ import moment from 'moment';
3
+
4
+ import { GetHistoryUrlResp } from '@/api/types';
5
+ import { UrlsTableItemType } from '@/components/history-control';
6
+ import { VideoType } from '@/components/player';
7
+
8
+ /** 时间格式枚举 */
9
+ export enum TimeFormat {
10
+ default = 'YYYY-MM-DDTHH:mm:ss',
11
+ params = 'YYYY-MM-DD HH:mm:ss',
12
+ url = 'YYYYMMDDTHHmmss',
13
+ }
14
+
15
+ /** 生成随机ID */
16
+ export const guidGenerator = () => {
17
+ const S4 = function () {
18
+ return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
19
+ };
20
+ return S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4();
21
+ };
22
+
23
+ type PlayerParams = {
24
+ /** 视频流地址 */
25
+ url: string;
26
+ /** 视频流格式 */
27
+ type: VideoType;
28
+ };
29
+ /**
30
+ * 获取视频直播地址及格式
31
+ * @param url
32
+ * @returns
33
+ */
34
+ export const getPlayerParams = (
35
+ url: string,
36
+ live: boolean,
37
+ startTime?: moment.MomentInput,
38
+ endTime?: moment.MomentInput
39
+ ): PlayerParams => {
40
+ let playerUrl = url;
41
+ let playerType: VideoType = 'flv';
42
+ if (url.startsWith('ws://')) {
43
+ playerType = 'hk_ws';
44
+ if (live) {
45
+ playerUrl = url;
46
+ } else {
47
+ playerUrl = url.split('?')[0];
48
+ }
49
+ }
50
+ if (url.startsWith('rtsp://')) {
51
+ playerType = 'flv';
52
+ if (live) {
53
+ playerUrl = `https://kanbandev.cloudhw.cn:8446/cloud/vic/convert/flv/live.flv?url=${Base64.encode(
54
+ url
55
+ )}`;
56
+ } else {
57
+ playerUrl = `https://kanbandev.cloudhw.cn:8446/cloud/vic/convert/flv/live.flv?url=${Base64.encode(
58
+ getFlvListUrl(url, startTime, endTime)
59
+ )}`;
60
+ }
61
+ }
62
+ if (url.endsWith('live.m3u8')) {
63
+ playerUrl = url;
64
+ playerType = 'hls';
65
+ }
66
+ return { url: playerUrl, type: playerType };
67
+ };
68
+
69
+ /**
70
+ * 获取历史回放表格数据
71
+ * @param data
72
+ * @returns
73
+ */
74
+ export const getUrlTableData = (data: GetHistoryUrlResp): UrlsTableItemType[] => {
75
+ const result: UrlsTableItemType[] = data.list.map((item, i) => {
76
+ const beginTime = moment(item.beginTime);
77
+ const endTime = moment(item.endTime);
78
+ const totalSeconds = moment(endTime).diff(moment(beginTime), 'seconds');
79
+ return {
80
+ index: i + 1,
81
+ deviceName: data.deviceName,
82
+ channelName: data.channelName,
83
+ beginTime: beginTime.format(TimeFormat.params),
84
+ endTime: endTime.format(TimeFormat.params),
85
+ size: bytesToMegaBytes(item.size),
86
+ duration: secondsToString(totalSeconds),
87
+ downloadUrl: '',
88
+ url: item.playbackUrl || '',
89
+ };
90
+ });
91
+ return result;
92
+ };
93
+
94
+ /**
95
+ * bytes转换mb
96
+ * @param bytes
97
+ * @returns
98
+ */
99
+ const bytesToMegaBytes = (bytes: number) => `${(bytes / 1024 ** 2).toFixed(2)}MB`;
100
+
101
+ /**
102
+ * 秒数=>0时0分0秒
103
+ * @param total
104
+ * @returns
105
+ */
106
+ const secondsToString = (total: number) => {
107
+ const hour = Math.floor(total / 3600);
108
+ const minute = Math.floor((total % 3600) / 60);
109
+ const second = Math.floor(total % 60);
110
+ const result = `${hour > 0 ? hour + '小时' : ''}${minute > 0 ? minute + '分' : ''}${
111
+ second > 0 ? second + '秒' : ''
112
+ }`;
113
+ return result;
114
+ };
115
+
116
+ /**
117
+ * 秒数=>00:00:00
118
+ * @param total
119
+ * @returns
120
+ */
121
+ export const secondsToTime = (total: number) => {
122
+ const hour = Math.floor(total / 3600);
123
+ const minute = Math.floor((total % 3600) / 60);
124
+ const second = Math.floor(total % 60);
125
+ const result = `${hour >= 10 ? hour : '0' + hour}:${minute >= 10 ? minute : '0' + minute}:${
126
+ second >= 10 ? second : '0' + second
127
+ }`;
128
+ return result;
129
+ };
130
+
131
+ /**
132
+ * 获取海康时间参数
133
+ * @param time 时间
134
+ * @returns
135
+ */
136
+ export const getHKTimeString = (time: moment.MomentInput) => {
137
+ return moment(time).format(TimeFormat.default) + 'Z';
138
+ };
139
+
140
+ /**
141
+ * 获取海康分段播放地址
142
+ * @param totalUrl 总播放地址
143
+ * @param startTime 开始时间
144
+ * @param endTime 结束时间
145
+ * @returns
146
+ */
147
+ export const getHKListUrl = (
148
+ totalUrl: string,
149
+ startTime: moment.MomentInput,
150
+ endTime: moment.MomentInput
151
+ ) => {
152
+ const [url, query] = totalUrl.split('?');
153
+ const urlParams = new URLSearchParams(query);
154
+ urlParams.set('beginTime', getHKTimeString(startTime));
155
+ urlParams.set('endTime', getHKTimeString(endTime));
156
+ return `${url}?${urlParams.toString()}`;
157
+ };
158
+
159
+ /**
160
+ *
161
+ * 获取flv格式分段播放地址
162
+ * @param totalUrl 总播放地址
163
+ * @param startTime 开始时间
164
+ * @param endTime 结束时间
165
+ * @returns
166
+ */
167
+ export const getFlvListUrl = (
168
+ totalUrl: string,
169
+ startTime: moment.MomentInput,
170
+ endTime: moment.MomentInput
171
+ ) => {
172
+ const [url, query] = totalUrl.split('?');
173
+ const urlParams = new URLSearchParams(query);
174
+ urlParams.set('beginTime', moment(startTime).format(TimeFormat.url));
175
+ urlParams.set('endTime', moment(endTime).format(TimeFormat.url));
176
+ return `${url}?${urlParams.toString()}`;
177
+ };
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
package/tsconfig.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "module": "esnext",
5
+ "jsx": "react-jsx",
6
+ "declaration": true,
7
+ "declarationDir": "types",
8
+ "sourceMap": true,
9
+ "outDir": "dist",
10
+ "strict": true,
11
+ "moduleResolution": "node",
12
+ "allowSyntheticDefaultImports": true,
13
+ "esModuleInterop": true,
14
+ "skipLibCheck": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "downlevelIteration": true,
17
+ "emitDeclarationOnly": true,
18
+ "baseUrl": "./",
19
+ "paths": {
20
+ "@/*": ["src/*"]
21
+ }
22
+ },
23
+ "exclude": ["src/**/*.stories.tsx"],
24
+ }