@sgrsoft/vpe-react-sdk 0.1.6 → 0.1.8
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/README.md +129 -11
- package/dist/vpe-react-sdk.es.js +9697 -8593
- package/dist/vpe-react-sdk.umd.js +184 -156
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
# VPE React SDK
|
|
1
|
+
# VPE React SDK
|
|
2
2
|
|
|
3
3
|
React 19/Vite 기반 VPE 플레이어 UI 라이브러리입니다. hls.js/dashjs는 번들에 포함되지 않으며, 외부 플러그인으로 주입합니다.
|
|
4
4
|
|
|
5
|
+
## 주요 기능
|
|
6
|
+
- HLS/DASH/MP4 재생 및 재생 타입 자동 판별
|
|
7
|
+
- 플레이리스트 재생, 다음/이전 이동, 자동 다음 재생(카운트다운)
|
|
8
|
+
- DRM 지원: Widevine/PlayReady/FairPlay + DRM 라이선스/인증서 헤더 전달
|
|
9
|
+
- 토큰 기반 스트림 URL 자동 부착(`options.token`)
|
|
10
|
+
- 커스텀 컨트롤바 레이아웃(라이브/VOD, PC/모바일/전체화면 분기)
|
|
11
|
+
- 이벤트 브리지(`onEvent`) 및 외부 컨트롤(Ref/UMD 인스턴스)
|
|
12
|
+
- 에러 UI 기본 제공 및 `errorOverride`로 커스터마이즈
|
|
13
|
+
|
|
5
14
|
## 설치
|
|
6
15
|
```bash
|
|
7
16
|
pnpm add @sgrsoft/vpe-react-sdk
|
|
@@ -22,24 +31,82 @@ export function App() {
|
|
|
22
31
|
return (
|
|
23
32
|
<VpePlayer
|
|
24
33
|
accessKey="..."
|
|
25
|
-
appId="..."
|
|
26
34
|
platform="pub"
|
|
27
35
|
stage="prod"
|
|
28
|
-
aspectRatio="16/9"
|
|
29
36
|
hls={Hls}
|
|
30
37
|
dashjs={dashjs}
|
|
31
38
|
options={{
|
|
32
|
-
|
|
39
|
+
aspectRatio: "16/9",
|
|
40
|
+
playlist: [
|
|
41
|
+
{
|
|
42
|
+
file: "https://.../master.m3u8",
|
|
43
|
+
poster: "https://.../poster.jpg",
|
|
44
|
+
vtt: [{ label: "KR", src: "https://.../subtitle.vtt", default: true }],
|
|
45
|
+
},
|
|
46
|
+
],
|
|
33
47
|
}}
|
|
34
48
|
/>
|
|
35
49
|
);
|
|
36
50
|
}
|
|
37
51
|
```
|
|
38
52
|
|
|
53
|
+
### React (Ref로 제어)
|
|
54
|
+
```tsx
|
|
55
|
+
import { useRef } from "react";
|
|
56
|
+
import { VpePlayer, type PlayerHandle } from "@sgrsoft/vpe-react-sdk";
|
|
57
|
+
|
|
58
|
+
export function App() {
|
|
59
|
+
const playerRef = useRef<PlayerHandle>(null);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<VpePlayer ref={playerRef} accessKey="..." options={{ playlist: [{ file: "..." }] }} />
|
|
64
|
+
<button onClick={() => playerRef.current?.play()}>Play</button>
|
|
65
|
+
<button onClick={() => playerRef.current?.fullscreenOn()}>Fullscreen</button>
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
39
71
|
## 레이아웃 시스템 사용 가이드
|
|
40
72
|
`VpePlayer`는 `layout` props로 컨트롤바 구성을 유연하게 커스터마이즈할 수 있습니다.
|
|
41
73
|
기본값은 내부 `defaultLayout`이며, 지정하지 않으면 기본 레이아웃을 사용합니다.
|
|
42
74
|
|
|
75
|
+
### 실시간 레이아웃 변경 (메소드)
|
|
76
|
+
UMD/ES 인스턴스에서 `layout(nextLayout, merge?)`를 호출하면 즉시 반영됩니다.
|
|
77
|
+
기본 동작은 **전달된 필드만 교체**하며, `merge=false`를 전달하면 전체 교체합니다.
|
|
78
|
+
|
|
79
|
+
#### ES (setup 인스턴스)
|
|
80
|
+
```ts
|
|
81
|
+
import { setup } from "@sgrsoft/vpe-react-sdk";
|
|
82
|
+
|
|
83
|
+
const instance = setup("#video", "ACCESS_KEY", {
|
|
84
|
+
options: { playlist: [{ file: "..." }] },
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
instance.layout({
|
|
88
|
+
bottom: [{ key: "custom", items: ["SettingBtn"] }],
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// 기존 bottom 삭제
|
|
92
|
+
// instance.layout({ bottom: [] });
|
|
93
|
+
|
|
94
|
+
// 전체 교체
|
|
95
|
+
// instance.layout({ bottom: [] }, false);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
#### UMD (ncplayer 인스턴스)
|
|
99
|
+
```html
|
|
100
|
+
<script>
|
|
101
|
+
const player = new ncplayer("#video", "ACCESS_KEY", {});
|
|
102
|
+
player.layout({
|
|
103
|
+
bottom: [{ key: "custom", items: ["SettingBtn"] }],
|
|
104
|
+
});
|
|
105
|
+
// player.layout({ bottom: [] });
|
|
106
|
+
// player.layout({ bottom: [] }, false);
|
|
107
|
+
</script>
|
|
108
|
+
```
|
|
109
|
+
|
|
43
110
|
### 1) 기본 레이아웃 정의
|
|
44
111
|
레이아웃은 섹션 단위(`top`, `upper`, `center`, `lower`, `bottom`)로 구성됩니다.
|
|
45
112
|
각 섹션은 그룹 배열이며, 그룹은 `items`로 버튼을 배치합니다.
|
|
@@ -100,15 +167,57 @@ const responsiveLayout = {
|
|
|
100
167
|
### 4) 그룹 옵션 요약
|
|
101
168
|
- `items`: 버튼 배열 또는 커스텀 ReactNode
|
|
102
169
|
- `wrapper`: `"Group"` 또는 `"Blank"` (미지정 시 기본 컨테이너)
|
|
103
|
-
- `cap`:
|
|
104
|
-
- `noPadding`: 그룹 패딩 제거
|
|
170
|
+
- `cap`: 그룹에 버튼간 간격
|
|
105
171
|
- `align`: `"left" | "right" | "center"`
|
|
106
172
|
|
|
107
173
|
### 5) 사용 가능한 `items`
|
|
108
174
|
```
|
|
109
175
|
PlayBtn, VolumeBtn, TimeBtn, SubtitleBtn, FullscreenBtn, SettingBtn, PipBtn,
|
|
110
|
-
|
|
111
|
-
SkipForwardBtn, SkipBackBtn, CurrentTimeBtn, MuteBtn,
|
|
176
|
+
MetaDesc, BigPlayBtn, SeekBar, SettingModal, DurationBtn,
|
|
177
|
+
SkipForwardBtn, SkipBackBtn, CurrentTimeBtn, MuteBtn, PrevBtn, NextBtn,
|
|
178
|
+
NextPrevBtn, Blank
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## 이벤트
|
|
182
|
+
`onEvent` 또는 UMD 인스턴스의 `on`으로 이벤트를 수신합니다.
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<VpePlayer
|
|
186
|
+
accessKey="..."
|
|
187
|
+
options={{ playlist: [{ file: "..." }] }}
|
|
188
|
+
onEvent={(event) => {
|
|
189
|
+
if (event.type === "error") {
|
|
190
|
+
console.log(event.data);
|
|
191
|
+
}
|
|
192
|
+
}}
|
|
193
|
+
/>
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
지원 이벤트: `stateChange`, `ready`, `play`, `pause`, `ended`, `fullscreen`, `fullscreenExit`, `loadingStart`,
|
|
197
|
+
`loadingEnd`, `bufferingStart`, `bufferingEnd`, `seeking`, `seeked`, `waiting`, `volumechange`, `timeupdate`,
|
|
198
|
+
`controlbarActive`, `controlbarDeactive`, `next`, `prev`, `skipForward`, `skipBack`, `playlistChange`, `error`
|
|
199
|
+
|
|
200
|
+
## DRM/토큰 적용 예시
|
|
201
|
+
```ts
|
|
202
|
+
options={{
|
|
203
|
+
token: "token=...",
|
|
204
|
+
playlist: [
|
|
205
|
+
{
|
|
206
|
+
drm: {
|
|
207
|
+
"com.widevine.alpha": {
|
|
208
|
+
src: "https://.../manifest.mpd",
|
|
209
|
+
licenseUri: "https://.../license",
|
|
210
|
+
licenseRequestHeader: { Authorization: "Bearer ..." },
|
|
211
|
+
},
|
|
212
|
+
"com.apple.fps": {
|
|
213
|
+
src: "https://.../master.m3u8",
|
|
214
|
+
licenseUri: "https://.../fps-license",
|
|
215
|
+
certificateUri: "https://.../fps-cert",
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
}}
|
|
112
221
|
```
|
|
113
222
|
|
|
114
223
|
### UMD
|
|
@@ -120,9 +229,18 @@ SkipForwardBtn, SkipBackBtn, CurrentTimeBtn, MuteBtn, Blank
|
|
|
120
229
|
<div id="video"></div>
|
|
121
230
|
<script>
|
|
122
231
|
ncplayer.use(window.Hls).use(window.dashjs);
|
|
123
|
-
const player = new ncplayer("video", {
|
|
124
|
-
|
|
125
|
-
});
|
|
232
|
+
const player = new ncplayer("video", { aspectRatio: "16/9" });
|
|
233
|
+
player.on("ready", (event) => console.log(event));
|
|
126
234
|
// player.destroy() 로 해제 가능
|
|
127
235
|
</script>
|
|
128
236
|
```
|
|
237
|
+
|
|
238
|
+
## UMD setup 함수
|
|
239
|
+
```html
|
|
240
|
+
<script>
|
|
241
|
+
const instance = window.vpe.setup("#video", "YOUR_ACCESS_KEY", {
|
|
242
|
+
options: { aspectRatio: "16/9", playlist: [{ file: "..." }] },
|
|
243
|
+
});
|
|
244
|
+
// instance.render({ options: { ... } }) 로 재렌더 가능
|
|
245
|
+
</script>
|
|
246
|
+
```
|