react 中使用 video.js 播放 hls(m3u8)格式的视频
简介:公司业务需求,由于后端把 mp4 视频转码成 m3u8 视频供手机端播放,导致后台系统播放不了 m3u8 格式的视频(原来是直接用的原生 video 标签播放)。
项目主要依赖:(先安装,步骤略)
create-react-app:3.0.0
1 | { |
2 | "react": "^16.11.0", |
3 | "react-router-dom": "^5.1.2", |
4 | "antd": "^3.19.2", |
5 | "axios": "^0.19.0", |
6 | "mux.js": "^5.5.1", |
7 | "prop-types": "^15.7.2", |
8 | "video.js": "^7.6.6", |
9 | "videojs-contrib-hls": "^5.15.0", |
10 | "webpack": "^4.41.2" |
11 | } |
1.组件
文件目录
src/components/VideoPlayer/index.jsx
1 | import React, { Component } from "react"; |
2 | import PropTypes from "prop-types"; |
3 | |
4 | import Videojs from "video.js"; |
5 | |
6 | // 添加hls插件,以保证播放m3u8格式的视频 |
7 | import "videojs-contrib-hls"; |
8 | // 导入videojs 的样式 |
9 | import "video.js/dist/video-js.css"; |
10 | // 自定义样式(见下文) |
11 | import "./style.css"; |
12 | |
13 | // 给window上添加videojs, zh-CN.js 语言注册依赖 videojs.addLanguage()方法 |
14 | // 配置了不生效的话 把public/index.html 里的标签 <html lang="en"> </html> lang设置为 "zh-CN" |
15 | window.videojs = Videojs; |
16 | import("video.js/dist/lang/zh-CN.js"); |
17 | |
18 | class VideoPlayer extends Component { |
19 | static propTypes = { |
20 | // 视频地址 |
21 | src: PropTypes.string, |
22 | // 视频高度 |
23 | height: PropTypes.string, |
24 | // 视频宽度 |
25 | width: PropTypes.string |
26 | }; |
27 | |
28 | // 默认的props |
29 | static defaultProps = { |
30 | src: "", |
31 | height: 360, |
32 | width: 640 |
33 | }; |
34 | |
35 | state = { |
36 | videoId: "custom-video" + +new Date() |
37 | }; |
38 | |
39 | // 初始化内容 |
40 | UNSAFE_componentWillReceiveProps(props) { |
41 | try { |
42 | const { src } = props; |
43 | if (!src || src === this.props.src) return; |
44 | this.initVideo(src); |
45 | } catch (error) { |
46 | console.log(error); |
47 | } |
48 | } |
49 | |
50 | componentWillUnmount() { |
51 | // 销毁播放器 |
52 | if (this.player) { |
53 | this.player.dispose(); |
54 | } |
55 | } |
56 | |
57 | // 初始化 |
58 | initVideo(src) { |
59 | const { videoId } = this.state; |
60 | const { height, width } = this.props; |
61 | this.player = Videojs(videoId, { |
62 | height, |
63 | width, |
64 | controls: true, |
65 | preload: "auto", |
66 | fluid: true |
67 | }); |
68 | |
69 | this.player.src({ src }); |
70 | } |
71 | |
72 | render() { |
73 | const { videoId } = this.state; |
74 | return ( |
75 | <div |
76 | className="custom-video-warpper" |
77 | style={{ |
78 | display: this.props.src ? "block" : "none" |
79 | }} |
80 | > |
81 | {/* video标签的className一定要是 "video-js",否则样式不生效 */} |
82 | <video id={videoId} className="video-js" /> |
83 | </div> |
84 | ); |
85 | } |
86 | } |
87 |
|
88 | export default VideoPlayer; |
src/components/VideoPlayer/style.css
1 | .custom-video-warpper { |
2 | margin-bottom: 10px; |
3 | } |
4 | .custom-video-warpper .video-js { |
5 | border: 1px solid #ccc; |
6 | position: relative; |
7 | } |
8 | .custom-video-warpper .custom-video-dimensions.vjs-fluid { |
9 | padding-top: 0; |
10 | } |
11 | .custom-video-warpper .video-js .vjs-big-play-button { |
12 | border-radius: 2em; |
13 | width: 2em; |
14 | height: 2em; |
15 | line-height: 2em; |
16 | top: 50%; |
17 | left: 50%; |
18 | transform: translate(-50%, -50%); |
19 | } |
2.使用
1 | import React, { Component } from "react"; |
2 | import VideoPlayer from '@/components/VideoPlayer' |
3 | |
4 | |
5 | class AppForm extends Component { |
6 | state = { |
7 | videoUrl: "" |
8 | }; |
9 | |
10 | componentDidMount() { |
11 | this.getVideoUrl(); |
12 | } |
13 | |
14 | // 获取VideoUrl |
15 | getVideoUrl = async () => { |
16 | let videoUrl = |
17 | "https://cn7.kankia.com/hls/20191215/f0bdccd9d46df8600c445e8c6b0c3169/1576378697/index.m3u8"; |
18 | |
19 | this.setState({ videoUrl }); |
20 | }; |
21 | |
22 | render() { |
23 | const { videoUrl } = this.state; |
24 | |
25 | return <VideoPlayer src={videoUrl} />; |
26 | } |
27 | } |
28 | |
29 | export default AppForm; |
3.实现效果
参考链接
1.https://docs.videojs.com/
2.https://docs.videojs.com/tutorial-react.html