Plus 组件

视频播放器

用于播放视频

代码演示

如何引入

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

基本用法

基本使用,通过 src 传入视频地址, 通过 poster 传入视频封面地址

封面
00:00 / 00:00
代码
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', 'next', 'time', 'volume', 'playbackRate', 'quality', 'route', 'mirror', 'fullscreen', 'pictureInPicture']

控件在 controlsList 允许、并且它所依赖的属性已提供时才显示:next 需要 onNext,quality 需要非空的 qualityList,route 需要非空的 routeList;其余控件只看 controlsList。

封面
00:00 / 00:00
代码
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 设置循环播放

封面
00:00 / 00:00
代码
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 />;
}

快进快退

通过 seekTime 设置快进快退时间,通过键盘左右键执行快进快退

请选择快进快退时间
封面
00:00 / 00:00
代码
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>
    );
}

播放速率

通过 playbackRateList 设置速率选择列表。速率、清晰度与线路控件都是原生按钮,用 Tab 聚焦即展开菜单,键盘操作见「键盘和焦点」。按钮名称为用途加当前选项(如「倍速 1.0x」),菜单项是单选项

封面
00:00 / 00:00
代码
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 设置初始音量,值区间为 0 - 100, 设置 muted 为 true 可以静音播放。用户调整音量时会触发 onVolumeChange

封面
00:00 / 00:00
代码
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 />;
}

清晰度切换

通过 qualityList 设置清晰度选择列表,defaultQuality 设置初始选择的清晰度,onQualityChange 设置点击后更新的 src 逻辑。

线路切换同理,通过 routeList 设置线路选择列表,defaultRoute 设置初始选择的线路,onRouteChange 设置点击后更新的 src 逻辑。

封面
00:00 / 00:00
代码
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);
            }}
        />
    );
}

章节标记

通过 markers 设置章节标记点

封面
00:00 / 00:00
代码
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 设置主题, 主题仅影响背景色

封面
00:00 / 00:00
代码
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" />;
}

使用 ref 控制

通过 ref 获取原生 video 元素,可以实现更灵活的控制,例如多个视频同步播放/暂停

封面
00:00 / 00:00
封面
00:00 / 00:00
代码
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>
    );
}

键盘和焦点

  • 焦点在播放器内时,空格键切换播放与暂停,焦点在按钮或输入控件上时空格键交给该控件;左右方向键按 seekTime 快退、快进,焦点在输入控件、进度条或菜单内时方向键交给它们。带 Alt、Ctrl、Meta 的组合键不处理。
  • 进度条是滑块(role="slider"),用方向键按 seekTime 增减,PageUp、PageDown 按总时长的十分之一增减,Home、End 跳到两端。读屏读出的是「当前时长 / 总时长」。
  • 倍速、清晰度、线路按钮用 Tab 聚焦即展开菜单,下、上方向键把焦点移到菜单的第一项、最后一项;菜单内用上下方向键与 Home、End 移动,Enter 或空格确认,Esc 关闭并回到按钮。
  • 音量按钮获得焦点时展开音量弹层,Enter 或空格切换静音;下方向键把焦点移进弹层,音量滑块用方向键调节。
  • 播放中指针离开播放器后,控制栏内有键盘焦点时控制栏保持显示。

API

Props

属性说明类型默认值
autoPlay是否自动播放。booleanfalse
captionsSrc字幕资源地址,传入后默认显示字幕。string-
className根元素的类名。string-
clickToPlay点击视频画面时是否切换播放与暂停。booleantrue
controlsList控制栏展示的控件,默认展示全部。控件还要满足依赖的属性已提供才会显示。VideoControl[]Type["play", "next", "time", "volume", "playbackRate", "quality", "route", "mirror", "fullscreen", "pictureInPicture"]
crossOriginvideo 元素的 CORS 设置,允许的值为 anonymous 与 use-credentials,空串等同 anonymous。TypeReact.MediaHTMLAttributes<HTMLVideoElement>['crossOrigin']-
defaultPlaybackRate初始播放倍率,仅在挂载时读取。number1
defaultQuality初始清晰度,仅在挂载时读取。string-
defaultRoute初始线路,仅在挂载时读取。string-
height播放器高度,数字按像素处理,字符串原样使用。number | string-
loop是否循环播放。booleanfalse
markers章节标记,每项含起始时间 start(秒)与标题 title。VideoPlayerMarker[]-
muted是否静音播放,仅在挂载时读取。booleanfalse
onNext点击「下一个」按钮时调用。设置后且 controlsList 包含 next 时才显示该按钮。Type() => void-
onPause暂停时调用。Type() => void-
onPlay开始播放时调用。Type() => void-
onQualityChange切换清晰度时调用,参数为所选清晰度的值。Type(quality: string) => void-
onRateChange切换倍速时调用,参数为所选倍率。Type(rate: number) => void-
onRouteChange切换线路时调用,参数为所选线路的值。Type(route: string) => void-
onVolumeChange用户拖动音量滑块或切换静音时调用,参数为变化后的音量,静音时为 0;初始化不调用。Type(volume: number) => void-
playbackRateList倍速选项列表,默认为 2.0、1.5、1.25、1.0、0.75 五档。TypeVideoPlayerOption<number>[]-
poster封面图地址。string-
qualityList清晰度选项列表,非空时才显示清晰度控件。TypeVideoPlayerOption<string>[]-
ref指向原生 video 元素的引用,用于更灵活的控制;可以是 ref 对象或回调函数。TypeReact.Ref<HTMLVideoElement>-
routeList线路选项列表,非空时才显示线路控件。TypeVideoPlayerOption<string>[]-
seekTime快进快退一次的秒数。number10
src视频地址。未设置时显示资源缺失提示;移除后 video 元素保留上一个地址。string-
style根元素的内联样式,写在 width、height 之后,同名属性以它为准。React.CSSProperties-
theme主题,仅影响背景色,可选 dark 或 light。VideoPlayerTheme"dark"
volume初始音量,取值 0 到 100,仅在挂载时读取。number100
width播放器宽度,数字按像素处理,字符串原样使用。number | string-

其他原生属性(如 id、aria-*、onClick)落在根元素 div 上。根元素带 aria-label 或 aria-labelledby 时自动加 role="group",自己传 role 则以传入的为准。媒体事件(onTimeUpdate 等)不会冒泡到根元素,因此不支持在组件上监听,需要时通过 ref 取得原生元素后自行监听。

Marker

属性说明类型默认值
start起始时间点number-
title标题string-

VideoPlayerOption

playbackRateList 的选项类型为 VideoPlayerOption<number>,qualityList、routeList 的选项类型为 VideoPlayerOption<string>,value 的类型即泛型参数。

属性说明类型默认值
label菜单中显示的名称string-
value选项值,回调参数取此T-

设计变量

下表是组件内部的 Sass 变量,不能覆写。定制样式请覆写 --semi-* CSS 变量(见 Design Token 页),或写不分层的 CSS 规则。
Sass 变量值用法
$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 字体粗细