UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

378 lines (329 loc) 14.7 kB
--- order: 99 localeCode: zh-CN category: Plus title: VideoPlayer 视频播放器 width: 60% icon: doc-videoplayer brief: 用于播放视频 --- ## 代码演示 ### 如何引入 ```jsx import import { VideoPlayer } from '@douyinfe/semi-ui'; ``` ### 基本用法 基本使用,通过 `src` 传入视频地址, 通过 `poster` 传入视频封面地址 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; return ( <VideoPlayer height={630} src={src} poster={poster} /> ); }; ``` ### 设置菜单栏功能 通过 `controlsList` 设置菜单栏的展示项,该项接受值为数组,默认值为`['play', 'next', 'time', 'volume', 'playbackRate', 'quality', 'route', 'mirror', 'fullscreen', 'pictureInPicture']` ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; const controlsList = ['play', 'time', 'volume', 'playbackRate', 'fullscreen']; return ( <VideoPlayer height={630} src={src} poster={poster} controlsList={controlsList} /> ); }; ``` ### 循环播放 通过 `loop` 设置循环播放 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; return ( <VideoPlayer height={630} src={src} poster={poster} loop={true} /> ); }; ``` ### 快进快退 通过 `seekTime` 设置快进快退时间,通过键盘左右键执行快进快退 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer, Select } from '@douyinfe/semi-ui'; () => { const [seekTime, setSeekTime] = useState(5); const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; return ( <div> <div> <span style={{ marginBottom: 10 }}>请选择快进快退时间</span> <Select value={seekTime} style={{ width: 100, marginLeft: 10 }} onChange={(value) => 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` 设置速率选择列表 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { 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 = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; return ( <VideoPlayer height={630} src={src} poster={poster} playbackRateList={playbackRateList} /> ); }; ``` ### 音量设置 通过 `volume` 设置初始音量,值区间为 0 - 100, 设置 `muted` 为 `true` 可以静音播放 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; return ( <VideoPlayer height={630} src={src} poster={poster} muted={true} /> ); }; ``` ### 清晰度切换 通过 `qualityList` 设置清晰度选择列表,`defaultQuality` 设置初始选择的清晰度,`onQualityChange` 设置点击后更新的 `src` 逻辑。 线路切换同理,通过 `routeList` 设置清晰度选择列表,`defaultRoute` 设置初始选择的线路,`onRouteChange` 设置点击后更新的 `src` 逻辑。 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const [src, setSrc] = useState('https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4'); const playList = [ { src: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4', quality: '1080p', }, { src: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/video/vchart-show-video-480p.mp4', quality: '480p', }, ]; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; const updateVideoSource = (quality) => { const source = playList.find((item) => item.quality === quality); 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` 设置章节标记点 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/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` 设置主题, 主题仅影响背景色 ```jsx live=true dir="column" import React from 'react'; import { VideoPlayer } from '@douyinfe/semi-ui'; () => { const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; return ( <VideoPlayer src={src} poster={poster} height={630} theme={'light'} /> ); }; ``` ### 使用 ref 控制 通过 `ref` 获取原生 video 元素,可以实现更灵活的控制,例如多个视频同步播放/暂停 ```jsx live=true dir="column" import React, { useRef } from 'react'; import { VideoPlayer, Button } from '@douyinfe/semi-ui'; () => { const videoRef1 = useRef(); const videoRef2 = useRef(); const src = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/vchart/landingPage/vchart-show-video.mp4"; const poster = "https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/poster2.jpeg"; const handlePlayAll = () => { const v1 = videoRef1.current; const v2 = videoRef2.current; if (v1) v1.play(); if (v2) 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> ); }; ``` ### API | 属性 | 说明 | 类型 | 默认值 | |------------|---------------------------------------------|--------------------------------------|-------| | autoPlay | 是否自动播放 | boolean | false | | captionsSrc | 字幕资源 | string | - | | className | 类名 | string | - | | clickToPlay | 是否启用点击以播放 | boolean | true | | controlsList | 设置菜单栏展示控件,默认展示所有控件 | string[] | ['play', 'next', 'time', 'volume', 'playbackRate', 'quality', 'route', 'mirror', 'fullscreen', 'pictureInPicture'] | | crossOrigin | 该枚举属性指明是否使用 CORS 来获取相关视频。允许 CORS 的资源可在 'canvas' 元素中被重用,而不会被污染。允许的值有 'anonymous''use-credentials' | 'anonymous' \|'use-credentials' | - | | defaultPlaybackRate | 默认倍率 | number | 1 | | defaultPlaybackRate | 默认视频清晰度 | string | - | | defaultRoute | 默认线路 | string | - | | forwardRef | 传递原生 video 元素的 ref,用于获取原生 video 元素进行更灵活的控制 | React.Ref&lt;HTMLVideoElement&gt; | - | | height | 高度 | string \| number | - | | loop | 是否启用循环播放 | boolean | false | | markers | 节点标记 | Marker[] | - | | muted | 是否静音播放 | boolean | false | | onPause | 暂停回调 | () => void | - | | onPlay | 播放回调 | () => void | - | | onQualityChange | 切换清晰度回调 | (quality: string) => void | - | | onRateChange | 切换速率回调 | (rate: number) => void | - | | onRouteChange | 切换线路回调 | (route: string) => void | - | | onVolumeChange | 调整音量回调 | (volume: number) => void | - | | playbackRateList | 速率列表,默认展示 6 种播放速率,分别为 0.50.751.01.251.52.0 | Array<{ label: string; value: string }> | - | | poster | 封面图 | string | - | | qualityList | 清晰度列表 | Array<{ label: string; value: string }> | - | | routeList | 线路列表 | Array<{ label: string; value: string }> | - | | seekTime | 快进快退时间 | number | 10 | | src | 视频播放地址 | string | - | | style | 样式 | CSSProperties | - | | theme | 主题设置,不同主题组件的背景色不同 | 'dark' \| 'light' | 'dark' | | volume | 默认音量 | number | 100 | | width | 宽度 | string \| number | - | #### Marker | 属性 | 说明 | 类型 | 默认值 | |------------|---------------------------------------------|--------------------------------------|-------| | start | 起始时间点 | number | | title | 标题 | string | ## 设计变量 <DesignToken/>