video.js在6版本之后是和flash分开的,如果需要使用高版本的,需要额外安装videojs-flash
项目有播放rtmp
视频流的功能需求,所以搞来搞去还是想着用video.js
这个库。
基于react
,[email protected]
yarn add [email protected] @types/video.js
文档:video.js
页面中使用挺简单的
import React, { useMemo, useState, useEffect } from 'react';
import videojs from 'video.js';
// //样式文件注意要加上
import 'video.js/dist/video-js.css';
const Player: React.FC<any> = (props) => {
const [videoNode, setVideoNode] = useState<any>();
const [player, setPlayer] = useState<any>();
const url = 'rtmp://58.200.131.2:1935/livetv/hunantv';
// rtmp播放
useMemo(() => {
if (videoNode) {
const videoJsOptions = {
autoplay: true, // 自动播放
language: 'zh-CN',
preload: 'auto', // 自动加载
errorDisplay: true, // 错误展示
width: 475, // 宽
height: 300,
flash: {
swf: '/video-js.swf',
},
sources: [
{
src: url,
type: 'rtmp/flv', // 类型可加可不加,目前未看到影响
},
],
};
const videoPlayer = videojs(videoNode, videoJsOptions);
setPlayer(videoPlayer);
}
}, [videoNode]);
useEffect(() => {
return (() => {
if (player) player.dispose()
})
}, [])
return (
<>
<div style={{margin:50}}>
<p>播放器</p>
<video
ref={(node) => {
setVideoNode(node);
}}
id="videoPlay"
className="video-js vjs-default-skin vjs-big-play-centered"
width="100%"
height="100%"
>
<track kind="captions" />
<p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
</video>
</div>
</>
)
}
export default Player;
import React, { useMemo, useState, useEffect } from 'react';
import videojs from 'video.js';
// //样式文件注意要加上
import 'video.js/dist/video-js.css';
import { Modal } from 'antd';
const playerModal: React.FC<any> = (props) => {
const { visible, onClose } = props;
const [videoNode, setVideoNode] = useState<any>();
const [player, setPlayer] = useState<any>();
console.log(1);
const url = 'rtmp://58.200.131.2:1935/livetv/hunantv';
// rtmp播放
useMemo(() => {
if (videoNode) {
const videoJsOptions = {
autoplay: true, // 自动播放
language: 'zh-CN',
preload: 'auto', // 自动加载
errorDisplay: true, // 错误展示
width: 475, // 宽
height: 300,
flash: {
swf: '/video-js.swf',
},
sources: [
{
src: url,
type: 'rtmp/flv',
},
],
};
const videoPlayer = videojs(videoNode, videoJsOptions);
setPlayer(videoPlayer);
}
}, [videoNode]);
useEffect(() => {
return (() => {
if (player) player.dispose()
})
}, [visible])
const onPlayerClose = () => {
console.log(1);
onClose()
}
return (
<>
<Modal
visible={visible}
title="预览"
onOk={onPlayerClose}
onCancel={onPlayerClose}
maskClosable={false}
>
<video
ref={(node) => {
setVideoNode(node);
}}
id="videoPlay"
className="video-js vjs-default-skin vjs-big-play-centered"
width="100%"
height="100%"
>
<track kind="captions" />
<p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
</video>
</Modal>
</>
)
}
export default playerModal;
关闭弹框后报错!
this.el_.vjs_getProperty is not a function
主要是会一直报错,然后达到一定次数页面就崩了
1、弹框没了的时候要销毁dispose
,我这里放在useEffect
中应该是没生效或者说不能解决吧
2、还要配合Modal
的销毁子节点api
:destroyOnClose
const onPlayerClose = () => {
onClose()
// 修改处
setTimeout(()=>{
if(player) player.dispose()
},800)
}
return (
<>
<Modal
visible={visible}
title="预览"
onOk={onPlayerClose}
onCancel={onPlayerClose}
maskClosable={false}
// 修改处
destroyOnClose
>
<video
ref={(node) => {
setVideoNode(node);
}}
id="videoPlay"
className="video-js vjs-default-skin vjs-big-play-centered"
width="100%"
height="100%"
>
<track kind="captions" />
<p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
</video>
</Modal>
</>
)
现在点击隐藏弹框也会出现报错,主要是我用了定时器销毁,如果不用定时器销毁的话,会有一定的视觉差。但是销毁之后就不会再报错了!
最后还是觉得这个报错不太爽,我就自己去改了一下源码,然后发布在gitee
上,想用的话可以这样做
package.js
"video.js": "git+https://gitee.com/jx915/video.js.git"
playerModal.tsx
import React, { useState, useEffect } from 'react';
import videojs from 'video.js';
//样式文件注意要加上
import 'video.js/dist/video-js.css';
import { Modal } from 'antd';
const url = 'rtmp://58.200.131.2:1935/livetv/hunantv';
const playerModal: React.FC<any> = (props) => {
const { visible, onClose } = props;
const [videoNode, setVideoNode] = useState<any>();
useEffect(() => {
if (videoNode) {
const videoJsOptions = {
autoplay: true, // 自动播放
language: 'zh-CN',
preload: 'auto', // 自动加载
errorDisplay: true, // 错误展示
width: 475, // 宽
height: 300,
flash: {
swf: '/video-js.swf',
},
sources: [
{
src: url,
type: 'rtmp/flv', // 类型可加可不加,目前未看到影响
},
],
};
videojs(videoNode, videoJsOptions)
}
}, [videoNode])
const onPlayerClose = () => {
onClose()
}
return (
<>
<Modal
visible={visible}
title="预览"
onOk={onPlayerClose}
onCancel={onPlayerClose}
maskClosable={false}
destroyOnClose
>
<video
ref={(node) => {
setVideoNode(node);
}}
id="videoPlay"
className="video-js vjs-default-skin vjs-big-play-centered"
width="100%"
height="100%"
>
<track kind="captions" />
<p className="vjs-no-js">您的浏览器不支持HTML5,请升级浏览器。</p>
</video>
</Modal>
</>
)
}
export default playerModal;