@vtx/player 0.0.3 → 0.0.6

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 (90) 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 +2 -2
  15. package/commitlint.config.js +10 -0
  16. package/package.json +98 -100
  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 +55 -0
  30. package/src/api/index.ts +43 -0
  31. package/{dist/types/api/types.d.ts → src/api/types.ts} +131 -117
  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 +13 -0
  35. package/src/components/bill-player/index.tsx +267 -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 +62 -0
  43. package/src/components/history-control/index.stories.tsx +130 -0
  44. package/src/components/history-control/index.tsx +368 -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 +206 -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 +75 -0
  52. package/src/components/live-control/index.less +65 -0
  53. package/src/components/live-control/index.stories.mdx +64 -0
  54. package/src/components/live-control/index.stories.tsx +61 -0
  55. package/src/components/live-control/index.tsx +274 -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 +318 -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/{dist/types/main.d.ts → src/main.ts} +9 -8
  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 +215 -0
  70. package/src/vite-env.d.ts +1 -0
  71. package/tsconfig.json +24 -0
  72. package/dist/index.d.ts +0 -223
  73. package/dist/index.es.js +0 -533
  74. package/dist/index.es.js.map +0 -1
  75. package/dist/index.umd.js +0 -533
  76. package/dist/index.umd.js.map +0 -1
  77. package/dist/types/api/fetch.d.ts +0 -12
  78. package/dist/types/api/index.d.ts +0 -16
  79. package/dist/types/components/bill-player/index.d.ts +0 -21
  80. package/dist/types/components/controls/index.d.ts +0 -52
  81. package/dist/types/components/history-control/index.d.ts +0 -39
  82. package/dist/types/components/history-player/index.d.ts +0 -31
  83. package/dist/types/components/live-channel-player/index.d.ts +0 -18
  84. package/dist/types/components/live-control/index.d.ts +0 -35
  85. package/dist/types/components/live-player/index.d.ts +0 -22
  86. package/dist/types/components/player/index.d.ts +0 -84
  87. package/dist/types/context/index.d.ts +0 -8
  88. package/dist/types/hooks/useSettings.d.ts +0 -9
  89. package/dist/types/icons/index.d.ts +0 -54
  90. package/dist/types/utils/index.d.ts +0 -60
