메서드
PlayerHandle ref를 사용하여 플레이어를 프로그래밍 방식으로 제어할 수 있습니다.
PlayerHandle ref 사용법
"use client";
import Hls from "hls.js";
import { VpePlayer, type PlayerHandle } from "@sgrsoft/vpe-react-sdk";
import { useRef } from "react";
export default function PlayerPage() {
const playerRef = useRef<PlayerHandle>(null);
const handlePlay = () => {
playerRef.current?.play();
};
const handleSeek = () => {
playerRef.current?.currentTime(30); // 30초 위치로 이동
};
return (
<div>
<VpePlayer
ref={playerRef}
hls={Hls}
accessKey="YOUR_ACCESS_KEY"
options={{
playlist: [{
file: "https://example.com/video/master.m3u8",
}],
}}
/>
<div>
<button onClick={handlePlay}>Play</button>
<button onClick={handleSeek}>Seek to 30s</button>
</div>
</div>
);
}재생 제어
| 메서드 | 설명 |
|---|---|
| play() | 영상을 재생합니다. |
| pause() | 영상을 일시정지합니다. |
| togglePlay() | 재생/일시정지 상태를 토글합니다. |
| mute() | 음소거를 토글합니다. |
| prev() | 이전 플레이리스트 항목으로 이동합니다. |
| next() | 다음 플레이리스트 항목으로 이동합니다. |
| currentTime(time?: number) | 지정한 시간(초)으로 이동합니다. 인자를 생략하면 0초로 이동합니다. |
| getCurrentTime() | 현재 재생 위치(초)를 반환합니다. |
| getDuration() | 전체 영상 길이(초)를 반환합니다. |
볼륨 제어
| 메서드 | 설명 |
|---|---|
| volume(vol?: number) | 볼륨을 설정합니다. (0~1) |
자막 제어
| 메서드 | 설명 |
|---|---|
| toggleSubtitle() | 자막 표시 여부를 토글합니다. |
| setSubtitleEnabled(enabled: boolean) | 자막 표시 여부를 설정합니다. |
| selectSubTitle(idx: number) | vtt 배열 인덱스로 자막 트랙을 선택합니다. |
UI 제어
| 메서드 | 설명 |
|---|---|
| fullscreen() | 전체화면을 토글합니다. |
| fullscreenOn() | 전체화면 모드로 전환합니다. |
| fullScreenOff() | 전체화면 모드를 해제합니다. |
| pip() | Picture in Picture 모드를 토글합니다. |
| uiHidden() | 플레이어 UI를 숨깁니다. |
| uiVisible() | 플레이어 UI를 표시합니다. |
| controlBarActive() | 컨트롤바를 활성화(표시)합니다. |
| controlBarDeactive() | 컨트롤바를 비활성화(숨김)합니다. |
| changeUiMode(mode: "pc" | "mobile" | "fullscreen" | null) | UI 모드를 변경합니다. null을 전달하면 기본 모드로 복원됩니다. |
| layout(nextLayout, merge?: boolean) | 레이아웃을 동적으로 변경합니다. merge가 true(기본값)이면 기존 레이아웃에 병합합니다. |
실시간 레이아웃 전환 예제
layout(nextLayout, merge?) — 두 번째 인자 merge의 기본값은 true입니다. Group에 key를 지정하면 같은 key의 Group끼리만 교체되고, 그 외는 base가 유지됩니다. 자세한 규칙은 레이아웃 시스템 페이지를 참조하세요.
// 특정 Group만 교체 — base의 같은 key Group이 교체됨
playerRef.current?.layout({
bottom: [
{ key: "right", items: ["SubtitleBtn", "PipBtn", "SettingBtn", "FullscreenBtn"] },
],
});
// 새 Group 추가 — 기존 Group 뒤에 append
playerRef.current?.layout({
bottom: [{ key: "extra", items: ["ShareBtn"] }],
});
// section 전체 교체 — merge: false
playerRef.current?.layout(
{
bottom: [
{ items: ["PlayBtn", "TimeBtn"], align: "left" },
{ items: ["FullscreenBtn"], align: "right" },
],
},
false,
);옵션 / 상태 제어
| 메서드 | 설명 |
|---|---|
| changeOptions(nextOptions: Partial<PlayerOptions>) | 플레이어 옵션을 동적으로 변경합니다. |
| changePlayMode(mode: "vod" | "live" | null) | 재생 모드(VOD/Live)를 변경합니다. null을 전달하면 기본 모드로 복원됩니다. |
| tokenChange(token: string) | 재생 중 Secure Token을 교체합니다. |
// 옵션 동적 변경
playerRef.current?.changeOptions({
muted: true,
autostart: false,
});
// 재생 모드 변경
playerRef.current?.changePlayMode("live");
// 토큰 교체
playerRef.current?.tokenChange("token=st=...~exp=...~acl=...");플레이리스트 제어
| 메서드 | 설명 |
|---|---|
| addNextSource(source: PlaylistItem | PlaylistItem[]) | 다음 영상을 플레이리스트에 추가합니다. |
| addPrevSource(source: PlaylistItem | PlaylistItem[]) | 이전 영상을 플레이리스트에 추가합니다. |
// 단일 영상 추가
playerRef.current?.addNextSource({
file: "https://example.com/new_video.mp4",
poster: "https://example.com/new_poster.jpg",
description: { title: "새로운 영상" },
});
// 여러 영상 동시 추가
playerRef.current?.addPrevSource([
{ file: "https://example.com/video_1.mp4" },
{ file: "https://example.com/video_2.mp4" },
]);이벤트
| 메서드 | 설명 |
|---|---|
| on(type: PlayerEventType | "*", callback) | 이벤트 리스너를 등록합니다. 해제 함수를 반환합니다. |
// ref를 통한 이벤트 리스너 등록
const unsubscribe = playerRef.current?.on("play", (event) => {
console.log("재생 시작", event);
});
// 모든 이벤트 수신
const unsubscribeAll = playerRef.current?.on("*", (event) => {
console.log(event.type, event);
});
// 이벤트 리스너 해제
unsubscribe?.();라이프사이클
| 메서드 | 설명 |
|---|---|
| destroy() | 플레이어 인스턴스를 제거합니다. |