video.js 是一个比较成熟的 HTML5 视频播放框架,兼容包括桌面和移动端在内的现代浏览器,支持从“传统“的 MP4 和 WebM 到流形式的 HSL 和 DASH 等多种格式播放,不仅提供很多插件去扩展播放器,还可以通过修改 css 方便的去调整样式。
# 安装
可以使用 CDN 或者 NPM 包安装,具体参考 Get Started (opens new window)
npm install --save-dev video.js
# 使用
video.js 使用比较简单,直接通过 videojs(id: string | Element, options?: VideoJsPlayerOptions | undefined, ready?: videojs.ReadyCallback | undefined)
形式使用即可。
const player = videojs('my-video', {
autoplay: 'muted'
});
2
3
# react 使用
在 react 中使用需要注意一点就是,如果在 useEffect
中创建了播放器,然后在返回值中 dispose
的话会把 video 标签干掉导致报错,因此 tutorial-react (opens new window) 文档中给出的方案是每次创建一个新的 VideoHtml
标签,这样组件刷新的时候就不会报错。
但是在使用过程中会发现一个新的问题,每次任意一个的 options 发生变化都会造成播放器的重新渲染,比如调节一个视频的声音都会让视频重新生成明显是不符合需求的。很显然,我们希望播放器在组件销毁时要 dispose
,但是部分属性改变时不应该重新渲染,那就分开在不同的 useEffect
中处理吧。
export const VideoPlayer = (props: VideoPlayerProps) => {
const { options, width, height, volume = 0, src } = props;
const videoRef = useRef<HTMLVideoElement>(null);
const player = useRef<VideoJsPlayer>();
// 根据options初始化播放器
useEffect(() => {
const videoElement = videoRef.current;
if (videoElement) {
player.current = videojs(videoElement, options);
}
return () => {
player.current?.dispose();
};
}, []);
// 如果时播放器的src改变了单独处理一下,因此这时候视频会重新开始播放
useEffect(() => {
if (src) {
player.current?.src(src);
}
}, [src]);
// 如果时诸如声音之类的配置改动,直接设置就行,不影响视频播放
useEffect(() => {
player.current?.controls(!!options.controls);
player.current?.autoplay(options.autoplay || false);
player.current?.loop(!!options.loop);
player.current?.volume(volume / 100);
}, [volume, options.autoplay, options.loop, options.controls]);
return (
<div data-vjs-player>
<video
width={width}
height={height}
ref={videoRef}
className="video-js"
/>
</div>
);
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 参数配置
使用 videojs 创建一个播放器很简单,通过配置参数也能很方便的个性化定制播放器,tutorial-options (opens new window) 给出了常见的一些配置项。
{
// 和video标签类似的选项
autoplay: false, // 是否自动播放,muted会静音视频然后播放;any是先播放,如果失败了就再静音然后播放
controls: true, // 是否显示控制工具
preload: "auto",
// 下面是一些videojs自己选项
responsive: true,
fluid: true, // 自适应宽高
language: "zh-CN", // 设置语言
muted: false, // 是否静音
controlBar: { // 设置控制条组件
// 使用children的形式可以控制每一个控件的位置,以及显示与否
children: [
{ name: "playToggle" }, // 播放按钮
{ name: "currentTimeDisplay" }, // 当前已播放时间
{ name: "progressControl" }, // 播放进度条
{ name: "durationDisplay" }, // 总时间
{
// 倍数播放
name: "playbackRateMenuButton",
playbackRates: [0.5, 1, 1.5, 2, 2.5],
},
{
name: "volumePanel", // 音量控制
inline: false, // 不使用水平方式,垂直方向的声音
},
{ name: "FullscreenToggle" }, // 全屏控制
],
},
sources: [ // 视频源
{
src: "http://www.w3school.com.cn/example/html5/mov_bbb.mp4",
type: "video/mp4",
},
],
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
上面只是列出了部分常用的配置项,还有很多配置项可以参考官方文档 (opens new window)或者一些中文文档有描述每个选项具体是做什么的。
注意:在当前 7.14.3 版本使用的时候,有一个问题就是配置了 currentTimeDisplay
后发现界面上怎么都不会生效,需要参考这个 issues (opens new window) 通过配置 css 解决
.video-js {
.vjs-control-bar {
.vjs-time-control {
display: block;
}
// 顺便改了一下间距
.vjs-current-time {
padding-right: 2px;
}
.vjs-time-divider {
padding: 0;
min-width: auto;
}
.vjs-duration {
padding-left: 2px;
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18