vpe-react-native-cli
v2.2.2
Published
VPE React Native SDK (React Native CLI / bare)
Readme
vpe-react-native-cli
VPE 비디오 플레이어 React Native SDK (React Native CLI / bare 워크플로우 전용).
NAVER Cloud Platform VOD/Live 스트리밍을 위한 풀스크린 비디오 플레이어 컴포넌트로, HLS/DASH/MP4 재생, DRM, 자막(VTT), 화질·배속 선택, 워터마크, 화면 녹화 방지, PIP, 프리미어(예약 공개), 커스텀 컨트롤 레이아웃, 미디어 분석(MA)을 기본 제공합니다.
⚠️ React Native CLI(bare) 전용 — 네이티브 모듈을 포함하므로 React Native CLI(bare) 프로젝트에서만 동작합니다.
목차
요구 사항
- React Native 0.79+ (New/Old Architecture 모두 지원)
- React 19+
- iOS 13+ / Android 7.0(API 24)+
이 SDK는 다음 라이브러리를 peer dependency 로 사용합니다. 호스트 앱에 반드시 설치되어 있어야 합니다.
| 패키지 | 용도 |
| --- | --- |
| @sgrsoft/react-native-video | 비디오 디코딩/재생 엔진 |
| @react-native-community/netinfo | 네트워크 상태 감지 |
| react-native-device-info | 디바이스/번들 정보 |
| react-native-localize | 로케일 감지(i18n) |
| react-native-orientation-locker | 전체화면 회전 제어 |
| react-native-safe-area-context | 안전 영역 처리 |
| react-native-svg | 벡터 아이콘 렌더 |
| phosphor-react-native | 컨트롤 아이콘 세트 |
설치
# npm
npm install vpe-react-native-cli
# yarn
yarn add vpe-react-native-clipeer dependency 설치:
npm install @sgrsoft/react-native-video @react-native-community/netinfo \
react-native-device-info react-native-localize react-native-orientation-locker \
react-native-safe-area-context react-native-svg phosphor-react-nativeiOS 네이티브 모듈 링크:
cd ios && pod install && cd ..패키지 설치 후 앱을 다시 빌드해야 네이티브 모듈이 링크됩니다.
react-native-orientation-locker,@sgrsoft/react-native-video등은 각 라이브러리의 추가 네이티브 설정(Info.plist 권한, 백그라운드 모드 등)이 필요할 수 있습니다.
빠른 시작
import React, { useRef, useState } from 'react';
import { View, StatusBar } from 'react-native';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
import { VpePlayer } from 'vpe-react-native-cli';
export default function PlayerScreen() {
const playerRef = useRef(null);
const [isFullScreen, setIsFullScreen] = useState(false);
return (
<SafeAreaProvider>
<SafeAreaView edges={isFullScreen ? ['none'] : ['top', 'left', 'right']} />
<StatusBar hidden={isFullScreen} />
<VpePlayer
ref={playerRef}
accessKey="여기에_발급받은_액세스_키"
devTestAppId="com.yourcompany.app"
platform="pub" // 'pub' | 'gov'
stage="prod" // 'prod' | 'beta'
options={{
autostart: true,
playlist: [
{
file: 'https://.../master.m3u8',
poster: 'https://.../poster.jpg',
description: {
title: '샘플 영상',
created_at: '2025.08.20',
profile_name: '채널명',
},
},
],
}}
events={{
ready: () => console.log('플레이어 준비 완료'),
fullScreen: (data) => setIsFullScreen(data.isFullScreen),
backPress: () => {
/* 뒤로가기 네비게이션 처리 */
},
}}
/>
</SafeAreaProvider>
);
}
accessKey와devTestAppId(번들 ID) 는 발급받은 라이선스와 일치해야 인증이 통과됩니다.
Props
VpePlayer 컴포넌트가 받는 최상위 props 입니다.
| Prop | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| accessKey | string | — | 발급받은 라이선스 액세스 키 (인증 필수) |
| devTestAppId | string | 'com.vpereactnative.example' | 라이선스와 매칭되는 앱 번들 ID |
| platform | 'pub' \| 'gov' | 'pub' | 서비스 환경 (공공/일반) |
| stage | 'prod' \| 'beta' | 'prod' | API 스테이지 |
| isDev | boolean | false | 개발 모드 |
| options | VpePlayerOptions | (아래 기본값) | 플레이어 동작/UI 옵션 |
| events | VpePlayerEvents | — | 이벤트 콜백 모음 |
| errorOverride | Component | — | 에러 화면 커스텀 렌더 컴포넌트 ({ error } props 수신) |
| override | object | — | 동작 오버라이드 (fullscreen, nextSource, prevSource 함수) |
| layout | ControlBarLayoutInput | 기본 반응형 레이아웃 | 컨트롤바 커스텀 레이아웃 |
options 상세
options 객체로 전달하며, 미지정 항목은 아래 기본값이 적용됩니다.
재생/표시
| 옵션 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| playlist | PlaylistItem[] | — | 재생 목록 (구조 참고) |
| playIndex | number | 0 | 시작 재생 인덱스 |
| autostart | boolean | true | 자동 재생 |
| muted | boolean | false | 음소거 시작 |
| repeat | boolean | false | 반복 재생 |
| aspectRatio | string | '16/9' | 인라인 화면 비율 |
| objectFit | 'contain' \| 'cover' \| 'fill' \| 'scale-down' | 'contain' | 비디오 리사이즈 모드 |
| autoPause | boolean | false | 앱 백그라운드 진입 시 일시정지 (false면 백그라운드 재생 허용) |
| lowLatencyMode | boolean | true | 저지연 모드(라이브) |
컨트롤/UI
| 옵션 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| controls | boolean | true | 컨트롤바 표시 |
| controlActiveTime | number | 3000 | 컨트롤 자동 숨김 시간(ms) |
| controlBtn | object | (아래) | 버튼별 표시 토글 |
| progressBarColor | string | '#4299f5' | 진행바 색상 |
| playRateSetting | number[] | [0.5,0.75,1,1.5,2] | 배속 옵션 목록 |
| touchGestures | boolean | true | 터치 제스처 |
| keyboardShortcut | boolean | false | 키보드 단축키 |
| modalFullscreen | boolean | false | 전체화면을 Modal로 표시 |
| lang | string | 'ko' | UI 언어 |
| descriptionNotVisible | boolean | false | 영상 설명 숨김 |
| startMutedInfoNotVisible | boolean | false | 음소거 시작 안내 숨김 |
controlBtn 기본값:
controlBtn: {
play: true,
fullscreen: true,
progressBar: true,
volume: false,
times: true,
pictureInPicture: true,
setting: true,
subtitle: true,
}자막 스타일
| 옵션 | 타입 | 기본값 |
| --- | --- | --- |
| captionStyle.fontSize | number | 12 |
| captionStyle.color | string | '#ffffff' |
| captionStyle.backgroundColor | string | 'rgba(0,0,0,0.4)' |
| captionStyle.edgeStyle | 'none' \| 'dropshadow' \| 'raised' \| 'depressed' \| 'uniform' | 'dropshadow' |
워터마크
| 옵션 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| visibleWatermark | boolean | false | 워터마크 표시 |
| watermarkText | string | 'NAVER CLOUD PLATFORM' | 표시 문구 |
| watermarkConfig.randPosition | boolean | true | 위치 랜덤 이동 |
| watermarkConfig.randPositionInterVal | number | 3000 | 이동 주기(ms) |
| watermarkConfig.x / .y | number | 10 / 10 | 고정 위치 좌표 |
| watermarkConfig.opacity | number | 0.5 | 투명도 |
보안 / 고급
| 옵션 | 타입 | 기본값 | 설명 |
| --- | --- | --- | --- |
| screenRecordingPrevention | boolean | false | 스크린샷/녹화 방지 |
| allowsPictureInPicture | boolean | false | PIP 허용 |
| staysActiveInBackground | boolean | false | 백그라운드 활성 유지 |
| setStartTime | Date \| string \| null | null | 프리미어(예약 공개) 시작 시각 |
| token | string | '' | 스트리밍 URL에 부착할 인증 토큰 |
| icon | IconOverrides | — | 컨트롤 아이콘 오버라이드 |
playlist 아이템 구조
{
file: 'https://.../master.m3u8', // 필수: HLS/DASH/MP4 URL
poster: 'https://.../poster.jpg', // 포스터 이미지
drm: { // 선택: DRM 설정 (아래 DRM 절 참고)
type: 'widevine',
licenseServer: 'https://...',
},
description: { // 메타데이터
title: '영상 제목',
created_at: '2025.08.20',
profile_name: '채널명',
profile_image: 'https://.../profile.png',
},
vtt: [ // 선택: 자막 트랙
{ id: 'ko', file: 'https://.../ko.vtt', label: '한국어', default: true },
{ id: 'en', file: 'https://.../en.vtt', label: 'English' },
],
}
playlist가 단일 객체/문자열이면 내부에서 1개짜리 배열로 정규화됩니다.
events 콜백
events 객체로 전달합니다. 모두 선택 사항입니다.
| 이벤트 | 시그니처 | 설명 |
| --- | --- | --- |
| ready | () => void | 플레이어 준비 완료 |
| play | () => void | 재생 시작 |
| pause | () => void | 일시정지 |
| ended | () => void | 재생 종료 |
| seeking | () => void | 탐색 시작 |
| seeked | () => void | 탐색 완료 |
| waiting | () => void | 버퍼링 |
| volumechange | (data) => void | 음소거 상태 변경 ({ muted }) |
| timeupdate | (data) => void | 재생 위치 갱신 |
| fullscreen | (data) => void | 전체화면 토글 ({ isFullScreen }) |
| fullscreen_on / fullscreen_off | () => void | 전체화면 진입/이탈 |
| controlbarActive / controlbarDeactive | () => void | 컨트롤바 표시/숨김 |
| nextTrack / prevTrack | (data) => void | 다음/이전 트랙 전환 ({ file, poster, title, ... }) |
| error | (data) => void | 에러 발생 |
| backPress | () => void | 뒤로가기 버튼 — 네비게이션은 직접 처리 |
Ref API (명령형 제어)
ref 를 통해 플레이어를 직접 제어할 수 있습니다.
const playerRef = useRef(null);
// ...
playerRef.current.play();
playerRef.current.currentTime(30); // 30초로 이동| 메서드 | 설명 |
| --- | --- |
| play() | 재생 (종료 상태면 처음부터) |
| pause() | 일시정지 |
| currentTime(time) | 지정 시간(초)으로 탐색 |
| muted() | 음소거 토글 |
| fullscreen() | 전체화면 토글 (Promise) |
| pip() | PIP 토글 (Promise) |
| next() / prev() | 다음/이전 트랙 |
| controlBarActive() / controlBarDeactive() | 컨트롤바 강제 표시/숨김 |
| tokenChange(token) | 스트리밍 토큰 교체 |
| addNextSource(item) / addPrevSource(item) | 플레이리스트 끝/앞에 소스 추가 |
| uiHidden() / uiVisible() | 컨트롤 UI 숨김/표시 |
| controlBarBtnStateUpdate(btns) | 컨트롤 버튼 표시 상태 일괄 변경 |
| destroy() | 플레이어 해제 (Promise) |
| tokenChange(token) | 스트리밍 토큰 교체 (재생 URL 뒤에 부착되어 즉시 재적용) |
| addListener(eventName, listener) | 리스너 등록 ({ remove } 반환) |
토큰은 ref 의
tokenChange(token)또는options.token값 변경 둘 다로 교체할 수 있습니다. 두 경우 모두 재생 URL 뒤에 부착되어 자동으로 재적용됩니다.
주요 기능 가이드
DRM
playlist 아이템의 drm 필드에 DRM 설정을 전달합니다. 형식은 내부적으로
@sgrsoft/react-native-video 의 drm prop 으로 전달되므로 해당 라이브러리의
Widevine(Android) / FairPlay(iOS) 규격을 따릅니다.
playlist: [
{
file: 'https://.../stream.mpd',
drm: {
type: 'widevine',
licenseServer: 'https://license.example.com/widevine',
headers: { Authorization: 'Bearer ...' },
},
},
];자막(VTT)
playlist[].vtt 배열로 자막 트랙을 지정합니다. .vtt 직접 파일과 HLS 자막
플레이리스트(.m3u8) 모두 지원하며, SDK가 세그먼트를 받아 파싱합니다.
default: true 인 트랙이 처음 선택되고, 컨트롤바의 자막 버튼으로 토글합니다.
워터마크
visibleWatermark: true 와 watermarkText 로 사용자 식별용 워터마크를 표시합니다.
watermarkConfig.randPosition 을 켜면 캡처 회피를 위해 위치가 주기적으로 이동합니다.
화면 녹화 방지
options={{ screenRecordingPrevention: true }}react-native-capture-protection 을 이용해 스크린샷/화면 녹화를 차단합니다.
PIP (Picture-in-Picture)
options={{ allowsPictureInPicture: true }}
// 제어
playerRef.current.pip();autoPause: false 와 함께 사용하면 앱 이탈 시 자동 PIP 진입이 가능합니다.
프리미어(예약 공개)
setStartTime 에 미래 시각을 주면 카운트다운 오버레이가 표시되고, 시작 시각이
되면 경과 시간만큼 오프셋하여 자동 재생됩니다(라이브 프리미어 방식).
options={{ setStartTime: new Date('2026-07-01T20:00:00') }}커스텀 컨트롤 레이아웃
layout prop 으로 컨트롤바 구성을 완전히 재정의할 수 있습니다. 섹션
(top/upper/center/lower/bottom)별 그룹 배열로 구성하며, 아이템은
이름 문자열('PlayBtn', 'SeekBar', 'FullscreenBtn' 등) 또는 임의의
ReactNode 를 넣을 수 있습니다. PC/모바일/전체화면 반응형, live/vod 변형도 지원합니다.
const layout = {
mobile: {
bottom: [
{ align: 'left', items: ['PlayBtn', 'CurrentTimeBtn', 'DurationBtn'] },
{ align: 'right', items: ['SubtitleBtn', 'SettingBtn', 'FullscreenBtn'] },
],
center: [{ items: ['SeekBar'] }],
},
};
<VpePlayer layout={layout} /* ... */ />지정 가능한 아이템 이름: PlayBtn, VolumeBtn, MuteBtn, TimeBtn,
CurrentTimeBtn, DurationBtn, SeekBar, SubtitleBtn, FullscreenBtn,
SettingBtn, PrevBtn, NextBtn, NextPrevBtn, SkipForwardBtn,
SkipBackBtn, BackBtn, ShareBtn, MetaDesc, BigPlayBtn,
NextVideoInfo, Blank 등.
아이콘 오버라이드
options.icon 으로 각 컨트롤 아이콘을 교체합니다. 값으로 JSX 요소, 원격 URL
문자열, require() 로컬 에셋(number), 또는 () => ReactNode 함수를 허용합니다.
import { CaretLeftIcon } from 'phosphor-react-native';
options={{
icon: {
play: <PlayCustomIcon />,
back: () => <CaretLeftIcon size={22} color="#fff" />,
bigPlay: require('./assets/play.png'),
fullscreen: 'https://cdn.example.com/fs.png',
},
}}오버라이드 가능한 키: bigPlay, play, pause, replay, prev, next,
subtitle, subtitleOff, fullscreen, fullscreenExit, volumeFull,
volumeMid, volumeMute, setting, back, share, skipForward, skipBack.
예제 앱 실행
저장소에는 모든 기능을 보여주는 예제 앱(example/)이 포함되어 있습니다.
yarn # 의존성 설치 (워크스페이스)
yarn example start # Metro 시작
# 다른 터미널에서
yarn example ios # iOS 실행
yarn example android # Android 실행예제에는 기본 재생, DRM, PIP, 워터마크, 자막, 화질/배속, 프리미어(StartTime), 커스텀 레이아웃, 아이콘/에러 오버라이드, 화면 녹화 방지 등 데모 화면이 있습니다.
기여
라이선스
MIT © SGRSOFT
홈페이지: https://vpe.sgrsoft.com
create-react-native-library 로 제작되었습니다.
