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 };
}

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

相关推荐
那就可爱多一点点1 小时前
H5页面多个视频如何只同时播放一个?
前端·音视频
前端郭德纲3 小时前
浅谈React的虚拟DOM
前端·javascript·react.js
2401_879103684 小时前
24.11.10 css
前端·css
ComPDFKit5 小时前
使用 PDF API 合并 PDF 文件
前端·javascript·macos
yqcoder5 小时前
react 中 memo 模块作用
前端·javascript·react.js
优雅永不过时·6 小时前
Three.js 原生 实现 react-three-fiber drei 的 磨砂反射的效果
前端·javascript·react.js·webgl·threejs·three
神夜大侠8 小时前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱8 小时前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号9 小时前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy72939 小时前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html