@sgrsoft/vpe-react-sdk 0.1.7 → 0.1.9

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 CHANGED
@@ -1,26 +1,31 @@
1
1
  # VPE React SDK
2
2
 
3
- React 19/Vite 기반 VPE 플레이어 UI 라이브러리입니다. hls.js/dashjs 번들에 포함되지 않으며, 외부 플러그인으로 주입합니다.
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
-
14
- ## 설치
3
+ React 19/Vite 기반 VPE 플레이어 SDK입니다. `hls.js`/`dashjs`는 번들에 포함되지 않으며 외부에서 주입합니다.
4
+
5
+ ## Modules 이용하기
6
+
7
+ ### npm 이용한 설치
8
+ ```bash
9
+ npm install @sgrsoft/vpe-react-sdk
10
+ ```
11
+
12
+ ### yarn 이용한 설치
13
+ ```bash
14
+ yarn add @sgrsoft/vpe-react-sdk
15
+ ```
16
+
17
+ ### pnpm 이용한 설치
15
18
  ```bash
16
19
  pnpm add @sgrsoft/vpe-react-sdk
17
- # 선택: 스트리밍 라이브러리
18
- pnpm add hls.js dashjs
19
20
  ```
20
- - hls.js/dashjs는 선택적 peerDependency입니다. 브라우저/CDN 또는 `import Hls from "hls.js"`, `import dashjs from "dashjs"`로 주입하세요.
21
21
 
22
+ ### 스트리밍 라이브러리 설치(선택)
23
+ ```bash
24
+ npm install hls.js dashjs
25
+ ```
26
+
27
+ ## 플레이어 생성
22
28
 
23
- ## 사용법
24
29
  ### React (ESM)
25
30
  ```tsx
26
31
  import Hls from "hls.js";
@@ -28,184 +33,777 @@ import dashjs from "dashjs";
28
33
  import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
29
34
 
30
35
  export function App() {
31
- return (
32
- <VpePlayer
33
- accessKey="..."
34
- platform="pub"
35
- stage="prod"
36
- hls={Hls}
37
- dashjs={dashjs}
38
- options={{
36
+ return (
37
+ <VpePlayer
38
+ accessKey="YOUR_ACCESS_KEY"
39
+ platform="pub"
40
+ stage="prod"
41
+ hls={Hls}
42
+ dashjs={dashjs}
43
+ options={{
44
+ aspectRatio: "16/9",
45
+ playlist: [
46
+ {
47
+ file: "https://CDN_DOMAIN/example_video_01.mp4",
48
+ poster: "https://CDN_DOMAIN/example_video_01.png",
49
+ },
50
+ ],
51
+ }}
52
+ />
53
+ );
54
+ }
55
+ ```
56
+
57
+ ## 옵션 레퍼런스
58
+ `options`는 `vpe-core-sdk`에서 검증/보정됩니다. 기본값은 코어에서 결정되는 항목이 많아, 명시되지 않은 경우는 “vpe-core-sdk 기본값”으로 표기합니다.
59
+
60
+ | 옵션 | 타입 | 기본값 | 필수 | 설명 |
61
+ | --- | --- | --- | --- | --- |
62
+ | autostart | boolean | vpe-core-sdk 기본값 | No | 자동 재생 여부 |
63
+ | muted | boolean | vpe-core-sdk 기본값 | No | 시작 시 음소거 |
64
+ | aspectRatio | string | vpe-core-sdk 기본값 | No | 비율 (`"16/9"`, `"9/16"` 등) |
65
+ | objectFit | `"contain" \| "cover" \| "fill" \| "scale-down" \| "stretch"` | vpe-core-sdk 기본값 | No | 비디오 fit 방식 |
66
+ | controls | boolean | vpe-core-sdk 기본값 | No | 기본 컨트롤 표시 |
67
+ | keyboardShortcut | boolean | vpe-core-sdk 기본값 | No | 키보드 단축키 |
68
+ | seekingPreview | boolean | vpe-core-sdk 기본값 | No | 시킹 프리뷰 표시 |
69
+ | touchGestures | boolean | vpe-core-sdk 기본값 | No | 터치 제스처 사용 |
70
+ | startMutedInfoNotVisible | boolean | vpe-core-sdk 기본값 | No | 시작 음소거 안내 표시 여부 |
71
+ | lang | string | vpe-core-sdk 기본값 | No | UI 언어 |
72
+ | ui | string | vpe-core-sdk 기본값 | No | UI 모드/스킨 키 |
73
+ | controlBtn | object | vpe-core-sdk 기본값 | No | 버튼 표시 on/off 설정 |
74
+ | progressBarColor | string | vpe-core-sdk 기본값 | No | 진행바 색상 |
75
+ | controlActiveTime | number | `3000` | No | 컨트롤 자동 숨김(ms) |
76
+ | playRateSetting | number[] | vpe-core-sdk 기본값 | No | 재생 속도 리스트 |
77
+ | autoPause | boolean | vpe-core-sdk 기본값 | No | 자동 정지 |
78
+ | repeat | boolean | vpe-core-sdk 기본값 | No | 반복 재생 |
79
+ | setStartTime | string \| null | vpe-core-sdk 기본값 | No | 시작 시간 (문자열) |
80
+ | lowLatencyMode | boolean | vpe-core-sdk 기본값 | No | 저지연 모드 |
81
+ | descriptionNotVisible | boolean | vpe-core-sdk 기본값 | No | 메타 설명 숨김 |
82
+ | iosFullscreenNativeMode | boolean | vpe-core-sdk 기본값 | No | iOS 네이티브 전체화면 |
83
+ | visibleWatermark | boolean | vpe-core-sdk 기본값 | No | 워터마크 표시 |
84
+ | watermarkText | string | vpe-core-sdk 기본값 | No | 워터마크 텍스트 |
85
+ | watermarkConfig | object | vpe-core-sdk 기본값 | No | 워터마크 상세 설정 |
86
+ | devTestAppId | string | vpe-core-sdk 기본값 | No | 개발 테스트용 AppId |
87
+ | token | string | vpe-core-sdk 기본값 | No | 스트림 URL 토큰 |
88
+ | override | object | vpe-core-sdk 기본값 | No | 이벤트/동작 오버라이드 |
89
+ | layout | ControlBarLayout \| Variant \| Responsive | SDK 기본 레이아웃 | No | 컨트롤바 레이아웃 |
90
+
91
+ 참고
92
+ - `playlist` 등 재생 관련 옵션은 `vpe-core-sdk`에서 확장 처리됩니다. 예시는 위 “플레이어 생성” 섹션을 참고하세요.
93
+
94
+ ## 옵션 사용 예시
95
+ 아래 예시는 각 옵션을 단독으로 적용하는 형태입니다. 공통으로 `accessKey`와 `playlist`를 포함한 실행 코드를 제공합니다.
96
+
97
+ ### autostart
98
+ - 자동 재생 여부를 설정합니다.
99
+ ```tsx
100
+ <VpePlayer
101
+ accessKey="YOUR_ACCESS_KEY"
102
+ options={{
103
+ playlist: [
104
+ {
105
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
106
+ }
107
+ ],
108
+ autostart: true,
109
+ }}
110
+ />
111
+ ```
112
+
113
+ ### muted
114
+ - 시작 시 음소거를 적용합니다.
115
+ ```tsx
116
+ <VpePlayer
117
+ accessKey="YOUR_ACCESS_KEY"
118
+ options={{
119
+ playlist: [
120
+ {
121
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
122
+ }
123
+ ],
124
+ muted: true,
125
+ }}
126
+ />
127
+ ```
128
+
129
+ ### aspectRatio
130
+ - 플레이어 비율을 지정합니다.
131
+ ```tsx
132
+ <VpePlayer
133
+ accessKey="YOUR_ACCESS_KEY"
134
+ options={{
135
+ playlist: [
136
+ {
137
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
138
+ }
139
+ ],
39
140
  aspectRatio: "16/9",
141
+ }}
142
+ />
143
+ ```
144
+
145
+ ### objectFit
146
+ - 비디오 표시 방식을 설정합니다.
147
+ - cover | contain | fill | stretch
148
+ ```tsx
149
+ <VpePlayer
150
+ accessKey="YOUR_ACCESS_KEY"
151
+ options={{
40
152
  playlist: [
41
- {
42
- file: "https://.../master.m3u8",
43
- poster: "https://.../poster.jpg",
44
- vtt: [{ label: "KR", src: "https://.../subtitle.vtt", default: true }],
45
- },
153
+ {
154
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
155
+ }
46
156
  ],
47
- }}
48
- />
49
- );
50
- }
157
+ objectFit: "cover",
158
+ }}
159
+ />
51
160
  ```
52
161
 
53
- ### React (Ref로 제어)
162
+ ### controls
163
+ - 기본 컨트롤 표시 여부를 설정합니다.
54
164
  ```tsx
55
- import { useRef } from "react";
56
- import { VpePlayer, type PlayerHandle } from "@sgrsoft/vpe-react-sdk";
165
+ <VpePlayer
166
+ accessKey="YOUR_ACCESS_KEY"
167
+ options={{
168
+ playlist: [
169
+ {
170
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
171
+ }
172
+ ],
173
+ controls: true
174
+ }}
175
+ />
176
+ ```
57
177
 
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
- }
178
+ ### keyboardShortcut
179
+ - 키보드 단축키를 활성화합니다.
180
+ ```tsx
181
+ <VpePlayer
182
+ accessKey="YOUR_ACCESS_KEY"
183
+ options={{
184
+ keyboardShortcut: true,
185
+ playlist: [{ file: "https://CDN_DOMAIN/example_video_01.mp4" }],
186
+ }}
187
+ />
188
+ ```
189
+
190
+ ### seekingPreview
191
+ - 시킹 프리뷰 표시 여부를 설정합니다.
192
+ ```tsx
193
+ <VpePlayer
194
+ accessKey="YOUR_ACCESS_KEY"
195
+ options={{
196
+ playlist: [
197
+ {
198
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
199
+ }
200
+ ],
201
+ seekingPreview: true,
202
+ }}
203
+ />
204
+ ```
205
+
206
+ ### touchGestures
207
+ - 터치 제스처 사용 여부를 설정합니다.
208
+ ```tsx
209
+ <VpePlayer
210
+ accessKey="YOUR_ACCESS_KEY"
211
+ options={{
212
+ playlist: [
213
+ {
214
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
215
+ }
216
+ ],
217
+ touchGestures: true,
218
+ }}
219
+ />
220
+ ```
221
+
222
+ ### startMutedInfoNotVisible
223
+ - 시작 음소거 안내 문구 표시 여부를 설정합니다.
224
+ ```tsx
225
+ <VpePlayer
226
+ accessKey="YOUR_ACCESS_KEY"
227
+ options={{
228
+ playlist: [
229
+ {
230
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
231
+ }
232
+ ],
233
+ startMutedInfoNotVisible: true,
234
+ }}
235
+ />
69
236
  ```
70
237
 
71
- ## 레이아웃 시스템 사용 가이드
72
- `VpePlayer`는 `layout` props로 컨트롤바 구성을 유연하게 커스터마이즈할 수 있습니다.
73
- 기본값은 내부 `defaultLayout`이며, 지정하지 않으면 기본 레이아웃을 사용합니다.
238
+ ### lang
239
+ - UI 언어를 설정합니다.
240
+ - 설정하지 않거나 'auto'로 설정되면 브라우저 or 기기설정을 따라갑니다.
241
+ ```tsx
242
+ <VpePlayer
243
+ accessKey="YOUR_ACCESS_KEY"
244
+ options={{
245
+ playlist: [
246
+ {
247
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
248
+ }
249
+ ],
250
+ lang: "ko",
251
+ }}
252
+ />
253
+ ```
74
254
 
75
- ### 1) 기본 레이아웃 정의
76
- 레이아웃은 섹션 단위(`top`, `upper`, `center`, `lower`, `bottom`)로 구성됩니다.
77
- 섹션은 그룹 배열이며, 그룹은 `items`로 버튼을 배치합니다.
255
+ ### ui
256
+ - UI 모드/스킨 키를 설정합니다.
257
+ - auto | pc | mobile
258
+ - 설정하지 않거나 'auto'로 설정되면 브라우저 가로폭이나 기기를 따라갑니다.
259
+ ```tsx
260
+ <VpePlayer
261
+ accessKey="YOUR_ACCESS_KEY"
262
+ options={{
263
+ playlist: [
264
+ {
265
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
266
+ }
267
+ ],
268
+ ui: "auto",
269
+ }}
270
+ />
271
+ ```
78
272
 
