canvas实现视频水印

在前面学习canvas学习笔记,实现刮刮卡、在线签名、图片涂抹裁切的基本操作和知识的过程中,发现可以用他播放视频,这就有意思了,详细了解下使用canvas播放视频的好处有以下几点:

  1. 可以实现自定义的视频播放器界面:通过canvas,开发者可以自由绘制视频播放器的界面,包括播放按钮、进度条、音量控制等,从而实现个性化的用户体验。
  2. 可以实现视频的特效和过滤效果:通过在canvas上渲染视频帧,在播放过程中可以实时对视频进行特效处理,比如添加滤镜、调整色彩、加入水印等,为观看者带来更多的视觉享受。
  3. 可以与其他元素进行更好的交互:在canvas中播放视频,可以方便地与其他HTML元素进行交互,比如在视频中嵌入文字、按钮等交互元素,实现更复杂的用户交互。
  4. 可以实现跨平台的视频播放:使用canvas播放视频可以实现跨平台的兼容性,因为canvas是HTML5标准的一部分,支持大多数主流浏览器和设备。
  5. 节省资源和提高性能:使用canvas播放视频相比传统的HTML5 video标签,能够更好地控制视频的加载和渲染过程,从而节省资源和提高性能。尤其在移动设备上,canvas可以更好地适应不同屏幕尺寸和分辨率的需求。

总的来说,使用canvas播放视频可以实现更多样化的用户体验,同时提供更灵活的交互方式和更好的性能表现。

最终效果

如上图是我写demo实现在视频中添加动态水印,这样即使被盗取,水印抹除成本也会很高。

在生产环境中也可起到保护视频内容的版权和安全。通过在视频中添加动态水印,可以在一定程度上防止视频被他人非法盗用或传播。动态水印通常包括视频的原始信息,如作者、来源、时间等,以及可追踪的标识码。当他人未经授权使用该视频时,水印会为原作者提供证据,并增加发现侵权行为的可能性。此外,添加动态水印还可以提高用户对视频内容的信任度,减少盗版传播,保护视频内容创作者的利益。

代码实现

基本页面,先创建两个文件index.htmlindex.js和一段可播放视频

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        video {
        width: 800px;
        height: 500px;
    }
    #canvas{
        height: 475px;
        width: 800px;
        border: 1px solid #323232;
    }
    </style>
</head>
<body>
    <!-- 声明一个视频组件 -->
    <div class="video-player">
        <!-- 视频播放器 -->
        <video src="./video.mp4" controls="controls" ></video>
        <canvas id="canvas"></canvas>
    </div>

    <script src="index.js"></script>
</body>
</html>

视频我选之前看演唱会录制的一段,你们可以替换为别的视频资源,完成前面的index.html后视频可以播放,只是它通过video组件实现的。

在js文件中,我们可以先设置canvas画布。

js 复制代码
const canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var video = document.querySelector('video');

获取video宽高,并通过视频流截取图片,绘制到canvas画布上,并设置定时任务每秒30帧率来重新绘制页面,从而实现canvas播放动态视频的功能。

js 复制代码
console.log(video)  //video标签
let width = this.videoWidth; //video的真实宽
let height = this.videoHeight; //video的真实高
let radio = height / width;
ctx.drawImage(video, 0, 0, 600, radio * 600) //截取video视频流中的图片


/**
 * 获取视频流,图片
 */
video.addEventListener('canplay', () => {
    // 设置画布的尺寸与视频的尺寸一致
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;
    console.log('canplay',video.paused)
        // 每秒截取一帧图像绘制到画布上
        setInterval(() => {
            // 绘制当前视频帧到画布上
            if (video.paused) {
                return;
            }
            ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
           // movements(); //这里调用动态水印的方法
        }, 1000 / 30); // 每秒30帧
    
});

动态水印

视频播放功能实现后,可以在每一帧图片上添加水印了,首先设置几个参数,用来控制水印的移动方向和位置

js 复制代码
//设置基本参数,例如当前位置,移动速度和方向
var x = 20  //水印当前x坐标
var y = 20 //水印当前Y坐标
var directionX = 5  //横向移动速度
var directionY = 3  //纵向移动速度

写一个函数根据传入的x,y值实现水印绘制到页面的对应位置功能。

js 复制代码
/**
 * 设置水印
 * 传入一个坐标
 *
 */
function scrolling(x, y) {
    // console.log(x,y)
    ctx.beginPath();
    ctx.font = '20px 微软雅黑';
    ctx.fillStyle = '#fff';
    ctx.fillText("moyouyu", x, y);
    ctx.beginPath();

}

调试一下,在刚才函数video.addEventListener('canplay', () => {中添加scrolling(x, y) 可以看到第二张图右上角有muyouyu水印固定在那里。

这时就差最后一步,那就是修改x,y值然后动态传入到scrolling(x, y)中这样就能实现页面动态水印,并且期望水印碰到墙壁调转方向(水印不会离开显示页面),横坐标和纵坐标速度不相同。 实现效果如下:

根据x ,y判断是否碰到画布边缘,重新设置移动方向,封装一个重新计算方向的函数setDirection(),执行效果如上图,调用movements()这个方法,如果碰到墙壁则更改directionYdirectionX从而实现改变运动路径移动,实现代码:

js 复制代码
/**
 * 传入上次坐标,x ,y 运动方向和速度 directionX,directionY
 * 如果碰到画布边缘,则重新设置移动方向
 * 移动速度1-8px
 * 横坐标和纵坐标速度不同
 * 有个计数器
 * 判断是否碰到边缘
 * 碰到边缘从新计数
 * 设置水印
 */
function movements() {
    let { speedXms, speedYms } = setDirection();
    if (x < 0 && directionX < 0) {
        directionX = speedXms;
        directionY = directionY
    } else if (x + 100 > canvas.width && directionX > 0) {
        // console.log(speedXms,speedYms);
        directionX = -speedXms;
        directionY = directionY
    } else if (y  - 20 < 0 && directionY < 0) {
        directionY = speedYms;
    } else if (y + 10 > canvas.height && directionY > 0) {
        directionY = -speedYms;
    }
    else {
        // directionY = directionY == 0? speedXms:0 ;
        x = x + directionX;
        y = y + directionY;
    }
    scrolling(x, y)
}

//重新计算方向
/**
 * 从新输出随机方向
 * @returns speedXms 横坐标方向
 * @returns speedYms 纵坐标方向
 */
function setDirection() {
    let speedXms = Math.floor(Math.random() * 8);
    let speedYms = Math.floor(Math.random() * 5);
    if (speedXms == 0 || speedYms == 0) {
        return setDirection();
    }
    return { speedXms, speedYms };
}

最终,将上面代码进行整合效果:

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅6 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax