video.js在6版本之后是和flash分开的,如果需要使用高版本的,需要额外安装videojs-flash
更新
2020.9.21
publish
:已更新至npm
仓库
- npm包:
npm i @antelopecloud/components
- README.md
2020.9.9
improve
:一些优化
- 第一版功能完成
- 作为组件,完成打包(暂未发布)
- 新增使用文档
README.md
2020.9.5
feat
:新增独立组件,地址FlashPlayer
- 功能:播放
RTMP
流,新增重连机制 - 未全部完成,可以做独立组件自行修改
- 使用方法看
FlashPlayer.stories.tsx
就行了
2020.8.5
docs
:新增高版本使用说明;新增@ly-utils/videojs-flash
库解决后续报错问题
准备
项目有播放rtmp
视频流的功能需求,所以搞来搞去还是想着用video.js
这个库。
基于react
,video.js@5.18.4
yarn add video.js@5.18.4 @types/video.js -D
建议使用 (使用这个库的话后续代码记得修改一下引用库名称)
yarn add @ly-utils/video.js -D
文档: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"
或者(使用这个库的话后续代码记得修改一下引用库名称)
yarn add @ly-utils/video.js -D
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;