Plus · VideoPlayer

VideoPlayer

Used to play video

Demos

How to import

import { VideoPlayer } from '@fibrous/semi-ui-react';

Basic Usage

For basic usage, pass the video address through src and pass the video cover address through poster

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return <VideoPlayer height={630} src={src} poster={poster} />;
}

Set controls list

Set the display items of the menu bar through controlsList. The accepted value is an array. The default value is ['play', 'next', 'time', 'volume', 'playbackRate', 'quality', 'route', 'mirror', 'fullscreen', 'pictureInPicture']

A control shows when controlsList allows it and the prop it depends on is provided: next needs onNext, quality needs a non-empty qualityList, and route needs a non-empty routeList; the other controls depend only on controlsList.

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return <VideoPlayer height={630} src={src} poster={poster} controlsList={['play', 'time', 'volume', 'playbackRate', 'fullscreen']} />;
}

Loop playback

Use loop to set loop playback

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return <VideoPlayer height={630} src={src} poster={poster} loop />;
}

Fast forward and rewind

Use seekTime to set the fast forward and rewind time, and use the left and right keys on the keyboard to fast forward and rewind.

请选择快进快退时间
封面
00:00 / 00:00
Code
import { useState } from 'react';
import { VideoPlayer, Select } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const [seekTime, setSeekTime] = useState(5);

    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return (
        <div>
            <div>
                <span style={{ marginBottom: 10 }}>请选择快进快退时间</span>
                <Select
                    aria-label="请选择快进快退时间"
                    value={seekTime}
                    style={{ width: 100, marginLeft: 10 }}
                    onChange={(value) => {
                        if (value !== undefined) setSeekTime(value);
                    }}
                    optionList={[
                        { label: '5s', value: 5 },
                        { label: '10s', value: 10 },
                        { label: '15s', value: 15 },
                    ]}
                    placeholder="请选择快进快退时间"
                />
            </div>
            <VideoPlayer height={630} style={{ marginTop: 10 }} src={src} poster={poster} seekTime={seekTime} />
        </div>
    );
}

Playback rate

Set the rate selection list through playbackRateList. The rate, quality and route controls are native buttons that open their menu when focused with Tab; see "Keyboard and focus" for the keys. Each button is named by what it sets followed by the current option (such as "Playback speed 1.0x"), and its menu items are radio items

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const playbackRateList = [
        { label: '0.5x', value: 0.5 },
        { label: '1.0x', value: 1 },
        { label: '1.5x', value: 1.5 },
        { label: '2.0x', value: 2 },
    ];
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return <VideoPlayer height={630} src={src} poster={poster} playbackRateList={playbackRateList} />;
}

Volume setting

Use volume to set the initial volume, the value range is 0 - 100, set muted to true to play silently. onVolumeChange is called when the user adjusts the volume

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return <VideoPlayer height={630} src={src} poster={poster} muted />;
}

Clarity switching

Use qualityList to set the clarity selection list, defaultQuality to set the initial selected clarity, and onQualityChange to set the src logic to be updated after clicking.

Similarly for route switching, use routeList to set the route selection list, defaultRoute to set the initial selected route, and onRouteChange to set the src logic to be updated after clicking.

封面
00:00 / 00:00
Code
import { useState } from 'react';
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const [src, setSrc] = useState('/assets/video/vchart-show-video.mp4');

    const playList = [
        {
            src: '/assets/video/vchart-show-video.mp4',
            quality: '1080p',
        },
        {
            src: '/assets/video/vchart-show-video.mp4',
            quality: '480p',
        },
    ];
    const poster = '/assets/poster2.jpeg';

    const updateVideoSource = (quality: string) => {
        const source = playList.find((item) => item.quality === quality);
        if (source) setSrc(source.src);
    };

    return (
        <VideoPlayer
            height={630}
            src={src}
            poster={poster}
            defaultQuality="1080p"
            qualityList={[
                { label: '1080p', value: '1080p' },
                { label: '480p', value: '480p' },
            ]}
            onQualityChange={(quality) => {
                console.log('quality change', quality);
                updateVideoSource(quality);
            }}
        />
    );
}

Chapter markers

