@vtx/player 0.0.1 → 0.0.2
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/index.es.js +533 -0
- package/lib/index.es.js.map +1 -0
- package/lib/index.umd.js +533 -0
- package/lib/index.umd.js.map +1 -0
- package/lib/types/api/fetch.d.ts +12 -0
- package/lib/types/api/index.d.ts +16 -0
- package/{src/api/types.ts → lib/types/api/types.d.ts} +7 -31
- package/lib/types/components/bill-player/index.d.ts +21 -0
- package/lib/types/components/controls/index.d.ts +52 -0
- package/lib/types/components/history-control/index.d.ts +39 -0
- package/lib/types/components/history-player/index.d.ts +31 -0
- package/lib/types/components/live-channel-player/index.d.ts +18 -0
- package/lib/types/components/live-control/index.d.ts +35 -0
- package/lib/types/components/live-player/index.d.ts +22 -0
- package/lib/types/components/player/index.d.ts +84 -0
- package/lib/types/context/index.d.ts +8 -0
- package/lib/types/hooks/useSettings.d.ts +9 -0
- package/lib/types/icons/index.d.ts +54 -0
- package/{src/main.ts → lib/types/main.d.ts} +0 -1
- package/lib/types/utils/index.d.ts +60 -0
- package/package.json +7 -5
- package/.eslintignore +0 -11
- package/.eslintrc.js +0 -31
- package/.prettierignore +0 -10
- package/.prettierrc.js +0 -22
- package/.storybook/main.js +0 -58
- package/.storybook/manager.js +0 -7
- package/.storybook/preview-head.html +0 -5
- package/.storybook/preview.js +0 -9
- package/.storybook/proxy.js +0 -6
- package/.storybook/theme.js +0 -8
- package/.stylelintrc.json +0 -13
- package/.vscode/extensions.json +0 -10
- package/.vscode/settings.json +0 -16
- package/commitlint.config.js +0 -10
- package/public/h5player.min.js +0 -311
- package/public/playctrl1/AudioRenderer.js +0 -225
- package/public/playctrl1/DecodeWorker.js +0 -711
- package/public/playctrl1/Decoder.js +0 -1
- package/public/playctrl1/SuperRender_10.js +0 -396
- package/public/playctrl2/Decoder.js +0 -21
- package/public/playctrl2/Decoder.wasm +0 -0
- package/public/playctrl2/Decoder.worker.js +0 -1
- package/public/playctrl3/Decoder.js +0 -21
- package/public/playctrl3/Decoder.wasm +0 -0
- package/public/playctrl3/Decoder.worker.js +0 -1
- package/rollup.config.js +0 -52
- package/src/api/fetch.ts +0 -50
- package/src/api/index.ts +0 -44
- package/src/components/bill-player/index.less +0 -58
- package/src/components/bill-player/index.stories.mdx +0 -24
- package/src/components/bill-player/index.stories.tsx +0 -14
- package/src/components/bill-player/index.tsx +0 -269
- package/src/components/controls/images/arrow.png +0 -0
- package/src/components/controls/images/error.png +0 -0
- package/src/components/controls/index.less +0 -182
- package/src/components/controls/index.tsx +0 -312
- package/src/components/history-control/images/collapse.png +0 -0
- package/src/components/history-control/index.less +0 -211
- package/src/components/history-control/index.stories.mdx +0 -64
- package/src/components/history-control/index.stories.tsx +0 -140
- package/src/components/history-control/index.tsx +0 -344
- package/src/components/history-player/index.less +0 -98
- package/src/components/history-player/index.stories.mdx +0 -38
- package/src/components/history-player/index.stories.tsx +0 -12
- package/src/components/history-player/index.tsx +0 -205
- package/src/components/live-channel-player/index.stories.mdx +0 -29
- package/src/components/live-channel-player/index.stories.tsx +0 -11
- package/src/components/live-channel-player/index.tsx +0 -79
- package/src/components/live-control/index.less +0 -65
- package/src/components/live-control/index.stories.mdx +0 -66
- package/src/components/live-control/index.stories.tsx +0 -69
- package/src/components/live-control/index.tsx +0 -255
- package/src/components/live-player/index.less +0 -71
- package/src/components/live-player/index.stories.mdx +0 -35
- package/src/components/live-player/index.stories.tsx +0 -12
- package/src/components/live-player/index.tsx +0 -118
- package/src/components/player/index.ts +0 -293
- package/src/context/index.ts +0 -13
- package/src/hooks/useSettings.tsx +0 -14
- package/src/icons/index.less +0 -27
- package/src/icons/index.tsx +0 -518
- package/src/stories/intro.stories.mdx +0 -16
- package/src/typings/@vtx/utils/index.d.ts +0 -27
- package/src/typings/h5player.d.ts +0 -133
- package/src/utils/index.ts +0 -177
- package/src/vite-env.d.ts +0 -1
- package/tsconfig.json +0 -24
|
@@ -1,205 +0,0 @@
|
|
|
1
|
-
import './index.less';
|
|
2
|
-
|
|
3
|
-
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
|
|
4
|
-
|
|
5
|
-
import { useFullscreen, useSetState } from 'ahooks';
|
|
6
|
-
import { Slider, Space } from 'antd';
|
|
7
|
-
import moment from 'moment';
|
|
8
|
-
|
|
9
|
-
import { LoadingState, SpeedControl, VolumeControl } from '@/components/controls';
|
|
10
|
-
import Player, { VideoType } from '@/components/player';
|
|
11
|
-
import { CaptureIcon, ExitFullScreenIcon, FullScreenIcon, PauseIcon, PlayIcon } from '@/icons';
|
|
12
|
-
import { TimeFormat, guidGenerator, secondsToTime } from '@/utils';
|
|
13
|
-
|
|
14
|
-
export type HistoryPlayerHandle = {
|
|
15
|
-
/**
|
|
16
|
-
* 跳转,目前仅支持海康视频跳转
|
|
17
|
-
*/
|
|
18
|
-
seekTo: (time: string) => Promise<void>;
|
|
19
|
-
};
|
|
20
|
-
interface VtxPlayerProps {
|
|
21
|
-
/** 视频流地址 */
|
|
22
|
-
url: string;
|
|
23
|
-
/** 视频流格式,如果为空则根据url自行判断 */
|
|
24
|
-
type?: VideoType;
|
|
25
|
-
/** 开始时间,格式为:YYYY-MM-DD HH:mm:ss */
|
|
26
|
-
startTime: string;
|
|
27
|
-
/** 结束时间,格式为:YYYY-MM-DD HH:mm:ss */
|
|
28
|
-
endTime: string;
|
|
29
|
-
/** 宽度 */
|
|
30
|
-
width?: number;
|
|
31
|
-
/** 高度 */
|
|
32
|
-
height?: number;
|
|
33
|
-
/** 截图文件名 */
|
|
34
|
-
captureName?: string;
|
|
35
|
-
/** 控制条bottom */
|
|
36
|
-
controlBottom?: number;
|
|
37
|
-
/** 播放器进度回调,time:YYYY-MM-DD HH:mm:ss */
|
|
38
|
-
onTimeChange?: (time: string) => void;
|
|
39
|
-
}
|
|
40
|
-
type State = {
|
|
41
|
-
/** 播放状态 */
|
|
42
|
-
play: boolean;
|
|
43
|
-
/** 错误状态 */
|
|
44
|
-
error: boolean;
|
|
45
|
-
/** 加载状态 */
|
|
46
|
-
loading: boolean;
|
|
47
|
-
/** 音量 */
|
|
48
|
-
volume: number;
|
|
49
|
-
/** id */
|
|
50
|
-
id: string;
|
|
51
|
-
/** 当前时间 */
|
|
52
|
-
currentTime: number;
|
|
53
|
-
/** 进度 */
|
|
54
|
-
progress: number;
|
|
55
|
-
/** 控制器状态 */
|
|
56
|
-
controls: {
|
|
57
|
-
/** 进度条是否可用 */
|
|
58
|
-
progress: boolean;
|
|
59
|
-
};
|
|
60
|
-
};
|
|
61
|
-
export const HistoryPlayer = forwardRef<HistoryPlayerHandle, VtxPlayerProps>((props, ref) => {
|
|
62
|
-
const {
|
|
63
|
-
url,
|
|
64
|
-
type,
|
|
65
|
-
width = '100%',
|
|
66
|
-
height = '100%',
|
|
67
|
-
captureName,
|
|
68
|
-
controlBottom = 0,
|
|
69
|
-
startTime,
|
|
70
|
-
endTime,
|
|
71
|
-
onTimeChange,
|
|
72
|
-
} = props;
|
|
73
|
-
const totalTime = moment(endTime).diff(moment(startTime), 'seconds');
|
|
74
|
-
const containerRef = useRef<HTMLDivElement>(null);
|
|
75
|
-
const wrapRef = useRef<HTMLDivElement>(null);
|
|
76
|
-
const controlsRef = useRef<HTMLDivElement>(null);
|
|
77
|
-
const playerRef = useRef<Player>();
|
|
78
|
-
const [isFullscreen, { toggleFullscreen }] = useFullscreen(wrapRef);
|
|
79
|
-
const [state, setState] = useSetState<State>({
|
|
80
|
-
play: false,
|
|
81
|
-
error: false,
|
|
82
|
-
loading: false,
|
|
83
|
-
id: 'vtx_hk_player_' + guidGenerator(),
|
|
84
|
-
volume: 0,
|
|
85
|
-
currentTime: 0,
|
|
86
|
-
progress: 0,
|
|
87
|
-
controls: {
|
|
88
|
-
progress: true,
|
|
89
|
-
},
|
|
90
|
-
});
|
|
91
|
-
useImperativeHandle(ref, () => {
|
|
92
|
-
return {
|
|
93
|
-
seekTo: (time) => {
|
|
94
|
-
const player = playerRef.current;
|
|
95
|
-
if (player) {
|
|
96
|
-
const currentTime = moment(time).diff(moment(startTime), 'seconds');
|
|
97
|
-
return player.seekTo(currentTime);
|
|
98
|
-
} else {
|
|
99
|
-
return Promise.reject();
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
});
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
const container = containerRef.current;
|
|
106
|
-
if (!url || !container) return;
|
|
107
|
-
const player = new Player({ url, container, live: false, startTime, endTime, type });
|
|
108
|
-
playerRef.current = player;
|
|
109
|
-
setState({ loading: true, controls: { progress: player.type === 'hk_ws' } });
|
|
110
|
-
console.log(player.type);
|
|
111
|
-
player
|
|
112
|
-
.playBack()
|
|
113
|
-
.then(() => setState({ play: true, error: false }))
|
|
114
|
-
.catch(() => setState({ error: true }))
|
|
115
|
-
.finally(() => setState({ loading: false }));
|
|
116
|
-
|
|
117
|
-
player.onTimeUpdate((currentTime) => {
|
|
118
|
-
setState({ currentTime, progress: Math.floor((currentTime / totalTime) * 100) });
|
|
119
|
-
onTimeChange &&
|
|
120
|
-
onTimeChange(
|
|
121
|
-
moment(startTime).add(currentTime, 'seconds').format(TimeFormat.default)
|
|
122
|
-
);
|
|
123
|
-
});
|
|
124
|
-
return () => {
|
|
125
|
-
player.destroy();
|
|
126
|
-
setState({ error: false, loading: false, play: false });
|
|
127
|
-
};
|
|
128
|
-
}, [url, startTime, endTime]);
|
|
129
|
-
/** 截图方法 */
|
|
130
|
-
const handleCapture: React.MouseEventHandler = (e) => {
|
|
131
|
-
const player = playerRef.current;
|
|
132
|
-
player && player.capture(captureName);
|
|
133
|
-
e.stopPropagation();
|
|
134
|
-
};
|
|
135
|
-
/** 全屏方法 */
|
|
136
|
-
const handleFullScreen: React.MouseEventHandler = (e) => {
|
|
137
|
-
toggleFullscreen();
|
|
138
|
-
const player = playerRef.current;
|
|
139
|
-
player && player.resize();
|
|
140
|
-
e.stopPropagation();
|
|
141
|
-
};
|
|
142
|
-
/** 进度条控制器 */
|
|
143
|
-
const handleSlider = (value: number) => {
|
|
144
|
-
const currentTime = Math.floor((totalTime * value) / 100);
|
|
145
|
-
const player = playerRef.current;
|
|
146
|
-
setState({ progress: value });
|
|
147
|
-
player?.seekTo(currentTime);
|
|
148
|
-
};
|
|
149
|
-
/** 暂停方法 */
|
|
150
|
-
const handlePause = () => {
|
|
151
|
-
const player = playerRef.current;
|
|
152
|
-
player?.pause(() => {
|
|
153
|
-
setState({ play: false });
|
|
154
|
-
});
|
|
155
|
-
};
|
|
156
|
-
/** 恢复播放方法 */
|
|
157
|
-
const handleResume = () => {
|
|
158
|
-
const player = playerRef.current;
|
|
159
|
-
player?.resume(() => {
|
|
160
|
-
setState({ play: true });
|
|
161
|
-
});
|
|
162
|
-
};
|
|
163
|
-
return (
|
|
164
|
-
<div className="vtx-history-player" ref={wrapRef} style={{ width, height }}>
|
|
165
|
-
<div ref={containerRef} style={{ height: '100%', width: '100%' }} id={state.id} />
|
|
166
|
-
{/* {state.error && <ErrorState onClick={handleRetry} />} */}
|
|
167
|
-
{state.loading && <LoadingState />}
|
|
168
|
-
<div className="controls" ref={controlsRef} style={{ bottom: controlBottom }}>
|
|
169
|
-
{state.play ? (
|
|
170
|
-
<PauseIcon onClick={handlePause} />
|
|
171
|
-
) : (
|
|
172
|
-
<PlayIcon onClick={handleResume} />
|
|
173
|
-
)}
|
|
174
|
-
<div className="time">
|
|
175
|
-
<span className="current">{secondsToTime(state.currentTime)}</span>
|
|
176
|
-
<span className="total">/{secondsToTime(totalTime)}</span>
|
|
177
|
-
</div>
|
|
178
|
-
<div className="slider">
|
|
179
|
-
<Slider
|
|
180
|
-
disabled={!state.controls.progress}
|
|
181
|
-
tipFormatter={null}
|
|
182
|
-
onChange={handleSlider}
|
|
183
|
-
value={state.progress}
|
|
184
|
-
/>
|
|
185
|
-
</div>
|
|
186
|
-
<Space className="right" size={12} align="center">
|
|
187
|
-
<VolumeControl
|
|
188
|
-
player={playerRef.current}
|
|
189
|
-
defaultValue={0}
|
|
190
|
-
container={controlsRef.current}
|
|
191
|
-
/>
|
|
192
|
-
<SpeedControl player={playerRef.current} container={controlsRef.current} />
|
|
193
|
-
<CaptureIcon onClick={handleCapture} />
|
|
194
|
-
{isFullscreen ? (
|
|
195
|
-
<ExitFullScreenIcon onClick={handleFullScreen} />
|
|
196
|
-
) : (
|
|
197
|
-
<FullScreenIcon onClick={handleFullScreen} />
|
|
198
|
-
)}
|
|
199
|
-
</Space>
|
|
200
|
-
</div>
|
|
201
|
-
</div>
|
|
202
|
-
);
|
|
203
|
-
});
|
|
204
|
-
HistoryPlayer.displayName = 'HistoryPlayer';
|
|
205
|
-
export default HistoryPlayer;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import LiveChannelPlayer from '.';
|
|
2
|
-
import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
|
|
3
|
-
import { Alert, Space } from 'antd';
|
|
4
|
-
|
|
5
|
-
import * as stories from './index.stories';
|
|
6
|
-
|
|
7
|
-
<Meta title="组件/实时播放器-通道ID" component={LiveChannelPlayer} />
|
|
8
|
-
|
|
9
|
-
# 实时播放器-通道 ID
|
|
10
|
-
|
|
11
|
-
## 引入
|
|
12
|
-
|
|
13
|
-
```js
|
|
14
|
-
import { LiveChannelPlayer } from '@vtx/player';
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## 说明
|
|
18
|
-
|
|
19
|
-
基于 LivePlayer,参数变为 videoChannelId,在组件内部进行数据请求获得视频流地址。
|
|
20
|
-
|
|
21
|
-
## 属性
|
|
22
|
-
|
|
23
|
-
<ArgsTable of={LiveChannelPlayer} />
|
|
24
|
-
|
|
25
|
-
## 例子
|
|
26
|
-
|
|
27
|
-
<Canvas>
|
|
28
|
-
<Story name="实时播放器-通道ID" story={stories.Default} />
|
|
29
|
-
</Canvas>
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import LiveChannelPlayer from '.';
|
|
2
|
-
import { ComponentStory } from '@storybook/react';
|
|
3
|
-
|
|
4
|
-
const Template: ComponentStory<typeof LiveChannelPlayer> = (args) => <LiveChannelPlayer {...args} />;
|
|
5
|
-
|
|
6
|
-
export const Default = Template.bind({});
|
|
7
|
-
Default.args = {
|
|
8
|
-
width: 1000,
|
|
9
|
-
height: 600,
|
|
10
|
-
};
|
|
11
|
-
export default Default;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { useEffect, useState } from 'react';
|
|
2
|
-
|
|
3
|
-
import { CloudControlPanelProps, CloudControlType } from '../controls';
|
|
4
|
-
import LivePlayer from '../live-player';
|
|
5
|
-
import { useRequest } from 'ahooks';
|
|
6
|
-
|
|
7
|
-
import { getPreviewUrl, loadVideoChannel } from '@/api';
|
|
8
|
-
import { GetPreviewUrlResp } from '@/api/types';
|
|
9
|
-
|
|
10
|
-
interface LiveChannelPlayerProps {
|
|
11
|
-
/** 通道ID */
|
|
12
|
-
channelId: string;
|
|
13
|
-
/** 租户ID */
|
|
14
|
-
tenantId: string;
|
|
15
|
-
/** 宽度 */
|
|
16
|
-
width?: number;
|
|
17
|
-
/** 高度 */
|
|
18
|
-
height?: number;
|
|
19
|
-
/** 视频流格式,如果为空则根据url自行判断 */
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* 基于通道ID的实时播放器
|
|
23
|
-
* @param props
|
|
24
|
-
* @returns
|
|
25
|
-
*/
|
|
26
|
-
export const LiveChannelPlayer = (props: LiveChannelPlayerProps) => {
|
|
27
|
-
const { channelId, tenantId, width, height } = props;
|
|
28
|
-
const [params, setParams] = useState<GetPreviewUrlResp>();
|
|
29
|
-
const { runAsync: getChannelInfo } = useRequest(loadVideoChannel, { manual: true });
|
|
30
|
-
const { runAsync: getVideoUrl } = useRequest(getPreviewUrl, { manual: true });
|
|
31
|
-
const getVideoInfo = async () => {
|
|
32
|
-
const channel = await getChannelInfo(channelId, tenantId);
|
|
33
|
-
const videoInfo = await getVideoUrl({
|
|
34
|
-
tenantId,
|
|
35
|
-
channelNum: channel.channelNum,
|
|
36
|
-
deviceId: channel.videoDeviceId,
|
|
37
|
-
});
|
|
38
|
-
setParams(videoInfo);
|
|
39
|
-
};
|
|
40
|
-
const getCloudParams = (): CloudControlPanelProps | undefined => {
|
|
41
|
-
const ptzType = params?.ptzType;
|
|
42
|
-
if (ptzType) {
|
|
43
|
-
let type: CloudControlType = 'none';
|
|
44
|
-
if (ptzType === 1) {
|
|
45
|
-
type = 'all';
|
|
46
|
-
} else if (ptzType === 2) {
|
|
47
|
-
type = 'onlyFocus';
|
|
48
|
-
} else if (ptzType === 3) {
|
|
49
|
-
type = 'onlyRotate';
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
query: {
|
|
53
|
-
tenantId,
|
|
54
|
-
channelNum: params.channelNum,
|
|
55
|
-
deviceId: params.deviceId,
|
|
56
|
-
},
|
|
57
|
-
type,
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
if (channelId && tenantId) getVideoInfo();
|
|
63
|
-
}, [channelId]);
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
params && (
|
|
67
|
-
<LivePlayer
|
|
68
|
-
url={params.url}
|
|
69
|
-
width={width}
|
|
70
|
-
height={height}
|
|
71
|
-
talkUrl={params.beenHasVideo ? params.apiUrl : ''}
|
|
72
|
-
captureName={`${params.deviceName}-${params.channelName}`}
|
|
73
|
-
cloudParams={getCloudParams()}
|
|
74
|
-
/>
|
|
75
|
-
)
|
|
76
|
-
);
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
export default LiveChannelPlayer;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
.vtx-live-control {
|
|
2
|
-
display: flex;
|
|
3
|
-
flex-direction: column;
|
|
4
|
-
|
|
5
|
-
.player-grid-container {
|
|
6
|
-
display: grid;
|
|
7
|
-
flex-grow: 1;
|
|
8
|
-
grid-gap: 1px;
|
|
9
|
-
height: 0;
|
|
10
|
-
background-color: rgb(0 0 0 / 80%);
|
|
11
|
-
|
|
12
|
-
&._1 {
|
|
13
|
-
grid-template-rows: 1fr;
|
|
14
|
-
grid-template-columns: 1fr;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
&._2 {
|
|
18
|
-
grid-template-rows: 1fr 1fr;
|
|
19
|
-
grid-template-columns: 1fr 1fr;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
&._3 {
|
|
23
|
-
grid-template-rows: 1fr 1fr 1fr;
|
|
24
|
-
grid-template-columns: 1fr 1fr 1fr;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.grid-item-container {
|
|
28
|
-
display: flex;
|
|
29
|
-
flex-direction: column;
|
|
30
|
-
min-width: 0;
|
|
31
|
-
min-height: 0;
|
|
32
|
-
background-color: #2b3d51;
|
|
33
|
-
background-image: url('./images/empty.png');
|
|
34
|
-
background-repeat: no-repeat;
|
|
35
|
-
background-position: center;
|
|
36
|
-
|
|
37
|
-
&.active {
|
|
38
|
-
box-shadow: 0 0 0 1px #52c41a;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
> .content {
|
|
42
|
-
flex-grow: 1;
|
|
43
|
-
height: 0;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.controls {
|
|
49
|
-
display: flex;
|
|
50
|
-
align-items: center;
|
|
51
|
-
width: 100%;
|
|
52
|
-
height: 32px;
|
|
53
|
-
padding: 0 12px;
|
|
54
|
-
background-color: #243241;
|
|
55
|
-
|
|
56
|
-
.right {
|
|
57
|
-
margin-left: auto;
|
|
58
|
-
|
|
59
|
-
> div {
|
|
60
|
-
height: 24px;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import LiveControl from '.';
|
|
2
|
-
import { ArgsTable, Canvas, Meta, Story } from '@storybook/addon-docs';
|
|
3
|
-
|
|
4
|
-
import * as stories from './index.stories';
|
|
5
|
-
|
|
6
|
-
<Meta title="组件/实时视频控制器"/>
|
|
7
|
-
|
|
8
|
-
# 实时视频控制器
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## 引入
|
|
12
|
-
|
|
13
|
-
```js
|
|
14
|
-
import { LiveControl } from '@vtx/player';
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## 方法调用
|
|
18
|
-
|
|
19
|
-
```tsx
|
|
20
|
-
import { LiveControl } from '@vtx/player';
|
|
21
|
-
|
|
22
|
-
const MyApp = () => {
|
|
23
|
-
const ref = useRef<LiveControlHandle>(null);
|
|
24
|
-
const params = {};
|
|
25
|
-
return (
|
|
26
|
-
<div>
|
|
27
|
-
<button onClick={() => ref.load(params)}>加载视频</button>
|
|
28
|
-
<LiveControl ref={ref} />
|
|
29
|
-
</div>
|
|
30
|
-
);
|
|
31
|
-
};
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## 方法类型
|
|
35
|
-
|
|
36
|
-
```ts
|
|
37
|
-
type LiveControlHandle = {
|
|
38
|
-
/** 加载视频 */
|
|
39
|
-
load: (channel: ChannelType) => void;
|
|
40
|
-
/** 卸载视频,参数为通道编号 */
|
|
41
|
-
unLoad: (channelNum: string) => void;
|
|
42
|
-
/** 一次加载多个视频,适用于初始化 */
|
|
43
|
-
multiLoad: (channels: ChannelType[]) => void;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
type ChannelType = {
|
|
47
|
-
/** 通道号 */
|
|
48
|
-
channelNum: string;
|
|
49
|
-
/** 设备ID */
|
|
50
|
-
deviceId?: string;
|
|
51
|
-
/** 租户ID */
|
|
52
|
-
tenantId?: string;
|
|
53
|
-
/** 协议 */
|
|
54
|
-
protocol?: string;
|
|
55
|
-
};
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## 属性
|
|
59
|
-
|
|
60
|
-
<ArgsTable of={LiveControl} />
|
|
61
|
-
|
|
62
|
-
## 例子
|
|
63
|
-
|
|
64
|
-
<Canvas>
|
|
65
|
-
<Story name="实时视频控制器" story={stories.Default} />
|
|
66
|
-
</Canvas>
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { useRef } from 'react';
|
|
2
|
-
|
|
3
|
-
import LiveControl, { ChannelType, LiveControlHandle } from '.';
|
|
4
|
-
import { ComponentStory } from '@storybook/react';
|
|
5
|
-
import { Button, Form, Input, Space } from 'antd';
|
|
6
|
-
|
|
7
|
-
const Template: ComponentStory<typeof LiveControl> = (args) => {
|
|
8
|
-
const ref = useRef<LiveControlHandle>(null);
|
|
9
|
-
const onFinish = (values: ChannelType) => {
|
|
10
|
-
const control = ref.current;
|
|
11
|
-
if (control) control.load(values);
|
|
12
|
-
};
|
|
13
|
-
return (
|
|
14
|
-
<Space size={24}>
|
|
15
|
-
<LiveControl ref={ref} {...args} />
|
|
16
|
-
<div>
|
|
17
|
-
<Form
|
|
18
|
-
name="basic"
|
|
19
|
-
labelCol={{ span: 8 }}
|
|
20
|
-
wrapperCol={{ span: 16 }}
|
|
21
|
-
onFinish={onFinish}
|
|
22
|
-
initialValues={{
|
|
23
|
-
channelNum: '87cc1a9de57a41e19344d4d3e75a5976',
|
|
24
|
-
deviceId: '687a1c4765c0453ea58618e5c7c6d9dd',
|
|
25
|
-
tenantId: '60edef2faea44a39a6385146f4fa131c',
|
|
26
|
-
}}
|
|
27
|
-
autoComplete="off"
|
|
28
|
-
>
|
|
29
|
-
<Form.Item
|
|
30
|
-
label="ChannelNum"
|
|
31
|
-
name="channelNum"
|
|
32
|
-
rules={[{ required: true, message: '请输入通道编号' }]}
|
|
33
|
-
>
|
|
34
|
-
<Input />
|
|
35
|
-
</Form.Item>
|
|
36
|
-
<Form.Item
|
|
37
|
-
label="TenantId"
|
|
38
|
-
name="tenantId"
|
|
39
|
-
rules={[{ required: true, message: '请输入通租户ID' }]}
|
|
40
|
-
>
|
|
41
|
-
<Input />
|
|
42
|
-
</Form.Item>
|
|
43
|
-
<Form.Item
|
|
44
|
-
label="DeviceId"
|
|
45
|
-
name="deviceId"
|
|
46
|
-
rules={[{ required: true, message: '请输入设备ID' }]}
|
|
47
|
-
>
|
|
48
|
-
<Input />
|
|
49
|
-
</Form.Item>
|
|
50
|
-
<Form.Item label="Protocol" name="protocol">
|
|
51
|
-
<Input />
|
|
52
|
-
</Form.Item>
|
|
53
|
-
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
|
|
54
|
-
<Button type="primary" htmlType="submit">
|
|
55
|
-
加载
|
|
56
|
-
</Button>
|
|
57
|
-
</Form.Item>
|
|
58
|
-
</Form>
|
|
59
|
-
</div>
|
|
60
|
-
</Space>
|
|
61
|
-
);
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
export const Default = Template.bind({});
|
|
65
|
-
Default.args = {
|
|
66
|
-
height: 600,
|
|
67
|
-
width: 1000,
|
|
68
|
-
};
|
|
69
|
-
export default Default;
|