前端视频课程添加水印,全屏不消失解决方法
使用video组件自己的全屏功能时,浏览器将自动全屏video组件。
而video.js插件二次开发他全屏的是组件外部的div,加入水印逻辑就是在获取player.el节点之后插入div元素实现水印功能。
1.引入video.js插件
npm i video.js -S
2.页面引入video.js插件以及样式
import videojs from "video.js";
import "video.js/dist/video-js.css";
3.开发一个video.js Plugins插件 Watemark.js
import videojs from 'video.js';
import moment from 'moment'// Default options for the plugin.
const defaults = {position: 'top-right',fadeTime: 3000,url: undefined,image: undefined
};/*** 移除已存在的水印元素** @function removeExistingWatermark* @param {HTMLElement} container*/
const removeExistingWatermark = (container) => {const existingWatermark = container.querySelector('.vjs-watermark-content');if (existingWatermark) {existingWatermark.remove();}
};/*** Sets up the div, img and optional a tags for the plugin.** @function setupWatermark* @param {Player} player* @param {Object} [options={}]*/
const setupWatermark = (player, options) => {// Add a div and img tagconst videoEl = player.el();if (!videoEl) return;const container = videoEl;// 先移除已存在的水印,避免重复创建removeExistingWatermark(container);// 水印尺寸估计(用于确保水印完全在容器内)const watermarkWidth = 300;const watermarkHeight = 32;// 计算随机位置,确保水印完全在容器内const maxX = container.clientWidth - watermarkWidth;const maxY = container.clientHeight - watermarkHeight;const randomX = Math.floor(Math.random() * maxX);const randomY = Math.floor(Math.random() * maxY);const div = document.createElement('div');div.classList.add('vjs-watermark-content');Object.assign(div.style, {position: 'absolute',top: `${maxY - 50}px`,left: `${50}px`,color: '#000',fontSize: '16px',pointerEvents: 'none', // 不影响操作whiteSpace: 'nowrap',userSelect: 'none',zIndex: 99,fontWeight: 'bold',opacity: 0.12})div.textContent = options.text;const p = document.createElement('p');p.textContent = moment().format('YYYY-MM-DD HH:mm')div.appendChild(p);videoEl.appendChild(div);
};/*** Fades the watermark image.** @function fadeWatermark* @param {Object} [options={* fadeTime:* 'The number of milliseconds before the inital watermark fade out'}]*/
const fadeWatermark = (options) => {setTimeout(() => document.getElementsByClassName('vjs-watermark-content')[0].classList.add('vjs-watermark-fade'),options.fadeTime);
};/*** Function to invoke when the player is ready.** This is a great place for your plugin to initialize itself. When this* function is called, the player will have its DOM and child components* in place.** @function onPlayerReady* @param {Player} player* @param {Object} [options={}]*/
const onPlayerReady = (player, options) => {player.addClass('vjs-watermark');// if there is no image set just exitif (!options.text) {return;}setupWatermark(player, options);// Setup watermark autofadeif (options.fadeTime === null) {return;}player.on('play', () => fadeWatermark(options));player.on('fullscreenchange', () => {// 全屏变化时更新水印,setupWatermark函数内部已处理移除旧水印setupWatermark(player, options);});// 确保在组件卸载时清理水印player.on('dispose', () => {const videoEl = player.el();if (videoEl) {removeExistingWatermark(videoEl);}});
};/*** A video.js plugin.** In the plugin function, the value of `this` is a video.js `Player`* instance. You cannot rely on the player being in a "ready" state here,* depending on how the plugin is invoked. This may or may not be important* to you; if not, remove the wait for "ready"!** @function watermark* @param {Object} [options={}]* An object of options left to the plugin author to define.*/
const watermark = function (options) {this.ready(() => {onPlayerReady(this, videojs.mergeOptions(defaults, options));});
};// Register the plugin with video.js.
videojs.registerPlugin('watermark', watermark);// Include the version number.
watermark.VERSION = '__VERSION__';export default watermark;
记得引入
import "./watemark.js";
4.调用videojs加载watermark代码
var player = videojs(playerRef.current,{plugins: {watermark: {text: "www.jz07.cn",opacity: 0.5}},height: height,width: width,autoplay: false, //是否自动播放loop: false, //是否循环播放controls: true, //控制器controlBar: {// 设置控制条组件playbackRateMenuButton: true}}, () => {onReady?.()});