273
+ ### controlBtn
274
+ - 컨트롤 버튼 표시 여부를 설정합니다.
275
+ ```tsx
276
+ <VpePlayer
277
+ accessKey="YOUR_ACCESS_KEY"
278
+ options={{
279
+ playlist: [
280
+ {
281
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
282
+ }
283
+ ],
284
+ controlBtn: {
285
+ play: true,
286
+ fullscreen: true,
287
+ progressBar: true,
288
+ volume: true,
289
+ times: true,
290
+ pictureInPicture: true,
291
+ setting: true,
292
+ subtitle: true,
293
+ },
294
+ }}
295
+ />
296
+ ```
297
+
298
+ ### progressBarColor
299
+ - 진행바 색상을 설정합니다.
300
+ ```tsx
301
+ <VpePlayer
302
+ accessKey="YOUR_ACCESS_KEY"
303
+ options={{
304
+ playlist: [
305
+ {
306
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
307
+ }
308
+ ],
309
+ progressBarColor: "#00E0FF",
310
+ }}
311
+ />
312
+ ```
313
+
314
+ ### controlActiveTime
315
+ - 컨트롤 자동 숨김 시간을 설정합니다(ms).
316
+ ```tsx
317
+ <VpePlayer
318
+ accessKey="YOUR_ACCESS_KEY"
319
+ options={{
320
+ playlist: [
321
+ {
322
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
323
+ }
324
+ ],
325
+ controlActiveTime: 3000,
326
+ }}
327
+ />
328
+ ```
329
+
330
+ ### playRateSetting
331
+ - 재생 속도 옵션을 설정합니다.
332
+ ```tsx
333
+ <VpePlayer
334
+ accessKey="YOUR_ACCESS_KEY"
335
+ options={{
336
+ playlist: [
337
+ {
338
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
339
+ }
340
+ ],
341
+ playRateSetting: [0.5, 1, 1.5, 2],
342
+ }}
343
+ />
344
+ ```
345
+
346
+ ### autoPause
347
+ - 탭 전환/창 최소화 시 자동 정지를 설정합니다.
348
+ - 인앱의 웹뷰 상황에서는 정상동작하지 않습니다. (앱의 백그라운드 상황은 지원하지 않습니다.)
349
+ ```tsx
350
+ <VpePlayer
351
+ accessKey="YOUR_ACCESS_KEY"
352
+ options={{
353
+ playlist: [
354
+ {
355
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
356
+ }
357
+ ],
358
+ autoPause: true,
359
+ }}
360
+ />
361
+ ```
362
+
363
+ ### repeat
364
+ - 반복 재생을 설정합니다.
365
+ - 여러 영상의 플레이리스트 상태라면 모든 영상이 재생 후 맨처음 영상으로 이동하여 반복 재생됩니다.
366
+ ```tsx
367
+ <VpePlayer
368
+ accessKey="YOUR_ACCESS_KEY"
369
+ options={{
370
+ playlist: [
371
+ {
372
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
373
+ }
374
+ ],
375
+ repeat: true,
376
+ }}
377
+ />
378
+ ```
379
+
380
+ ### setStartTime
381
+ - 시작 시간을 지정합니다(문자열).
382
+ - 기존적으로 UTC 시간을 지원하지만, 로컬포멧도 지원합니다.
383
+ ```tsx
384
+ <VpePlayer
385
+ accessKey="YOUR_ACCESS_KEY"
386
+ options={{
387
+ playlist: [
388
+ {
389
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
390
+ }
391
+ ],
392
+ setStartTime: "2026-02-03T09:00:00Z",
393
+ }}
394
+ />
395
+ ```
396
+
397
+ ### lowLatencyMode
398
+ - 저지연 모드를 활성화합니다.
399
+ - LL-HLS를 제대로 재생하려면 해당 옵션이 필수입니다.
400
+ ```tsx
401
+ <VpePlayer
402
+ accessKey="YOUR_ACCESS_KEY"
403
+ options={{
404
+ playlist: [
405
+ {
406
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
407
+ }
408
+ ],
409
+ lowLatencyMode: true,
410
+ }}
411
+ />
412
+ ```
413
+
414
+ ### descriptionNotVisible
415
+ - 메타 설명 표시 여부를 설정합니다.
416
+ - 기본값은 false 이며 ture 설정시 화면에 표시되지 않습니다.
417
+ ```tsx
418
+ <VpePlayer
419
+ accessKey="YOUR_ACCESS_KEY"
420
+ options={{
421
+ playlist: [
422
+ {
423
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
424
+ }
425
+ ],
426
+ descriptionNotVisible: true,
427
+ }}
428
+ />
429
+ ```
430
+
431
+ ### iosFullscreenNativeMode
432
+ - iOS 네이티브 전체화면 모드를 사용합니다.
433
+ ```tsx
434
+ <VpePlayer
435
+ accessKey="YOUR_ACCESS_KEY"
436
+ options={{
437
+ playlist: [
438
+ {
439
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
440
+ }
441
+ ],
442
+ iosFullscreenNativeMode: true,
443
+ }}
444
+ />
445
+ ```
446
+
447
+ ### visibleWatermark
448
+ - 워터마크 표시 여부를 설정합니다.
449
+ - 이 옵션은 Video Player Enhancement 콘솔 옵션에서만 적용 가능합니다.
450
+ - 코드사에서 이 옵션을 수정할 수 없습니다.
451
+ ```tsx
452
+ <VpePlayer
453
+ accessKey="YOUR_ACCESS_KEY"
454
+ options={{
455
+ playlist: [
456
+ {
457
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
458
+ }
459
+ ],
460
+ visibleWatermark: true,
461
+ }}
462
+ />
463
+ ```
464
+
465
+ ### watermarkText
466
+ - 워터마크 텍스트를 지정합니다.
467
+ ```tsx
468
+ <VpePlayer
469
+ accessKey="YOUR_ACCESS_KEY"
470
+ options={{
471
+ playlist: [
472
+ {
473
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
474
+ }
475
+ ],
476
+ watermarkText: "SAMPLE@example.com",
477
+ }}
478
+ />
479
+ ```
480
+
481
+ ### watermarkConfig
482
+ - 워터마크 상세 설정을 지정합니다.
483
+ ```tsx
484
+ <VpePlayer
485
+ accessKey="YOUR_ACCESS_KEY"
486
+ options={{
487
+ playlist: [
488
+ {
489
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
490
+ }
491
+ ],
492
+ watermarkConfig: {
493
+ randPosition: true, //위치 랜덤 여부
494
+ randPositionInterVal: 5000, //랜덤 주기 (ms)
495
+ x: 10, //randPosition 이 false 라면 워터마크 위치 고정시 X값 (단위 %)
496
+ y: 10, //randPosition 이 false 라면 워터마크 위치 고정시 Y값 (단위 %)
497
+ opacity: 0.4, //워터마크 투명도
498
+ },
499
+ }}
500
+ />
501
+ ```
502
+
503
+
504
+ ### token
505
+ - 스트림 URL에 자동으로 붙일 토큰을 설정합니다.
506
+ - 글로벌엣지 CDN 보안 토큰을 설정합니다. hls/dash 적용시 하위 ts 파일까지 함께 적용됩니다.
507
+ ```tsx
508
+ <VpePlayer
509
+ accessKey="YOUR_ACCESS_KEY"
510
+ options={{
511
+ playlist: [
512
+ {
513
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
514
+ }
515
+ ],
516
+ token: "token=...",
517
+ }}
518
+ />
519
+ ```
520
+
521
+ ### override
522
+ - 내부 동작을 오버라이드합니다.
523
+ ```tsx
524
+ <VpePlayer
525
+ accessKey="YOUR_ACCESS_KEY"
526
+ options={{
527
+ playlist: [
528
+ {
529
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
530
+ }
531
+ ],
532
+ override: {
533
+ error: (error) => console.log(error), //에러 발생시 실행
534
+ nextSource: () => {}, //다음 동영상 이동시 실행
535
+ prevSource: () => {}, //이전 동영상 이동시 실행
536
+ pip: { //pip 오버라이드, pip를 직접 구현할때 사용
537
+ on: () => {},
538
+ off: () => {},
539
+ },
540
+ },
541
+
542
+ }}
543
+ />
544
+ ```
545
+
546
+ ---
547
+
548
+ ### layout
549
+ - 레이아웃을 옵션으로 전달해 컨트롤바를 변경합니다.
550
+ - 레이아웃 Video Player Enhancement 시스템은 콘솔에 UI 편집툴을 이용하여 작성할 수 있습니다.
551
+ - PC | Mobile | FullScreen 상태에 vod | live 별로 레이아웃 구성 지원합니다.
552
+ - 전체 레이아웃이 아닌 일부만 입력한다면 기존 레이아웃과 머지되어 동작합니다.
553
+ - 자세한건 하위 레이아웃 시스템에 기술되어 있습니다.
554
+ ```tsx
555
+ <VpePlayer
556
+ accessKey="YOUR_ACCESS_KEY"
557
+ options={{
558
+ playlist: [
559
+ {
560
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
561
+ }
562
+ ],
563
+ layout: {
564
+ pc:{
565
+ vod: {
566
+ bottom: [{ key: "play", items: ["PlayBtn"] }],
567
+ },
568
+ live:{
569
+ bottom: [{ key: "play", items: ["PlayBtn"] }],
570
+ }
571
+ }
572
+ },
573
+ }}
574
+ />
575
+ ```
576
+
577
+ ## 레이아웃 시스템
578
+ `layout` props로 컨트롤바를 커스터마이즈할 수 있습니다.
579
+
580
+ ### 기본 레이아웃
79
581
  ```tsx
80
582
  const layout = {
81
- top: [],
82
- center: [{ key: "bigPlayBtn", items: ["BigPlayBtn"] }],
83
- bottom: [
84
- { key: "play", items: ["PlayBtn"], wrapper: "Group", noPadding: true },
85
- { key: "volume", items: ["VolumeBtn"], wrapper: "Group" },
86
- { key: "time", items: ["TimeBtn"], wrapper: "Group" },
87
- { key: "blank", wrapper: "Blank", items: [] },
88
- { key: "right", items: ["SubtitleBtn", "FullscreenBtn"], cap: 2, wrapper: "Group" },
89
- ],
90
- order: ["top", "upper", "center", "seekbar", "lower", "bottom"],
583
+ top: [],
584
+ center: [{ key: "bigPlayBtn", items: ["BigPlayBtn"] }],
585
+ bottom: [
586
+ { key: "play", items: ["PlayBtn"], wrapper: "Group", noPadding: true },
587
+ { key: "volume", items: ["VolumeBtn"], wrapper: "Group" },
588
+ { key: "time", items: ["TimeBtn"], wrapper: "Group" },
589
+ { key: "blank", wrapper: "Blank", items: [] },
590
+ { key: "right", items: ["SubtitleBtn", "FullscreenBtn"], cap: 2, wrapper: "Group" },
591
+ ],
91
592
  };
92
593
 
93
- <VpePlayer layout={layout} />
594
+ <VpePlayer layout={layout} />;
94
595
  ```
