前端视频课程添加水印,全屏不消失解决方法

使用video组件自己的全屏功能时,浏览器将自动全屏video组件。

而video.js插件二次开发他全屏的是组件外部的div,加入水印逻辑就是在获取player.el节点之后插入div元素实现水印功能。

1.引入video.js插件

javascript 复制代码
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 tag
  const 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 exit
  if (!options.text) {
    return;
  }
  setupWatermark(player, options);

  // Setup watermark autofade
  if (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?.()
        });
相关推荐
Mr数据杨4 小时前
【ComfyUI】Animate单人物角色视频替换
人工智能·计算机视觉·音视频
我命由我123454 小时前
PDFBox - PDDocument 与 byte 数组、PDF 加密
java·服务器·前端·后端·学习·java-ee·pdf
@PHARAOH4 小时前
HOW - prefetch 二级页面实践
前端·javascript·react.js
EF@蛐蛐堂4 小时前
WUJIE VS QIANKUN 微前端框架选型(一)
前端·vue.js·微服务·架构
咚咚咚小柒4 小时前
【前端】用el-popover做通用悬停气泡(可设置弹框宽度)
前端·javascript·vue.js·elementui·html·scss
Ares-Wang4 小时前
CSS3》》 transform、transition、translate、animation 区别
前端·css·css3
fsnine5 小时前
Python Web框架对比与模型部署
开发语言·前端·python
Xxtaoaooo5 小时前
Sora文生视频技术拆解:Diffusion Transformer架构与时空建模原理
人工智能·架构·音视频·transformer·sora
广州华水科技5 小时前
单北斗GNSS形变监测系统在桥梁安全中的应用与技术解析
前端