zoukankan      html  css  js  c++  java
  • js实现视频截图,视频批量截图,canvas实现

    截取视频的某一时间的图像并保存

    利用canvas的绘画能力画出视频某一帧的视频画面, 获得到图像之后转换成base64图像, 再利用a标签的实现自动保存到本地

    • html代码
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>视频截图保存到本地</title>
    </head>
    
    <body>
        <div><button id="btn">开始截图</button></div>
        <img id="img">
        <a id="a" download="" style="display: none;">去下载</a>
    </body>
    
    </html>
    
    • js代码
    // 绑定下载
    document.getElementById("btn").onclick = function() {
        videoCover("视频地址", null, 400)
    }
    /**
     * @param {String} src 视频链接
     * @param {Number} width 视频容器播放的宽
     * @param {Number} height 视频容器播放的高
     * @param {Number} second 需要截图视频的帧数, 单位秒
     * @param {Number} bufftime 视频加载缓冲的时长, 单位秒
     */
    function videoCover(src, width, height, second, bufftime) {
        const canvas = document.createElement('canvas'); //  创建canvas 用来截图
        const video = document.createElement('video'); //  创建video 用来存放被截图的视频
        const img = document.getElementById('img') //  用来显示截图的图片效果
        const a = document.getElementById('a') //  用来自动下载图片保存到本地
        video.setAttribute('crossOrigin', 'anonymous'); //  支持跨域
        document.body.appendChild(video); //  把视频插入页面里
        video.setAttribute('src', src); //  设置video路径
        video.style.visibility = "hidden" //  视频不显示
    
        // 监听视频播放
        video.onplay = function() {
            // 暂停
            video.pause()
            // 指定播放时间 1代表视频的第一秒帧 可以浮点数
            video.currentTime = second || 1
            // 设置视频容器的宽高播放 如果设置一项会自动按照比例生成  这里是高固定,宽自动
            video.height = height || video.clientHeight;
            // 设置canvas的截图大小,如果没给定宽高值会取视频容器的宽高
            canvas.width = width || video.clientWidth;
            canvas.height = height || video.height;
            /*  
                使用定时器为了视频跳转到某一帧的时候视频进行缓冲,等视频加载完成之后进行截图
                如果截图是黑屏说明视频未加载完成就开始截屏了
            */
            setTimeout(() => {
                //  使用canvas进行绘画 视频画面
                canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
                // 获取到base64图片 png格式
                const IMG_TYPE = "png"
                const b64 = canvas.toDataURL('image/' + IMG_TYPE);
                // 展示到页面上给img的src赋值
                document.getElementById('img').setAttribute('src', b64);
                // 设置下载图片地址
                document.getElementById('a').setAttribute('href', b64);
                //  设置下载图片的名称
                const filename = "测试图" + "." + IMG_TYPE
                document.getElementById('a').setAttribute('download', filename);
                //  模拟点击自动下载图片
                document.getElementById('a').click()
                //  移除视频容器
                document.body.removeChild(video);
            }, bufftime * 1000 || 3000);
        }
        // 当视频准备就绪的时候 
        video.onloadeddata = () => {
            //  播放它
            video.play()
        }
    }
    

    以上代码就完成了单个的视频截图了.

    • 如何实现多个视频批量截图视频呢?

    使用for循环遍历 调用 videoCover 函数, videoCover 需要重写一下.

    先规定需要遍历视频截图的内容

    [
        {
            "src":"*******.video", // 视频下载地址
            "currentTime":5, //需要截取的视频帧数,第几秒
            "filename":"测试1", // 需要下载到本地的文件名
            "filetype":"png" // 下载的图片类型
        },
        {
            "src":"*******.video", // 视频下载地址
            "currentTime":5, //需要截取的视频帧数,第几秒
            "filename":"测试1", // 需要下载到本地的文件名
            "filetype":"png" // 下载的图片类型
        }
    ]
    
    • 重写videoCover 函数

    使用promise,async,await 遍历循环截图下载图片

    /**
    * @param {Object} obj 视频内容对象
    * @param {Number} width 视频容器播放的宽
    * @param {Number} height 视频容器播放的高
    * @param {Number} bufftime 视频加载缓冲的时长, 单位秒
    */
    function videoCover(obj, width, height, bufftime) {
        return new Promise((resolve, reject) => {
            const canvas = document.createElement('canvas'); //  创建canvas 用来截图
            const video = document.createElement('video'); //  创建video 用来存放被截图的视频
            const img = document.getElementById('img') //  用来显示截图的图片效果
            const a = document.getElementById('a') //  用来自动下载图片保存到本地
            video.setAttribute('crossOrigin', 'anonymous'); //  支持跨域
            document.body.appendChild(video); //  把视频插入页面里
            video.setAttribute('src', obj.src); //  设置video路径
            video.style.visibility = "hidden" //  视频不显示
            // 监听视频播放
            video.onplay = function () {
                // 暂停
                video.pause()
                // 指定播放时间 1代表视频的第一秒帧 可以浮点数
                video.currentTime = obj.currentTime || 1
                // 设置视频容器的宽高播放 如果设置一项会自动按照比例生成  这里是高固定,宽自动
                video.height = height || video.clientHeight;
                // 设置canvas的截图大小,如果没给定宽高值会取视频容器的宽高
                canvas.width = width || video.clientWidth;
                canvas.height = height || video.height;
                /*  
                    使用定时器为了视频跳转到某一帧的时候视频进行缓冲,等视频加载完成之后进行截图
                    如果截图是黑屏说明视频未加载完成就开始截屏了
                */
                setTimeout(() => {
                    //  使用canvas进行绘画 视频画面
                    canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
                    // 获取到base64图片 png格式
                    const b64 = canvas.toDataURL('image/' + obj.filetype);
                    //  移除视频容器
                    document.body.removeChild(video);
                    resolve(b64)
                }, bufftime * 1000 || 3000);
            }
            // 当视频准备就绪的时候 
            video.onloadeddata = () => {
                //  播放它
                video.play()
            }
        })
    
    }
    
    • 在写个循环遍历videoCover 函数
    async function start() {
        const DATA = [{
            "src": "http:/****.mp4", // 视频下载地址
            "currentTime": 5, //需要截取的视频帧数,第几秒
            "filename": "测试1", // 需要下载到本地的文件名
            "filetype": "png" // 下载的图片类型
        },
        {
            "src": "http:/****.mp4", // 视频下载地址
            "currentTime": 2, //需要截取的视频帧数,第几秒
            "filename": "测试2", // 需要下载到本地的文件名
            "filetype": "png" // 下载的图片类型
        }]
        const img = document.getElementById('img')      //  用来显示截图的图片效果
        const a = document.getElementById('a')          //  用来自动下载图片保存到本地
        for (let index = 0; index < DATA.length; index++) {
            const element = DATA[index];
            console.log("开始截图视频:" + element.src);
            const b64 = await videoCover(element, null, 400, 3)
            // 展示到页面上给img的src赋值
            img.setAttribute('src', b64);
            // 设置下载图片地址
            a.setAttribute('href', b64);
            //  设置下载图片的名称
            const filename = element.filename + "." + element.filetype
            a.setAttribute('download', filename);
            //  模拟点击自动下载图片
            a.click()
            console.log("截图保存到本地成功:命名<" + filename + ">");
        }
        console.log("所有视频截图下载本地完成!");
    }
    // 绑定下载
    document.getElementById("btn").onclick = function () {
        start()
    }
    

    然后点击按钮去截图,就可以开始批量截图视频保存到本地了.
    多个视频截图

    提示: async/await属于es7语法,部分低版本浏览器暂不支持,需要前往高版本浏览器使用!

  • 相关阅读:
    Spring Boot 使用 Dom4j XStream 操作 Xml
    Spring Boot 使用 JAX-WS 调用 WebService 服务
    Spring Boot 使用 CXF 调用 WebService 服务
    Spring Boot 开发 WebService 服务
    Spring Boot 中使用 HttpClient 进行 POST GET PUT DELETE
    Spring Boot Ftp Client 客户端示例支持断点续传
    Spring Boot 发送邮件
    Spring Boot 定时任务 Quartz 使用教程
    Spring Boot 缓存应用 Memcached 入门教程
    ThreadLocal,Java中特殊的线程绑定机制
  • 原文地址:https://www.cnblogs.com/kongyijilafumi/p/14088697.html
Copyright © 2011-2022 走看看