@@ -0,0 +1,267 @@
1
+ import './index.less';
2
+
3
+ import { useRef } from 'react';
4
+
5
+ import HistoryControl, { HistoryControlHandle } from '../history-control';
6
+ import LiveControl, { LiveControlHandle } from '../live-control';
7
+ import { useRequest, useSetState } from 'ahooks';
8
+ import { Button, Checkbox, DatePicker, Form, Radio, RadioChangeEvent, Select, Tabs } from 'antd';
9
+ import moment from 'moment';
10
+
11
+ import { loadVideoInfo } from '@/api';
12
+ import { LoadVideoInfoParams } from '@/api/types';
13
+ import { TimeFormat } from '@/utils';
14
+
15
+ const { TabPane } = Tabs;
16
+
17
+ type HistoryFormData = {
18
+ /** 频道号 */
19
+ channelNum: string;
20
+ /** 开始时间,格式:2022-06-01 00:00:00 */
21
+ beginTime: string;
22
+ /** 结束时间,格式:2022-06-01 23:59:59 */
23
+ endTime: string;
24
+ };
25
+
26
+ interface State {
27
+ /** 日期选择器是否可用 */
28
+ datePickerDisabled: boolean;
29
+ /** 实时视频列表勾选状态 */
30
+ liveListState: Map<string, boolean>;
31
+ /** 设备ID */
32
+ deviceId: string;
33
+ }
34
+
35
+ interface BillPlayerProps {
36
+ /** 参数 */
37
+ params: LoadVideoInfoParams;
38
+ /** 宽度 */
39
+ width?: string | number;
40
+ /** 高度 */
41
+ height?: string | number;
42
+ /** 是否显示实时视频,默认为true */
43
+ live?: boolean;
44
+ /** 是否显示历史视频,默认为true */
45
+ history?: boolean;
46
+ /** 实时默认播放 */
47
+ defaultLivePlay?: boolean;
48
+ /** 历史默认播放 */
49
+ defaultHistoryPlay?: boolean;
50
+ }
51
+ export const BillPlayer = (props: BillPlayerProps) => {
52
+ const {
53
+ params,
54
+ live = true,
55
+ history = true,
56
+ height = '100%',
57
+ width = '100%',
58
+ defaultLivePlay = true,
59
+ } = props;
60
+ const [state, setState] = useSetState<State>({
61
+ datePickerDisabled: false,
62
+ liveListState: new Map(),
63
+ deviceId: '',
64
+ });
65
+ const { data } = useRequest(() => loadVideoInfo(params), {
66
+ refreshDeps: [params.billId],
67
+ onSuccess: (result) => {
68
+ if (defaultLivePlay) {
69
+ const livePlayer = liveRef.current;
70
+ if (livePlayer) {
71
+ const liveListState = new Map();
72
+ for (const item of result) {
73
+ liveListState.set(item.channelNum, true);
74
+ }
75
+ setState({ liveListState, deviceId: result[0].videoDeviceId });
76
+ livePlayer.multiLoad(
77
+ result.map((item) => ({
78
+ channelNum: item.channelNum,
79
+ deviceId: item.videoDeviceId,
80
+ }))
81
+ );
82
+ }
83
+ }
84
+ form.setFieldsValue({ channelNum: result[0].channelNum });
85
+ },
86
+ });
87
+ const [form] = Form.useForm();
88
+ const liveRef = useRef<LiveControlHandle>(null);
89
+ const historyRef = useRef<HistoryControlHandle>(null);
90
+ const getLivePanel = () => {
91
+ const list = data?.map((item) => (
92
+ <Checkbox
93
+ key={item.channelNum}
94
+ checked={state.liveListState.get(item.channelNum)}
95
+ onChange={(e) => {
96
+ const checked = e.target.checked;
97
+ const liveControl = liveRef.current;
98
+ if (liveControl) {
99
+ if (checked) {
100
+ liveControl.load({ ...item, deviceId: item.videoDeviceId });
101
+ } else {
102
+ liveControl.unLoad(item.channelNum);
103
+ }
104
+ }
105
+ }}
106
+ >
107
+ {item.channelName}
108
+ </Checkbox>
109
+ ));
110
+ return (
111
+ <div className="player-panel">
112
+ <div className="player-container">
113
+ <LiveControl
114
+ ref={liveRef}
115
+ onChannelChange={(channelsNum) => {
116
+ const liveListState = new Map(state.liveListState);
117
+ for (const channelNum of channelsNum) {
118
+ liveListState.set(channelNum, !liveListState.get(channelNum));
119
+ }
120
+ for (const item of liveListState) {
121
+ if (channelsNum.includes(item[0])) liveListState.set(item[0], true);
122
+ else liveListState.set(item[0], false);
123
+ }
124
+ setState({ liveListState });
125
+ }}
126
+ />
127
+ </div>
128
+ <div className="control-container">
129
+ <div className="header">视频通道</div>
130
+ <div className="list">{list}</div>
131
+ </div>
132
+ </div>
133
+ );
134
+ };
135
+ const onHistorySubmit = (values: HistoryFormData) => {
136
+ const historyControl = historyRef.current;
137
+ historyControl?.load({
138
+ channelNum: values.channelNum,
139
+ deviceId: state.deviceId,
140
+ beginTime: moment(values.beginTime).format(TimeFormat.params),
141
+ endTime: moment(values.endTime).format(TimeFormat.params),
142
+ });
143
+ };
144
+ const onTimeRadioChange = (e: RadioChangeEvent) => {
145
+ const value = e.target.value;
146
+ if (value === 'custom') {
147
+ setState({ datePickerDisabled: false });
148
+ } else {
149
+ setState({ datePickerDisabled: true });
150
+ if (value === 'today') {
151
+ form.setFieldsValue({
152
+ beginTime: moment().startOf('day'),
153
+ endTime: moment(),
154
+ });
155
+ }
156
+ if (value === 'yesterday') {
157
+ form.setFieldsValue({
158
+ beginTime: moment().subtract(1, 'day').startOf('day'),
159
+ endTime: moment().subtract(1, 'day').endOf('day'),
160
+ });
161
+ }
162
+ if (value === 'dayBeforeYesterday') {
163
+ form.setFieldsValue({
164
+ beginTime: moment().subtract(2, 'day').startOf('day'),
165
+ endTime: moment().subtract(2, 'day').endOf('day'),
166
+ });
167
+ }
168
+ }
169
+ };
170
+ const getHistoryPanel = () => {
171
+ return (
172
+ <div className="player-panel">
173
+ <div className="player-container">
174
+ <HistoryControl ref={historyRef} />
175
+ </div>
176
+ <div className="control-container">
177
+ <div className="header">查询视频</div>
178
+ <div className="form">
179
+ <Form
180
+ form={form}
181
+ name="history"
182
+ labelCol={{ span: 5 }}
183
+ wrapperCol={{ span: 19 }}
184
+ onFinish={onHistorySubmit}
185
+ requiredMark={false}
186
+ colon={false}
187
+ initialValues={{
188
+ beginTime: moment().subtract(1, 'day').startOf('day'),
189
+ endTime: moment().subtract(1, 'day').endOf('day'),
190
+ }}
191
+ autoComplete="off"
192
+ >
193
+ <Form.Item label="选择时段">
194
+ <Radio.Group
195
+ onChange={onTimeRadioChange}
196
+ defaultValue="custom"
197
+ className="time-radio-group"
198
+ >
199
+ <Radio value="today">当日</Radio>
200
+ <Radio value="yesterday">昨日</Radio>
201
+ <Radio value="dayBeforeYesterday">前日</Radio>
202
+ <Radio value="custom">自选</Radio>
203
+ </Radio.Group>
204
+ </Form.Item>
205
+ <Form.Item
206
+ label="开始时间"
207
+ name="beginTime"
208
+ rules={[{ required: true, message: '请输入开始时间' }]}
209
+ >
210
+ <DatePicker
211
+ style={{ width: '100%' }}
212
+ showTime
213
+ disabled={state.datePickerDisabled}
214
+ />
215
+ </Form.Item>
216
+ <Form.Item
217
+ label="结束时间"
218
+ name="endTime"
219
+ rules={[{ required: true, message: '请输入结束时间' }]}
220
+ >
221
+ <DatePicker showTime disabled={state.datePickerDisabled} />
222
+ </Form.Item>
223
+ <Form.Item
224
+ label="视频通道"
225
+ name="channelNum"
226
+ rules={[{ required: true, message: '请选择视频通道' }]}
227
+ >
228
+ <Select>
229
+ {data?.map((item) => (
230
+ <Select.Option
231
+ key={item.channelNum}
232
+ value={item.channelNum}
233
+ >
234
+ {item.channelName}
235
+ </Select.Option>
236
+ ))}
237
+ </Select>
238
+ </Form.Item>
239
+ <Form.Item wrapperCol={{ span: 24 }}>
240
+ <Button type="primary" htmlType="submit">
241
+ 查询
242
+ </Button>
243
+ </Form.Item>
244
+ </Form>
245
+ </div>
246
+ </div>
247
+ </div>
248
+ );
249
+ };
250
+ return (
251
+ <div className="vtx-bill-player" style={{ height, width }}>
252
+ {live && history && (
253
+ <Tabs defaultActiveKey="live" className="bill-tabs">
254
+ <TabPane tab="实时视频" key="live">
255
+ {getLivePanel()}
256
+ </TabPane>
257
+ <TabPane tab="历史视频" key="history">
258
+ {getHistoryPanel()}
259
+ </TabPane>
260
+ </Tabs>
261
+ )}
262
+ {live && !history && getLivePanel()}
263
+ {history && !live && getHistoryPanel()}
264
+ </div>
265
+ );
266
+ };
267
+ export default BillPlayer;
@@ -0,0 +1,182 @@
1
+ .player-control-popover {
2
+ border-radius: 2px;
3
+
4
+ .ant-popover-content {
5
+ background: rgb(0 0 0 / 75%);
6
+ box-shadow: 0 2px 8px 1px rgb(0 0 0 / 15%);
7
+
8
+ .ant-popover-arrow-content {
9
+ background: rgb(0 0 0 / 75%);
10
+
11
+ &::before {
12
+ background: none;
13
+ }
14
+ }
15
+
16
+ .ant-popover-inner {
17
+ background: transparent;
18
+
19
+ .ant-popover-inner-content {
20
+ padding: 0;
21
+
22
+ .volume-content {
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: center;
26
+ width: 44px;
27
+ padding: 8px 0;
28
+
29
+ .value {
30
+ font-size: 14px;
31
+ color: rgb(255 255 255 / 84.7%);
32
+ }
33
+
34
+ .ant-slider-vertical {
35
+ height: 62px;
36
+
37
+ .ant-slider-handle {
38
+ background-color: #1890ff;
39
+ border: solid 2px #1890ff;
40
+ }
41
+
42
+ .ant-slider-track {
43
+ background-color: #1890ff;
44
+ }
45
+ }
46
+ }
47
+
48
+ .speed-content {
49
+ .item {
50
+ padding: 2px 10px;
51
+ color: rgb(255 255 255 / 65%);
52
+ cursor: pointer;
53
+
54
+ &:hover {
55
+ background-color: rgb(255 255 255 / 25%);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ .vtx-player-speed-control {
65
+ line-height: 24px;
66
+ color: rgb(255 255 255 / 65%);
67
+ cursor: pointer;
68
+ }
69
+
70
+ .vtx-player-header {
71
+ display: flex;
72
+ align-items: center;
73
+ width: 100%;
74
+ height: 26px;
75
+ padding: 0 12px;
76
+ background-color: #131d27;
77
+
78
+ .title {
79
+ font-size: 14px;
80
+ color: white;
81
+ }
82
+
83
+ .close {
84
+ margin-left: auto;
85
+ }
86
+ }
87
+
88
+ .cloud-control-panel {
89
+ position: absolute;
90
+ top: 0;
91
+ width: 100%;
92
+ height: calc(100% - 24px);
93
+
94
+ .arrow {
95
+ position: absolute;
96
+ cursor: pointer;
97
+
98
+ &.up {
99
+ top: 16px;
100
+ left: 50%;
101
+ transform: translateX(-50%) rotate(180deg);
102
+ }
103
+
104
+ &.down {
105
+ bottom: 16px;
106
+ left: 50%;
107
+ transform: translateX(-50%);
108
+ }
109
+
110
+ &.left {
111
+ top: 50%;
112
+ left: 16px;
113
+ transform: translateY(-50%) rotate(90deg);
114
+ }
115
+
116
+ &.right {
117
+ top: 50%;
118
+ right: 16px;
119
+ transform: translateY(-50%) rotate(-90deg);
120
+ }
121
+
122
+ &.left-up {
123
+ top: 16px;
124
+ left: 16px;
125
+ transform: rotate(135deg);
126
+ }
127
+
128
+ &.left-down {
129
+ bottom: 16px;
130
+ left: 16px;
131
+ transform: rotate(45deg);
132
+ }
133
+
134
+ &.right-up {
135
+ top: 16px;
136
+ right: 16px;
137
+ transform: rotate(90deg);
138
+ }
139
+
140
+ &.right-down {
141
+ right: 16px;
142
+ bottom: 16px;
143
+ transform: rotate(-45deg);
144
+ }
145
+ }
146
+
147
+ .buttons {
148
+ position: absolute;
149
+ bottom: 80px;
150
+ left: 50%;
151
+ transform: translateX(-50%);
152
+
153
+ .control-button {
154
+ display: flex;
155
+ height: 32px;
156
+ line-height: 32px;
157
+ color: white;
158
+ cursor: default;
159
+ background-color: rgb(0 0 0 / 35%);
160
+ border: 1px solid rgb(0 0 0 / 15%);
161
+ border-radius: 2px;
162
+
163
+ > span {
164
+ height: 100%;
165
+ padding: 0 8px;
166
+ }
167
+
168
+ .text {
169
+ height: 100%;
170
+ padding: 0 8px;
171
+ white-space: nowrap;
172
+ border-right: 1px solid rgb(0 0 0 / 15%);
173
+ border-left: 1px solid rgb(0 0 0 / 15%);
174
+ }
175
+
176
+ .icon {
177
+ padding: 0 12px;
178
+ cursor: pointer;
179
+ }
180
+ }
181
+ }
182
+ }