Set chapter markers via markers

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    const markers = [
        {
            start: 0,
            title: '片头',
        },
        {
            start: 4,
            title: '功能介绍',
        },
        {
            start: 38,
            title: 'Figma Plugin',
        },
        {
            start: 51,
            title: '片尾',
        },
    ];

    return <VideoPlayer height={630} src={src} poster={poster} markers={markers} />;
}

Theme

Set the theme via theme, the theme only affects the background color

封面
00:00 / 00:00
Code
import { VideoPlayer } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';
    return <VideoPlayer src={src} poster={poster} height={630} theme="light" />;
}

Using ref for control

Get the native video element via ref for more flexible control, such as synchronized playback/pause of multiple videos

封面
00:00 / 00:00
封面
00:00 / 00:00
Code
import { useRef } from 'react';
import { VideoPlayer, Button } from '@fibrous/semi-ui-react';

export default function VideoPlayerDemo() {
    const videoRef1 = useRef<HTMLVideoElement>(null);
    const videoRef2 = useRef<HTMLVideoElement>(null);
    const src = '/assets/video/vchart-show-video.mp4';
    const poster = '/assets/poster2.jpeg';

    const handlePlayAll = () => {
        const v1 = videoRef1.current;
        const v2 = videoRef2.current;
        if (v1) void v1.play();
        if (v2) void v2.play();
    };

    const handlePauseAll = () => {
        const v1 = videoRef1.current;
        const v2 = videoRef2.current;
        if (v1) v1.pause();
        if (v2) v2.pause();
    };

    return (
        <div>
            <div style={{ marginBottom: 12 }}>
                <Button onClick={handlePlayAll} style={{ marginRight: 8 }}>
                    同时播放
                </Button>
                <Button onClick={handlePauseAll}>同时暂停</Button>
            </div>
            <div style={{ display: 'flex', gap: 12 }}>
                <VideoPlayer ref={videoRef1} src={src} poster={poster} height={315} width="50%" />
                <VideoPlayer ref={videoRef2} src={src} poster={poster} height={315} width="50%" />
            </div>
        </div>
    );
}

Keyboard and focus

  • While focus is inside the player, Space toggles play and pause, except on a button or an input control, which keeps the key; the left and right arrow keys rewind and fast forward by seekTime, except inside an input control, the progress bar or a menu, which keep the keys. Combinations with Alt, Ctrl or Meta are ignored.
  • The progress bar is a slider (role="slider"): the arrow keys move it by seekTime, PageUp and PageDown by a tenth of the duration, and Home and End jump to either end. Screen readers announce "current time / total time".
  • The playback rate, quality and route buttons open their menu when focused with Tab; the down and up arrow keys move focus to the first and last item. In the menu, the up and down arrow keys, Home and End move focus, Enter or Space selects, and Esc closes the menu and returns to the button.
  • The volume popover opens when the volume button receives focus, and Enter or Space toggles mute; the down arrow key moves focus into the popover, where the volume slider takes the arrow keys.
  • When the pointer leaves the player during playback, the control bar stays visible while it holds keyboard focus.

API

Props

PropertyDescriptionTypeDefault
autoPlayWhether to play automatically.booleanfalse
captionsSrcCaptions source URL; the captions are shown by default once set.string-
classNameClass name of the root element.string-
clickToPlayWhether clicking the video toggles playback.booleantrue
controlsListControls shown in the control bar, all by default. A control also needs the prop it depends on to show.VideoControl[]Type["play", "next", "time", "volume", "playbackRate", "quality", "route", "mirror", "fullscreen", "pictureInPicture"]
crossOriginCORS setting of the video element: anonymous or use-credentials; an empty string means anonymous.TypeReact.MediaHTMLAttributes<HTMLVideoElement>['crossOrigin']-
defaultPlaybackRateInitial playback rate, read once when the player mounts.number1
defaultQualityInitial quality, read once when the player mounts.string-
defaultRouteInitial route, read once when the player mounts.string-
heightPlayer height; a number is in pixels, a string is used as is.number | string-
loopWhether to loop playback.booleanfalse
markersChapter markers, each with a start time start in seconds and a title title.VideoPlayerMarker[]-
mutedWhether to start muted, read once when the player mounts.booleanfalse
onNextCalled when the next button is clicked. The button shows only when this is set and controlsList includes next.Type() => void-
onPauseCalled when playback pauses.Type() => void-
onPlayCalled when playback starts.Type() => void-
onQualityChangeCalled when the quality changes, with the selected quality value.Type(quality: string) => void-
onRateChangeCalled when the playback rate changes, with the selected rate.Type(rate: number) => void-
onRouteChangeCalled when the route changes, with the selected route value.Type(route: string) => void-
onVolumeChangeCalled when the user drags the volume slider or toggles mute, with the new volume (0 when muted); not called on initialization.Type(volume: number) => void-
playbackRateListPlayback rate options, by default 2.0, 1.5, 1.25, 1.0 and 0.75.TypeVideoPlayerOption<number>[]-
posterPoster image URL.string-
qualityListQuality options; the quality control shows only when this is non-empty.TypeVideoPlayerOption<string>[]-
refReference to the native video element, for more flexible control; either a ref object or a callback.TypeReact.Ref<HTMLVideoElement>-
routeListRoute options; the route control shows only when this is non-empty.TypeVideoPlayerOption<string>[]-
seekTimeSeconds a fast forward or rewind moves.number10
srcVideo URL. Without it a missing-resource message shows; removing it keeps the previous source on the video element.string-
styleInline style of the root element, applied after width and height, so it overrides them.React.CSSProperties-
themeTheme, affecting only the background color: dark or light.VideoPlayerTheme"dark"
volumeInitial volume from 0 to 100, read once when the player mounts.number100
widthPlayer width; a number is in pixels, a string is used as is.number | string-