95
596
 
96
- ### 2) 라이브/다시보기 분기
97
- 라이브/다시보기 레이아웃을 분기하려면 `live`, `vod`를 사용합니다.
98
-
597
+ ### 라이브/다시보기 분기
99
598
  ```tsx
100
599
  const layoutVariant = {
101
- live: { /* live 전용 레이아웃 */ },
102
- vod: { /* vod 전용 레이아웃 */ },
600
+ live: { /* live 전용 레이아웃 */ },
601
+ vod: { /* vod 전용 레이아웃 */ },
103
602
  };
104
603
 
105
- <VpePlayer layout={layoutVariant} />
604
+ <VpePlayer layout={layoutVariant} />;
106
605
  ```
107
606
 
108
- ### 3) 반응형 레이아웃
109
- PC/모바일/전체화면을 분기하려면 `pc`, `mobile`, `fullscreen`을 사용합니다.
110
- 각 항목은 기본 레이아웃 또는 라이브/다시보기 분기 레이아웃을 받을 수 있습니다.
111
-
607
+ ### 반응형 레이아웃
112
608
  ```tsx
113
609
  const responsiveLayout = {
114
- pc: {
115
- live: { /* pc live */ },
116
- vod: { /* pc vod */ },
117
- },
118
- mobile: {
119
- live: { /* mobile live */ },
120
- vod: { /* mobile vod */ },
121
- },
122
- fullscreen: {
123
- live: { /* fullscreen live */ },
124
- vod: { /* fullscreen vod */ },
125
- },
126
- breakpoint: 768, // 모바일 판단 기준(px)
610
+ pc: {
611
+ live: { /* pc live */ },
612
+ vod: { /* pc vod */ },
613
+ },
614
+ mobile: {
615
+ live: { /* mobile live */ },
616
+ vod: { /* mobile vod */ },
617
+ },
618
+ fullscreen: {
619
+ live: { /* fullscreen live */ },
620
+ vod: { /* fullscreen vod */ },
621
+ },
622
+ breakpoint: 768,
127
623
  };
128
624
 
129
- <VpePlayer layout={responsiveLayout} />
625
+ <VpePlayer layout={responsiveLayout} />;
130
626
  ```
