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.
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
aspectRatio: '16/9', // Set the aspect ratio
}}
/>
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:
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
aspectRatio: '16/9',
objectFit: 'cover', // Configures Full screen (preserves the aspect ratio and fills the screen)
}}
/>
Control bar
controls (show control bar)
You can set to display the control bar with the controls property.
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
controls: false, // Hide control bar (true: Show control bar)
}}
/>
controlBtn (control bar button UI)
You can set usage of the control bar button UI with the controlBtn property.
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
controls: true,
controlBtn: {
play: true, // Playback
progressBar: true, // Enable/disable playback bar
fullscreen: true, // Switch to Full screen
volume: true, // Volume control
times: true, // Playback time
setting: true, // Settings
},
}}
/>
progressBarColor (control bar color)
You can set the color of the control bar on the video search slider with the progressBarColor property.
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
progressBarColor: "#ff0000", // Color code (red)
}}
/>
controlActiveTime (control bar display duration)
You can set the time when the control bar is displayed with the controlActiveTime property.
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.
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
controlActiveTime: 3000, // Set the control bar display time (3000=3 seconds)
}}
/>
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 (
<VpePlayer
ref={playerRef}
events={{
timeupdate: (res) => {
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.
<VpePlayer
options={{
playlist: [
{ file: 'https://CDNdomain/example_video_01.mp4' },
],
captionStyle: {
fontSize: 12,
color: '#FFFFFF',
backgroundColor: 'rgba(0, 0, 0, 0.7)',
edgeStyle: 'dropshadow', // dropshadow, raised, depressed, uniform
},
}}
/>
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, andbottom - 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. |
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); bypassTimeBtnwhen 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 (
<VpePlayer
accessKey={'YOUR_ACCESS_KEY'}
layout={myLayout}
options={{
playlist: [{ file: 'https://CDNdomain/master.m3u8' }],
aspectRatio: '16/9',
}}
/>
);
}
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: falseis the case, double-tap is disabled (only single-tap toggle works).