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

使用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?.()
        });
相关推荐
u***u68510 小时前
React环境
前端·react.js·前端框架
X***E46310 小时前
前端数据分析应用
前端·数据挖掘·数据分析
4***149010 小时前
React社区
前端·react.js·前端框架
LFly_ice10 小时前
学习React-24-路由传参
前端·学习·react.js
Lhuu(重开版11 小时前
CSS:动效布局动画
前端·css
Q***K5511 小时前
前端构建工具
前端
laocooon52385788611 小时前
创建了一个带悬停效果的“我的个人主页“按钮
前端
2013编程爱好者12 小时前
Vue工程结构分析
前端·javascript·vue.js·typescript·前端框架
小满zs13 小时前
Next.js第十一章(渲染基础概念)
前端
不羁的fang少年14 小时前
前端常见问题(vue,css,html,js等)
前端·javascript·css