Available in Classic and VPC
It explains how to modify the script code to configure UI-related options.
- For descriptions of properties to set options, see player settings.
- The available options may vary depending on your subscription plan.
Default option
aspectRatio (interface ratio)
This property sets the aspect ratio of the player component.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
aspectRatio: "16/9", // Set the aspect ratio
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
objectFit (Full screen)
This property sets how the video fits the component.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
objectFit: "cover", // Specifies how the video is displayed
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
Language (multilingual)
Set the language used in the player. If not set, it follows the language used in the browser.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
lang: "ko", // language setting
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
Control bar
controls (show control bar)
Set whether to display the default control bar UI.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
controls: true, // Set whether to display the control bar
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
controlBtn (control bar button UI)
Individually set the visibility of control bar buttons.
Available only with the standard plan.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
controlBtn: {
play: true, // Playback
progressBar: true, // Control bar
fullscreen: true, // Full screen
volume: true, // Volume
times: true, // Remaining time
pictureInPicture: true, // PIP
setting: true, // Settings
subtitle: true, // Subtitle
},
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
progressBarColor (control bar color)
Set the progress color of the control bar.
Available only with the standard plan.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
progressBarColor: "#2e6ae0", // Specifies the control bar progress color
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
controlActiveTime (control bar display duration)
Sets the duration for which the control bar is displayed.
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.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
controlActiveTime: 3000, // Sets the control bar display duration (ms)
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
UI (fix control bar UI)
Designate the UI type.
Available only with the standard plan.
- The mobile UI provides
touchGestures, while the PC UI provideskeyboardShortcut.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
ui: "mobile", // UI type setting
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
Subtitles
Subtitle settings (vtt)
Connect the VTT subtitle.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Video (MP4)
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
options={{
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
poster: "https://CDNdomain/example_video_01.png",
vtt: [
{
id: "ko",
file: "https://CDNdomain/example_video_01.vtt",
label: "Korean",
default: true, // Default subtitle settings
},
],
},
],
}}
/>
);
}
captionType (subtitle rendering type)
This option determines how subtitles are rendered. You can choose "html" (default) or "native", and the behavior will vary depending on whether design consistency is prioritized or OS accessibility settings are prioritized.
| Item | "html" (default) |
"native" |
|---|---|---|
| Rendering entity | The SDK draws subtitles directly <div> on top of the player. |
Uses the default ::cue rendering of the browser/OS. |
| captionStyle option | Applied to all (directly controlled with inline styles) | Ignored (consistent styling not possible due to browser-specific ::cue support differences) |
| OS accessibility subtitle settings | No effect (on mobile, the native subtitle UI is blocked by track.mode="hidden", ensuring consistent styling) |
Directly reflected (follows iOS , and Android Settings > Accessibility > Subtitles & Captioning and Android Settings > Accessibility > Caption preferences) |
| Recommended case | Design consistency prioritized (e.g., dark mode UI, brand-colored subtitles) | Web accessibility prioritized (services that must follow OS accessibility settings due to visual assistance policies) |
According to the Web Accessibility (WCAG) guidelines, users must be able to adjust subtitle fonts, sizes, and colors themselves. captionType: "native" directly reflects the OS-provided accessibility subtitle settings, delivering the closest experience for users who require visual assistance.
html mode: Styled directly with captionStyle (default)
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
options={{
captionType: "html", // Optional. Default value
captionStyle: {
fontSize: 20,
color: "#FFFF00",
edgeStyle: "uniform",
},
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
vtt: [{ id: "ko", file: "https://CDNdomain/example_video_01.vtt", label: "Korean", default: true }],
},
],
}}
/>
Native mode: Follows OS accessibility subtitle settings as is
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
options={{
captionType: "native",
// captionStyle is not applied.
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
vtt: [{ id: "ko", file: "https://CDNdomain/example_video_01.vtt", label: "Korean", default: true }],
},
],
}}
/>
captionStyle (caption style)
Caption font size, color, background, edge treatment, line spacing, and position are directly configurable as options. Applies only when captionType is set to "html" (default), and is ignored in "native" mode. Can be used when consistent subtitle styling is required, such as brand colors or dark mode UI.
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
options={{
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
vtt: [
{
id: "ko",
file: "https://CDNdomain/example_video_01.vtt",
label: "Korean",
default: true,
},
],
},
],
captionStyle: {
fontSize: {
pc: 18, // caption font size (px or %)
mobile: 14,
},
color: "#ffffff",
edgeStyle: "uniform", // Text edge style (dropshadow, raised, depressed, uniform)
bottomOffset: {
pc: 30, // Move higher to avoid overlapping with the control bar
mobile: 50,
},
sidePadding: {
pc: 60, // Wider left and right margins
mobile: 40,
},
lineHeight: {
pc: 1, // Tighter subtitle line spacing
mobile: 1.2,
},
},
}}
/>
captionStyle property
If unspecified, the default value is applied automatically, and when options are provided, they are deep-merged with the default. (Example: If only { fontSize: 20 } is passed, it applies fontSize=20 plus defaults for the rest)
Responsive branching: fontSize, lineHeight, bottomOffset, and sidePadding can be designated as a single value or a { pc, mobile } object.
| Properties | Type | Default value | Description |
|---|---|---|---|
fontSize |
number \| string \| { pc?, mobile? } |
{ pc: 20, mobile: 14 } |
Caption font size (in px/CSS). PC/mobile branching supported |
fontFamily |
string |
— | Caption font (CSS font-family) |
color |
string |
#ffffff |
Subtitle text color (CSS color value) |
backgroundColor |
string |
transparent |
Subtitle box background color Example: rgba(0,0,0,0.4) |
opacity |
number |
1 |
Subtitle text overall opacity (0–1) |
lineHeight |
number \| string \| { pc?, mobile? } |
{ pc: 1.3, mobile: 1.2 } |
Subtitle line spacing (multiplier) PC/mobile branching supported |
edgeStyle |
none \| dropshadow \| raised \| depressed \| uniform |
uniform |
Subtitle text edge treatment method (high readability on both light and dark backgrounds) |
bottomOffset |
number \| { pc?, mobile? } |
{ pc: 30, mobile: 10 } |
Spacing from bottom of player (px) Adjust to avoid overlapping with the control bar PC/mobile branching supported |
sidePadding |
number \| { pc?, mobile? } |
{ pc: 60, mobile: 40 } |
Left/right safe component (px) PC/mobile branching supported |
padding |
number \| string |
3px 5px |
Subtitle text box inner padding (CSS padding value) |
edgeStyle type: none (no effect)/dropshadow (shadow)/raised (raised effect)/depressed (inset effect)/uniform (outline in 4 directions, default recommended)
Layout system
By using the layout system, you can declaratively define the placement of control bar buttons, area composition, and insertion of custom components based on JSON. You can separately manage screen environments (PC/mobile/Full screen) and content types (VOD/Live).
- Available only with the standard plan.
- Layout JSON can be visually edited in the UI Editor, and the results can be directly applied to the code. For detailed structure and attributes, see the Layout system guide.
Default layout configuration
Use to order define the section order, and place rows in each section. You can insert built-in components or custom elements into the items of a row.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
const layout = {
pc: {
vod: {
order: ["top", "center", "bottom"],
top: [{ items: ["MetaDesc"] }],
center: [{ items: ["BigPlayBtn"], align: "center" }],
bottom: [
{ items: ["ProgressBar"] },
{ items: ["PlayBtn", "VolumeBtn", "TimeBtn"], wrapper: "Group" },
{ wrapper: "Blank", items: [] },
{ items: ["SettingBtn", "PipBtn", "FullscreenBtn"], wrapper: "Group" },
],
},
},
};
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
layout={layout}
options={{
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
Layout type
layout props can be passed in the following 3 forms.
// 1) Single layout — one control bar configuration without branching for Live/VOD/device
type ControlBarLayout = {
order?: string[];
top?: Group[];
upper?: Group[];
center?: Group[];
lower?: Group[];
bottom?: Group[];
};
// 2) Live/VOD branching
type ControlBarLayoutVariant = {
live: ControlBarLayout;
vod: ControlBarLayout;
};
// 3) Responsive (PC/mobile/Full screen branching)
type ControlBarLayoutResponsive = {
pc: { live: ControlBarLayout; vod: ControlBarLayout };
mobile: { live: ControlBarLayout; vod: ControlBarLayout };
fullscreen: { live: ControlBarLayout; vod: ControlBarLayout };
breakpoint?: number; // default 768
};
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": { }
}
}
layout.json
Section and sequence
The order array determines the rendering order. The default sections are top, upper, center, lower, and bottom.
{
"order": ["top", "upper", "center", "lower", "bottom"],
"top": [
{ "items": ["MetaDesc"] },
{ "wrapper": "Blank", "items": [], "align": "left" },
{ "items": ["ShareBtn"] }
],
"center": [
{ "items": ["BigPlayBtn"], "align": "center" }
],
"bottom": [
{ "items": ["ProgressBar"] },
{ "items": ["PlayBtn", "VolumeBtn", "TimeDisplay"], "align": "left" },
{ "items": ["SettingBtn", "PIPBtn", "FullscreenBtn"], "align": "right" }
]
}
pc.vod.json
Row configuration
Each section is composed of multiple rows. A row places buttons or components through an items array, and adjusts alignment and grouping using align and wrapper.
| Key | Type | Description |
|---|---|---|
key |
string |
Group identifier. For runtime layout() merge, replace among groups of the same key (recommended) |
items |
(string \| ReactNode)[] |
Control list to be placed in a row (built-in keys or custom components) |
align |
left \| center \| right |
Content arrangement in rows |
wrapper |
"Group" \| "Blank" |
Wrapper type to apply to a row (group = grouping, blank = empty space/spacing) |
cap |
number |
Limit on the number of items displayed within a row |
noPadding |
boolean |
Remove left and right padding from group |
Default layout example
If you assign key to each group, you can safely replace only specific groups during runtime merging.
const layout: ControlBarLayout = {
top: [],
center: [{ key: "bigPlayBtn", items: ["BigPlayBtn"] }],
bottom: [
{ key: "play", items: ["PlayBtn"], wrapper: "Group", noPadding: true },
{ key: "volume", items: ["VolumeBtn"], wrapper: "Group" },
{ key: "time", items: ["TimeBtn"], wrapper: "Group" },
{ key: "blank", wrapper: "Blank", items: [] },
{ key: "right", items: ["SubtitleBtn", "FullscreenBtn"], cap: 2, wrapper: "Group" },
],
};
Insert a custom component
If you pass your own custom components instead of built-in keys to the items array of the layout, you can place custom UI at the desired position within the control bar.
import Hls from "hls.js";
import dashjs from "dashjs";
import { VpePlayer } from "@sgrsoft/vpe-react-sdk";
// Custom logo component
function Logo() {
return (
<div style={{ padding: "0 15px" }}>
<a href="https://example.com" target="_blank">
<img
src="https://example.com/logo.webp"
style={{ height: 24 }}
alt="Logo" />
</a>
</div>
);
}
const layout = {
pc: {
vod: {
order: ["top", "center", "bottom"],
top: [{ items: ["MetaDesc"] }],
center: [{ items: ["BigPlayBtn"], align: "center" }],
bottom: [
{ items: ["PlayBtn", "PrevBtn", "NextBtn"], wrapper: "Group" },
{ items: ["VolumeBtn"], wrapper: "Group" },
{ items: ["TimeBtn"], wrapper: "Group" },
{ wrapper: "Blank", items: [] },
{ items: [Logo()], wrapper: "Group" }, // Custom component
{ items: ["SubtitleBtn", "PipBtn", "SettingBtn", "FullscreenBtn"], cap: 2, wrapper: "Group" },
],
},
},
};
export function App() {
return (
<VpePlayer
accessKey="YOUR_ACCESS_KEY"
hls={Hls}
dashjs={dashjs}
platform="pub"
layout={layout}
options={{
playlist: [
{
file: "https://CDNdomain/example_video_01.mp4",
},
],
}}
/>
);
}
Realtime change (ref)
By calling playerRef.current?.layout(nextLayout, merge?), you can dynamically change the layout even during playback. The default value of the second factor merge is true.
Merge rule (merge: True)
- Among
top/upper/center/lower/bottom/order, sections not defined in next will retain the base. - Group merge within a section is based on
keyas follows:- When a group has the same key in both base and next, it will be replaced by next.
- Keys that exist only in base will retain the base.
- Keys that exist only in next will be appended to the end of the result.
- Groups without a key in next will be appended to the end of the result (considered as newly added).
- If both groups have no key, the entire section will be replaced (backward compatibility).
Example: Replace certain groups only
// base (default pcLayout.vod)
// bottom: [
// { key: "play", items: ["PlayBtn"] },
// { key: "volume", items: ["VolumeBtn"] },
// { key: "time", items: ["TimeBtn"] },
// { key: "blank", wrapper: "Blank", items: [] },
// { key: "right", items: ["SubtitleBtn", "FullscreenBtn"] },
// ]
playerRef.current?.layout({
bottom: [{ key: "right", items: ["SubtitleBtn", "PipBtn", "SettingBtn", "FullscreenBtn"] }],
});
// Result: Keep play/volume/time/blank, replace only right.
Example: Add a new group
playerRef.current?.layout({
bottom: [{ key: "extra", items: ["ShareBtn"] }],
});
// Result: Existing 5 groups + append extra (ShareBtn) at the end
Example: Replace all sections (merge: False)
playerRef.current?.layout(
{ bottom: [{ items: ["PlayBtn"] }] },
false, // Replace all
);