Other native attributes (such as id, aria-*, onClick) fall through to the root div. When the root has aria-label or aria-labelledby it gets role="group", and a role you pass takes precedence. Media events (onTimeUpdate and so on) do not bubble to the root, so listening to them on the component is not supported; get the native element through ref and listen on it instead.

Marker

PropertiesDescriptionTypeDefault Value
startstart time pointnumber-
titletitlestring-

VideoPlayerOption

The option type of playbackRateList is VideoPlayerOption<number>, and the option type of qualityList and routeList is VideoPlayerOption<string>. The type of value is the generic parameter.

PropertiesDescriptionTypeDefault Value
labelName shown in the menustring-
valueOption value, passed to the callbackT-

Design Token

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$animation_duration-videoPlayer_controls-show500msvideoPlayer菜单栏-弹出动画-动画持续时间
$animation_duration-videoPlayer_slider-in300msvideoPlayer进度条-弹出动画-动画持续时间
$animation_function-videoPlayer_slider-incubic-bezier(0.62, 0.05, 0.36, 0.95)videoPlayer进度条-弹出动画-动画插值函数
$animation_function-videoPlayer_slider-outcubic-bezier(0.62, 0.05, 0.36, 0.95)videoPlayer进度条-收起动画-动画插值函数
$color-videoPlayer_theme_dark-textvar(--semi-color-bg-0)dark theme 字体色
$color-videoPlayer_theme_dark-bgvar(--semi-grey-8)dark theme 背景色
$color-videoPlayer_theme_light-textvar(--semi-grey-8)light theme 字体色
$color-videoPlayer_theme_light-bgvar(--semi-color-disabled-bg)light theme 背景色
$color-videoPlayer_pause-bgvar(--semi-color-text-1)暂停按钮颜色
$color-videoPlayer_notification-bgvar(--semi-color-overlay-bg)notification 背景色
$color-videoPlayer_notification-textvar(--semi-color-default)notification 字体色
$color-videoPlayer_controls-bgrgba(28, 31, 35, 0.8)控制栏背景色
$color-videoPlayer_controls-text#fff控制栏文字色
$color-videoPlayer_controls_popup-bgrgb(46, 50, 56)音量弹层与菜单背景色
$color-videoPlayer_controls_item_popup-bg-defaultvar(--semi-color-overlay-bg)控制栏弹层背景色
$color-videoPlayer_controls_item_popup-bg-hoverrgba(67, 68, 74, 1)控制栏弹层背景色 - hover
$color-videoPlayer_controls_popup_item-text-defaultrgba(#fff, 0.7)控制栏文字色
$color-videoPlayer_controls_popup_item-text-activevar(--semi-color-primary)控制栏弹层文字色 - 选中
$color-videoPlayer_progress_bar-bg-playedvar(--semi-color-primary)进度条已播放部分背景色
$color-videoPlayer_progress_bar-bg-loadedvar(--semi-grey-3)进度条已加载部分背景色
$color-videoPlayer_progress_bar-bg-unplayedvar(--semi-grey-5)进度条未播放部分背景色
$color-videoPlayer_progress_bar_handle-bg#fffhandle 背景色
$color-videoPlayer_progress_bar_handle-bordervar(--semi-color-primary)handle 边框色
$color-videoPlayer_progress_bar_handle-shadowvar(--semi-color-shadow)handle 阴影色
$height-videoPlayer_progress_bar_hotSpot-default20px进度条热区 default 高度
$height-videoPlayer_progress_bar-default4px进度条 default 高度
$height-videoPlayer_progress_bar-hover10px进度条 hover 高度
$height-videoPlayer_progress_bar_handle16px进度条 handle 高度
$height-videoPlayer_controls_menu-default56px控制栏 default 高度
$height-videoPlayer_controls_volume-default168px控制栏音量 default 高度:标题 36px + 滑块 120px + 底部留白 12px
$height-videoPlayer_controls_popup-default24px控制栏弹层类元素 default 高度
$height-videoPlayer_controls_popup_item-default32px控制栏弹层类元素 item default 高度
$width-videoPlayer_controls_volume-default40px控制栏音量 default 宽度
$width-videoPlayer_controls_popup_item-default50px控制栏弹层类元素 default 宽度
$width-videoPlayer_controls_popup-default48px控制栏弹层 default 宽度
$spacing-videoPlayer-progress_bar_chapter-marginRight2px进度条分节间距
$spacing-videoPlayer_notification-bottom22pxnotification 距离菜单栏距离
$spacing-videoPlayer_notification-left8pxnotification 距离菜单栏左侧距离
$spacing-videoPlayer_notification_text-paddingY8pxnotification 文字垂直方向 padding
$spacing-videoPlayer_notification_text-paddingX12pxnotification 文字水平方向 padding
$spacing-videoPlayer-controls-padding$spacing-base-tight $spacing-base控制栏 padding
$spacing-videoPlayer-controls_item-gap$spacing-tight控制栏 item 间距
$spacing-videoPlayer-controls_time-paddingX8px控制栏时间 paddingX
$spacing-videoPlayer-controls_volume_title-paddingX10px控制栏音量标题文字 paddingX
$spacing-videoPlayer-controls_volume_title-paddingY0px控制栏音量标题文字 paddingX
$spacing-videoPlayer-controls_volume_popup-paddingY0px控制栏音量弹层 paddingX
$spacing-videoPlayer-controls_volume_popup-paddingX$spacing-extra-tight控制栏音量弹层 paddingX
$spacing-videoPlayer-controls_popup-paddingX$spacing-tight控制栏弹层元素 paddingX
$spacing-videoPlayer-controls_popup-paddingY0px控制栏弹层元素 paddingY
$spacing-videoPlayer-progress_bar_wrapper-marginX$spacing-tight进度条 wrapper marginX
$spacing-videoPlayer-progress_bar_wrapper-marginY0px进度条 wrapper marginY
$spacing-videoPlayer_progress_bar-centerY$height-videoPlayer_progress_bar_hotSpot-default - $height-videoPlayer_progress_bar-default * 0.5进度条与 handle 的中心线距热区顶部的距离,悬停变粗时上下对称
$spacing-videoPlayer_error_svg-marginBottom12pxerror svg marginBottom
$radius-videoPlayer_notification3pxnotification 圆角
$radius-videoPlayer_progress_bar_handle50%进度条 handle 圆角
$radius-videoPlayer_progress_bar999px进度条圆角
$radius-videoPlayer_controls_item3px控制栏 item 圆角
$radius-videoPlayer_controls_popup4px控制栏弹层圆角
$font-videoPlayer_notification-fontSize$font-size-regularnotification 字体大小
$font-videoPlayer_controls_item-fontSize$font-size-small控制栏 item 字体大小
$font-videoPlayer_controls_time_text-fontSize$font-size-regular控制栏时间字体大小
$font-videoPlayer_error-fontSize$font-size-regularerror 字体大小
$font-videoPlayer_notification-lineHeight20pxnotification 行高
$font-videoPlayer_controls_popup_item-lineHeight16px控制栏 item 行高
$font-videoPlayer_controls_popup_item-fontWeight600控制栏 item 字体粗细
$font-videoPlayer_error-fontWeight600error 字体粗细