131
627
 
132
- ### 4) 그룹 옵션 요약
133
- - `items`: 버튼 배열 또는 커스텀 ReactNode
134
- - `wrapper`: `"Group"` 또는 `"Blank"` (미지정 시 기본 컨테이너)
135
- - `cap`: 그룹에 버튼간 간격
136
- - `align`: `"left" | "right" | "center"`
628
+ ### 레이아웃 실시간 변경
629
+ Ref 인스턴스에서 `layout(nextLayout, merge?)`를 호출하면 즉시 반영됩니다.
137
630
 
138
- ### 5) 사용 가능한 `items`
631
+ ```ts
632
+ import { setup } from "@sgrsoft/vpe-react-sdk";
633
+
634
+ const instance = setup("#video", "YOUR_ACCESS_KEY", {
635
+ options: { playlist: [{ file: "https://CDN_DOMAIN/example_video_01.mp4" }] },
636
+ });
637
+
638
+ instance.layout({
639
+ bottom: [{ key: "custom", items: ["SettingBtn"] }],
640
+ });
139
641
  ```
140
- PlayBtn, VolumeBtn, TimeBtn, SubtitleBtn, FullscreenBtn, SettingBtn, PipBtn,
141
- LevelSelectBtn, MetaDesc, BigPlayBtn, SeekBar, SettingModal, DurationBtn,
142
- SkipForwardBtn, SkipBackBtn, CurrentTimeBtn, MuteBtn, PrevBtn, NextBtn,
143
- NextPrevBtn, Blank
642
+
643
+ ## 플레이어 메소드 (Ref)
644
+ `ref`로 전달되는 `PlayerHandle`에서 아래 메소드를 사용할 수 있습니다.
645
+
646
+ ```tsx
647
+ import { useRef } from "react";
648
+ import { VpePlayer, type PlayerHandle } from "@sgrsoft/vpe-react-sdk";
649
+
650
+ export function App() {
651
+ const playerRef = useRef<PlayerHandle>(null);
652
+
653
+ return (
654
+ <>
655
+ <VpePlayer
656
+ ref={playerRef}
657
+ accessKey="YOUR_ACCESS_KEY"
658
+ options={{
659
+ playlist: [
660
+ {
661
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
662
+ }
663
+ ],
664
+ }}
665
+ />
666
+ <button onClick={() => playerRef.current?.play()}>Play</button>
667
+ <button onClick={() => playerRef.current?.pause()}>Pause</button>
668
+ </>
669
+ );
670
+ }
144
671
  ```
