目录
在Video.js播放器中定制自己的组件 - acgtofe
注意:videojs升级后,不能用extend创建组件,需要按下方代码建一个组件
- import videojs from "video.js";
-
- const Component: any = videojs.getComponent("Component");
-
- export class VideoPausedIcon extends Component {
- constructor(player: any, options: any) {
- super(player, options);
- // 监听,暂停播放,显示播放按钮
- player.on("pause", () => {
- this.visible = true;
- const el = this.el();
- el.className = "vjs-define-paused";
- });
- // 监听,开始播放,隐藏播放按钮,通过videojs自带的 vjs-hidden 类
- player.on("play", () => {
- this.visible = false;
- const el = this.el();
- el.className = "vjs-define-paused vjs-hidden";
- });
- this.on("touchstart", this.handleTouchStart);
- this.on("touchend", this.handleTouchEnd);
- // 如果需要在web端使用,必须,不兼容的话,web端点击按钮就不会暂停/播放
- this.on("click", (e: any) => this.handleClick(e, player));
- }
-
- createEl() {
- let pauseIcon = videojs.dom.createEl("div", {
- className: "vjs-define-paused",
- tabIndex: -1,
- });
- !this.visible && videojs.dom.appendContent(pauseIcon, "");
- return pauseIcon;
- }
-
- handleTouchStart(e: any) {
- // 此处必须,不然点击按钮不能播放/暂停
- e.stopPropagation();
- }
-
- handleTouchEnd(e: any) {
- // 此处必须,不然点击按钮不能播放/暂停
- e.stopPropagation();
- }
-
- handleClick(e: any, player: any) {
- e.stopPropagation();
- if (!player) {
- return;
- }
- const paused = player.paused();
- if (paused) {
- player.play();
- } else {
- player.pause();
- }
- }
- }
- import React, { useEffect } from "react";
- import videojs from "video.js";
- import "video.js/dist/video-js.css";
- import styles from "./Video.module.less";
- import { VideoPausedIcon } from "./VideoPausedIcon";
-
- interface IProps {
- url: string;
- }
-
- const VideoCom: React.FC<IProps> = (props: any) => {
- const videoRef = React.useRef
(null); - const playerRef = React.useRef
(null); -
- useEffect(() => {
- const player: any = playerRef && playerRef.current;
- return () => {
- if (player && !player.isDisposed()) {
- player.dispose();
- playerRef.current = null;
- }
- };
- }, [playerRef]);
-
- useEffect(() => {
- if (!props.url) {
- return;
- }
- let options: any = {
- controlBar: {
- fullscreenToggle: true,
- pictureInPictureToggle: false,
- volumePanel: false,
- playToggle: false,
- },
- muted: false,
- controls: true, //进度条
- autoplay: false, //自动播放
- loop: false, //是否循环
- languages: {
- "zh-CN": new URL(`video.js/dist/lang/zh-CN.json`, import.meta.url).href,
- },
- language: "zh-CN",
- preload: "auto",
- nodownload: true,
- sources: [{ src: props.url, type: "video/mp4" }],
- };
-
- // Make sure Video.js player is only initialized once
- if (!playerRef || !playerRef.current) {
- // The Video.js player needs to be _inside_ the component el for React 18 Strict Mode.
- const videoElement = document.createElement("video-js");
- videoRef &&
- videoRef.current &&
- videoRef.current.appendChild(videoElement);
-
- playerRef.current = videojs(videoElement, options, () => {
- console.log("player is ready");
- const player: any = playerRef.current;
- player.on("error", (err: any) => {
- console.log("source load fail");
- // message.error("视频源请求出错");
- });
- let touchStartTime = 0;
- let touchEndTime = 0;
- player.on("touchstart", (e: any) => {
- touchStartTime = new Date().getTime();
- });
- player.on("touchend", (e: any) => {
- touchEndTime = new Date().getTime();
- if (touchEndTime - touchStartTime < 300) {
- const paused = player.paused();
- if (paused) {
- player.play();
- } else {
- player.pause();
- }
- }
- });
- });
- createPausedIcon();
- } else {
- const player: any = playerRef.current;
- player.src(options.sources);
- }
- }, [
- props.url,
- playerRef,
- videoRef
- ]);
-
- const createPausedIcon = () => {
- const player = playerRef && playerRef.current;
- if (!player) {
- return;
- }
- const Component: any = videojs.getComponent("Component");
- Component.registerComponent("VideoPausedIcon", VideoPausedIcon);
- const options = {};
- const properIndex = player
- .children()
- .indexOf(player.getChild("BigPlayButton"));
- player.addChild("VideoPausedIcon", options, properIndex);
- };
-
- return (
- <div className={styles.container}>
- <div className={styles.videoBox} ref={videoRef}>div>
- div>
- );
- };
-
- export default VideoCom;
- .container {
- width: 100%;
- height: 100%;
-
- .videoBox {
- width: 100%;
- height: 100%;
-
- :global {
- .video-js {
- width: 100%;
- height: 100%;
-
- .vjs-big-play-button {
- display: none;
- }
-
- .vjs-define-paused {
- width: 30px;
- height: 28px;
- background: rgba(43, 63, 46, 0.7);
- border: 1px solid rgb(0, 255, 140);
- border-radius: 10px;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- transition: all .4s;
-
- &::after {
- display: block;
- content: '';
- position: absolute;
- top: 50%;
- left: calc(50% + 5px);
- transform: translate(-50%, -50%);
- border-top: 5px solid;
- border-bottom: 5px solid;
- border-left: 8px solid;
- border-right: 8px solid;
- border-color: transparent;
- border-left-color: rgb(0, 255, 140);
- }
- }
- }
- }
- }
-
- }