PC端使用video.js点击播放按钮 弹出遮罩层播放
import React, { useState, useRef, useLayoutEffect } from 'react';
import { Modal } from '@antd/design';
import 'video.js/dist/video-js.css';
import videojs from 'video.js';
import './index.scss';
function videoInit(id, options) {
const player = videojs(id, options, function onPlayerReady() {
videojs.log('Your player is ready! 111');
this.on('abort', () => {
videojs.log('abort');
});
this.on('play', () => {
videojs.log('play');
});
this.on('suspend', () => {
videojs.log('suspend');
});
this.on('emptied', () => {
videojs.log('emptied');
});
this.on('stalled', () => {
videojs.log('stalled');
});
this.on('pause', () => {
videojs.log('pause');
});
this.on('canplay', () => {
videojs.log('canplay');
});
this.on('playing', () => {
videojs.log('playing');
});
this.on('seeking', () => {
videojs.log('seeking');
});
this.on('seeked', () => {
videojs.log('seeked');
});
this.on('canplay', () => {
videojs.log('canplay');
// In this context, `this` is the player that was created by Video.js.
// this.play();
});
this.on('loadeddata', () => {
videojs.log('loadeddata');
// In this context, `this` is the player that was created by Video.js.
});
// How about an event listener?
this.on('ended', () => {
videojs.log('Awww...over so soon?!');
});
});
return player;
}
interface IProps {
id: string; // 视频唯一id,用于获取dom节点播放视频
poster: string; // 视频封面url,视频未播放时展示的图片
videoMp4Url?: string; // mp4格式视频url
videoOggUrl?: string; // mp4格式视频url
videoWebmUrl?: string; // mp4格式视频url
children: JSX.Element | JSX.Element[];
clickPlayStartCallBack?: Function; // 点击播放时回调函数;
}
export default function VideoPlayer(props: IProps) {
const { id, poster, videoMp4Url, videoOggUrl, videoWebmUrl, children, clickPlayStartCallBack } = props;
const [isShowModal, setIsShowModal] = useState<boolean>(false);
const idVideo = `${id}-video`;
const videoPlayerRef = useRef();
// const isInIos = isIos();
const options = {};
useLayoutEffect(() => {
if (!isShowModal || videoPlayerRef?.current) {
return;
}
setTimeout(() => {
videoPlayerRef.current = videoInit(idVideo, options);
}, 10);
}, [isShowModal]);
/** ios 渲染隐藏的视频, 会打开 ios 默认的视频播放弹窗 */
const renderVideo = () => (
<video
id={idVideo}
className="video-js"
// autoPlay
controls
preload="auto"
poster={poster}
data-setup="{}"
disablePictureInPicture
>
{videoMp4Url ? <source src={videoMp4Url} type="video/mp4" /> : null}
{videoOggUrl ? <source src={videoOggUrl} type="video/ogg" /> : null}
{videoWebmUrl ? <source src={videoWebmUrl} type="video/webm" /> : null}
<track kind="captions" />
<p className="vjs-no-js">
To view this video please enable JavaScript, and consider upgrading to a web browser that
<a href="http://videojs.com/html5-video-support/" target="_blank" rel="noreferrer">
supports HTML5 video
</a>
</p>
</video>
);
const playVideo = () => {
setIsShowModal(true);
if (videoMp4Url || videoOggUrl || videoWebmUrl) {
setTimeout(() => {
const domId = document.getElementById(`${idVideo}_html5_api`) || document.getElementById(`${idVideo}`);
if (domId) (domId as HTMLVideoElement).play();
}, 50);
}
clickPlayStartCallBack && clickPlayStartCallBack();
};
return (
<div className="zp_videoPlayer">
<div className="videoImgWrap" id={id} onClick={() => playVideo()}>
{children}
</div>
{isShowModal && (
<Modal
className="zp_videoPlayer_modal"
mask
maskClosable
closable={false}
onClose={() => {
setIsShowModal(false);
}}
>
<Modal.Body>
<i
className="iconfont-official-website icon-zp-mtdui-close closeIcon cursor_pointer"
onClick={() => {
setIsShowModal(false);
}}
/>
{renderVideo()}
</Modal.Body>
</Modal>
)}
</div>
);
}
.zp_videoPlayer {
width: 100%;
height: 100%;
.videoImgWrap {
width: 100%;
height: 100%;
}
}
.zp_videoPlayer_modal {
min-width: 890px;
.video-js {
width: 890px;
height: 500px;
// .vjs-big-play-button {
// width: 34px;
// height: 34px;
// border: none;
// border-radius: 50%;
// line-height: 34px;
// bottom: 10px;
// top: auto;
// }
.vjs-time-tooltip {
width: 50px;
}
}
.mtd-mobile-modal-content {
width: 100%;
overflow: visible;
}
.mtd-mobile-modal-mask-bg {
background-color: rgba(0, 0, 0, 0.7);
}
.closeIcon {
position: absolute;
top: 10px;
right: 10px;
z-index: 20;
border: 10px solid transparent;
font-size: 20px;
font-weight: bolder;
color: white;
}
}
.zp_videoPlayer_modal.mtd-modal {
padding: 0;
.mtd-modal-body {
padding: 0;
}
.mtd-modal-header {
display: none;
}
}
在组件中使用
<div className="item_img_wrapper">
<VideoPlayer id={v.code} poster={v.poster} videoMp4Url={v.linkUrl}>
<img style={{ width: '100%', height: '100%' }} alt="cover" src={v.poster} />
<div className="play_btn">
<img src={require('../../../imgs/play.svg')} alt="" />
</div>
<div className="time_btn">
<div className="mins">{v.duration}</div>
<div className="date">{v.date}</div>
</div>
</VideoPlayer>
</div>