145
672
 
673
+ 지원 메소드
674
+
675
+ | 메소드 | 시그니처 | 설명 |
676
+ | --- | --- | --- |
677
+ | play | `play()` | 재생 시작 |
678
+ | pause | `pause()` | 재생 일시정지 |
679
+ | mute | `mute()` | 음소거 |
680
+ | prev | `prev()` | 이전 플레이리스트 아이템 |
681
+ | next | `next()` | 다음 플레이리스트 아이템 |
682
+ | fullscreen | `fullscreen()` | 전체화면 토글 |
683
+ | fullscreenOn | `fullscreenOn()` | 전체화면 진입 |
684
+ | fullScreenOff | `fullScreenOff()` | 전체화면 종료 |
685
+ | pip | `pip()` | PIP 토글 |
686
+ | volume | `volume(vol?)` | 볼륨 설정 |
687
+ | uiHidden | `uiHidden()` | UI 숨김 |
688
+ | uiVisible | `uiVisible()` | UI 표시 |
689
+ | currentTime | `currentTime(time?)` | 현재 재생 시간 설정 |
690
+ | controlBarActive | `controlBarActive()` | 컨트롤바 활성화 |
691
+ | controlBarDeactive | `controlBarDeactive()` | 컨트롤바 비활성화 |
692
+ | tokenChange | `tokenChange(token)` | 토큰 변경 |
693
+ | layout | `layout(nextLayout, merge?)` | 레이아웃 변경 |
694
+ | changeUiMode | `changeUiMode(mode)` | UI 모드 변경 |
695
+ | changePlayMode | `changePlayMode(mode)` | 재생 모드 변경 |
696
+
146
697
  ## 이벤트
147
- `onEvent` 또는 UMD 인스턴스의 `on`으로 이벤트를 수신합니다.
698
+ `onEvent`로 이벤트를 수신합니다.
148
699
 
149
700
  ```tsx
150
701
  <VpePlayer
151
- accessKey="..."
152
- options={{ playlist: [{ file: "..." }] }}
153
- onEvent={(event) => {
154
- if (event.type === "error") {
155
- console.log(event.data);
156
- }
157
- }}
158
- />
702
+ accessKey="YOUR_ACCESS_KEY"
703
+ options={{
704
+ playlist: [
705
+ {
706
+ file: "https://CDN_DOMAIN/example_video_01.mp4"
707
+ }
708
+ ],
709
+ }}
710
+ onEvent={(event) => {
711
+ if (event.type === "error") {
712
+ console.log(event.data);
713
+ }
714
+ }}
715
+ />;
159
716
  ```
160
717
 
161
- 지원 이벤트: `stateChange`, `ready`, `play`, `pause`, `ended`, `fullscreen`, `fullscreenExit`, `loadingStart`,
162
- `loadingEnd`, `bufferingStart`, `bufferingEnd`, `seeking`, `seeked`, `waiting`, `volumechange`, `timeupdate`,
163
- `controlbarActive`, `controlbarDeactive`, `next`, `prev`, `skipForward`, `skipBack`, `playlistChange`, `error`
718
+ 지원 이벤트
164
719
 
