---
title: "Player UI"
slug: "vpe-rn-player-ui"
updated: 2026-09-17T09:22:36Z
published: 2026-09-17T09:22:36Z
canonical: "guide.ncloud-docs.com/vpe-rn-player-ui"
stale: true
---
> ## Documentation Index
> Fetch the complete documentation index at: https://guide.ncloud-docs.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Player UI
Available in Classic and VPC
Learn about options for configuring and customizing the player UI.
## Default option
### aspectRatio (interface ratio)
You can specify aspect ratio of the player with the `aspectRatio` property. This applies only when the player does not have a fixed size (width, height). The set aspect ratio is maintained even if the container size changes.
```
```
### objectFit (Full screen)
You can set Full screen with the `objectFit` property. The following example sets the player to Full screen while maintaining the playback source ratio:
```
```
## Control bar
### controls (show control bar)
You can set to display the control bar with the `controls` property.
```
```
### controlBtn (control bar button UI)
You can set usage of the control bar button UI with the `controlBtn` property.
```
```
### progressBarColor (control bar color)
You can set the color of the control bar on the video search slider with the `progressBarColor` property.
```
```
### controlActiveTime (control bar display duration)
You can set the time when the control bar is displayed with the `controlActiveTime` property.
Note
If set to `controlActiveTime: 0`, the control bar will not be hidden automatically and will always be displayed. This is useful for interfaces where the UI should always be shown, such as live commerce.
```
```
### Dynamic modification of control bar UI
You can dynamically modify the button UI according to video length. For example, if the video length is less than 10 seconds, you can set the Full screen, PIP, and settings buttons not to be displayed.
```
const playerRef = useRef(null);
return (
{
if (res.duration < 10) {
playerRef.current.controlBarBtnStateUpdate({
fullscreen: false,
pictureInPicture: false,
setting: false,
});
}
},
}}
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
controlBtn: {
play: true,
fullscreen: true,
volume: true,
times: true,
setting: true,
subtitle: false,
},
}}
/>
);
```
## Subtitle UI configuration
You can set the size, background, and style of the subtitles.
```
```
## Layout system
Supported platforms: `Android` `iOS`
The VPE React Native SDK provides a layout-driven ControlBar system ported from the web SDK. With JSON declarations, you can define the placement and grouping of control buttons, as well as configure layouts by screen environment (PC/mobile/Full screen) and content type (VOD/Live).
### Overview
You can pass a layout object to the `layout` prop to fully customize all components of the ControlBar. If the `layout` prop is not provided, the default responsive layout will be used.
- 5 sections: `top`, `upper`, `center`, `lower`, and `bottom`
- Environment-specific separation: `pc`/`mobile`/`fullscreen`
- Content-type separation: `vod`/`live`
- Mobile judgment breakpoint: Default 768
- Automatically merge custom and default layouts (section-based replacement)
### Configuration structure
The top-level keys are divided into `pc`, `mobile`, and `fullscreen`, and each environment defines the `vod` and `live` layouts.
```
{
"pc": {
"vod": {},
"live": {}
},
"mobile": {
"vod": {},
"live": {}
},
"fullscreen": {
"vod": {},
"live": {}
},
"breakpoint": 768
}
```
`layout.json`
Each variant consists of the order of five sections and the alignment of groups/items.
```
{
"order": ["top", "upper", "center", "lower", "bottom"],
"top": [
{ "wrapper": "Group", "items": ["BackBtn"] },
{ "wrapper": "Blank" },
{ "wrapper": "Group", "items": ["ShareBtn", "SettingBtn"] }
],
"center": [
{ "wrapper": "Blank", "items": ["BigPlayBtn"] }
],
"bottom": {
"seekbar": ["SeekBar"],
"left": [
{ "wrapper": "Group", "items": ["PlayBtn", "VolumeBtn"] },
{ "wrapper": "Group", "items": ["TimeBtn"] }
],
"right": [
{ "wrapper": "Group", "items": ["SubtitleBtn", "FullscreenBtn"] }
]
}
}
```
`variant.json`
### Available control items
You can use the following names in the `items` array.
| Name | Description |
| --- | --- |
| `PlayBtn` | Play/pause/replay toggle (isEnded branch) |
| `BigPlayBtn` | Central large play button If playlist > 1, prev/next are automatically displayed on both sides |
| `VolumeBtn` | Volume toggle |
| `MuteBtn` | Mute-only button |
| `TimeBtn` | Current time/total time or LIVE indicator |
| `CurrentTimeBtn` | Current playback time (separated version) |
| `DurationBtn` | Total playback time (separated version) |
| `SeekBar` | Progress rate slider |
| `FullscreenBtn` | Full screen toggle |
| `SubtitleBtn` | Immediate subtitle toggle (without going through SettingsMenu) |
| `SettingBtn` | SettingsMenu toggle (quality/playback speed/subtitles) |
| `PrevBtn` | Previous track |
| `NextBtn` | Next track |
| `NextPrevBtn` | Integrated prev/next button |
| `BackBtn` | Back. Calls `events.backPress` |
| `ShareBtn` | Calls the React Native Share API |
| `SkipForwardBtn` | Skip forward 10 seconds |
| `SkipBackBtn` | Skip backward 10 seconds |
| `MetaDesc` | Video metadata (title/profile/upload date) |
| `Blank` | If no child, use spacer (`flex:1`); If child exists, use row for alignment. |
Note
In React Native, the explicit PIP button (`PipBtn`) is non-standard and has been deprecated. Use `playerRef.current.pip()` or the `options.allowsPictureInPicture` lifecycle instead.
### Wrapper type
- `Group` — Default pill-shaped group (semi-transparent background, borderRadius 999). If single child, render as circle (`aspectRatio: 1`); bypass `TimeBtn` when standalone.
- `Blank` — If no child, use spacer; If child exists, apply align row.
### Basic usage example
```
import { VpePlayer } from 'vpe-react-native';
const myLayout = {
pc: {
vod: {
order: ['top', 'center', 'bottom'],
top: [
{ wrapper: 'Group', items: ['BackBtn'] },
{ wrapper: 'Blank' },
{ wrapper: 'Group', items: ['ShareBtn', 'SettingBtn'] },
],
center: [{ wrapper: 'Blank', items: ['BigPlayBtn'] }],
bottom: {
seekbar: ['SeekBar'],
left: [
{ wrapper: 'Group', items: ['PlayBtn', 'VolumeBtn'] },
{ wrapper: 'Group', items: ['TimeBtn'] },
],
right: [
{ wrapper: 'Group', items: ['SubtitleBtn', 'FullscreenBtn'] },
],
},
},
live: { /* ... */ },
},
mobile: {
vod: { /* ... */ },
live: { /* ... */ },
},
fullscreen: {
vod: { /* ... */ },
live: { /* ... */ },
},
breakpoint: 768,
};
export default function MyPlayer() {
return (
);
}
```
### Layout merge behavior
User-provided layout is automatically merged with the default layout. If you define only specific environments (for example, `pc` only) or sections, the default layout is used for the rest. However, replacement is performed on a **per-section basis**. Defining a section completely replaces the corresponding section in the default layout.
In development (`__DEV__`) mode, console warnings are displayed for invalid item names or missing required sections.
### Touch gestures
ControlBar handles single/double-tap gestures. The interface is divided into left/center/right thirds; on double-tap, cumulative 10-second seek occurs, while single-tap toggles the control bar.
- Single-tap toggle has a 300 ms delay (during this time, if a second tap occurs, it is processed as a double-tap to prevent control flicker).
- Double-tap left/right → cumulative 10-second seek (actual seek executed after 500 ms).
- When `options.touchGestures: false` is the case, double-tap is disabled (only single-tap toggle works).
## Related guides
- [Custom icon (IconOverrides)](https://developer.vpe.naverncp.com/docs/rn/custom-icon)
- [Player UI options](https://developer.vpe.naverncp.com/docs/rn/player-ui)
- [Player UX options](https://developer.vpe.naverncp.com/docs/rn/player-ux)