165
- ## DRM/토큰 적용 예시
720
+ | 이벤트 | 설명 |
721
+ | --- | --- |
722
+ | stateChange | 플레이어 상태 스냅샷 변경 |
723
+ | ready | 초기화 완료 및 재생 준비 |
724
+ | play | 재생 시작 |
725
+ | pause | 재생 일시정지 |
726
+ | ended | 재생 종료 |
727
+ | fullscreen | 전체화면 진입 |
728
+ | fullscreenExit | 전체화면 종료 |
729
+ | loadingStart | 로딩 시작 |
730
+ | loadingEnd | 로딩 종료 |
731
+ | bufferingStart | 버퍼링 시작 |
732
+ | bufferingEnd | 버퍼링 종료 |
733
+ | seeking | 탐색 시작 |
734
+ | seeked | 탐색 종료 |
735
+ | waiting | 재생 대기 상태 |
736
+ | volumechange | 볼륨 변경 |
737
+ | timeupdate | 재생 시간 변경 |
738
+ | controlbarActive | 컨트롤바 활성화 |
739
+ | controlbarDeactive | 컨트롤바 비활성화 |
740
+ | next | 다음 아이템으로 이동 |
741
+ | prev | 이전 아이템으로 이동 |
742
+ | skipForward | 앞으로 건너뜀 |
743
+ | skipBack | 뒤로 건너뜀 |
744
+ | playlistChange | 플레이리스트 변경 |
745
+ | error | 오류 발생 |
746
+
747
+ ## One Click Multi DRM 예제
166
748
  ```ts
167
749
  options={{
168
- token: "token=...",
169
- playlist: [
170
- {
171
- drm: {
172
- "com.widevine.alpha": {
173
- src: "https://.../manifest.mpd",
174
- licenseUri: "https://.../license",
175
- licenseRequestHeader: { Authorization: "Bearer ..." },
176
- },
177
- "com.apple.fps": {
178
- src: "https://.../master.m3u8",
179
- licenseUri: "https://.../fps-license",
180
- certificateUri: "https://.../fps-cert",
750
+ aspectRatio: "16/9",
751
+ autostart: true,
752
+ muted: true,
753
+ playlist: [
754
+ {
755
+ poster: "https://CDN_DOMAIN/example_poster.jpg",
756
+ description: {
757
+ title: "테스트 영상",
758
+ created_at: "2024.07.13",
759
+ profile_name: "VPE",
760
+ profile_image: "https://CDN_DOMAIN/profile.png",
761
+ },
762
+ drm: {
763
+ "com.widevine.alpha": {
764
+ src: "https://CDN_DOMAIN/manifest.mpd",
765
+ licenseUri: "https://multi-drm.apigw.ntruss.com/api/v1/license",
766
+ licenseRequestHeader: {
767
+ "x-ncp-region_code": "KR",
768
+ "x-ncp-iam-access-key": "YOUR_ACCESS_KEY",
769
+ "x-ncp-apigw-timestamp": 1770125949480,
770
+ "x-ncp-apigw-signature-v2": "YOUR_SIGNATURE",
771
+ "x-drm-token": "YOUR_DRM_TOKEN",
772
+ },
773
+ },
774
+ "com.microsoft.playready": {
775
+ src: "https://CDN_DOMAIN/manifest.mpd",
776
+ licenseUri: "https://multi-drm.apigw.ntruss.com/api/v1/license",
777
+ licenseRequestHeader: {
778
+ "x-ncp-region_code": "KR",
779
+ "x-ncp-iam-access-key": "YOUR_ACCESS_KEY",
780
+ "x-ncp-apigw-timestamp": 1770125949480,
781
+ "x-ncp-apigw-signature-v2": "YOUR_SIGNATURE",
782
+ "x-drm-token": "YOUR_DRM_TOKEN",
783
+ },
784
+ },
785
+ "com.apple.fps": {
786
+ src: "https://CDN_DOMAIN/index.m3u8",
787
+ certificateUri: "https://multi-drm.apigw.ntruss.com/api/v1/license/fairPlay",
788
+ certificateRequestHeader: {
789
+ "x-ncp-region_code": "KR",
790
+ "x-ncp-iam-access-key": "YOUR_ACCESS_KEY",
791
+ "x-ncp-apigw-timestamp": 1770125949480,
792
+ "x-ncp-apigw-signature-v2": "YOUR_SIGNATURE",
793
+ "x-drm-token": "YOUR_DRM_TOKEN",
794
+ "accept": "application/json",
795
+ },
796
+ licenseUri: "https://multi-drm.apigw.ntruss.com/api/v1/license",
797
+ licenseRequestHeader: {
798
+ "x-ncp-region_code": "KR",
799
+ "x-ncp-iam-access-key": "YOUR_ACCESS_KEY",
800
+ "x-ncp-apigw-timestamp": 1770125949481,
801
+ "x-ncp-apigw-signature-v2": "YOUR_SIGNATURE",
802
+ "x-drm-token": "YOUR_DRM_TOKEN",
803
+ },
804
+ },
805
+ },
181
806
  },
182
- },
183
- },
184
- ],
807
+ ],
185
808
  }}
186
809
  ```
187
-
188
- ### UMD
189
- ```html
190
- <link rel="stylesheet" href="./vpePlayer.css" />
191
- <script src="https://cdn.jsdelivr.net/npm/hls.js@1"></script>
192
- <script src="https://cdn.jsdelivr.net/npm/dashjs@4"></script>
193
- <script src="./vpePlayer.js?accessKey=YOUR_ACCESS_KEY"></script>
194
- <div id="video"></div>
195
- <script>
196
- ncplayer.use(window.Hls).use(window.dashjs);
197
- const player = new ncplayer("video", { aspectRatio: "16/9" });
198
- player.on("ready", (event) => console.log(event));
199
- // player.destroy() 로 해제 가능
200
- </script>
201
- ```
202
-
203
- ## UMD setup 함수
204
- ```html
205
- <script>
206
- const instance = window.vpe.setup("#video", "YOUR_ACCESS_KEY", {
207
- options: { aspectRatio: "16/9", playlist: [{ file: "..." }] },
208
- });
209
- // instance.render({ options: { ... } }) 로 재렌더 가능
210
- </script>
211
- ```