需求背景

运营同事PC端发布的视频,可以直接在视频中选择时间,将当前时间的帧,作为视频的封面图。在这个过程中遇到了跨域问题,时间轴同步问题,video标签跨域问题,前端视频缓存问题

目标效果

image

遇到的问题

1.本地选择视频可以实现截图,OSS中的视频会爆跨域问题,无法实现截图

本地选择的视频是blob格式是没问题的,而OSS中选择的视频域名和PC端管理系统的域名不相同,导致出现问题。解决办法:在OSS中设置跨域规则

2.后端跨域解决之后,前端渲染的video组件无法成功执行截图方法,会报错

本地渲染的视频地址已经被浏览器缓存,导致报错。解决办法:使用js创建一个dispaly:"none"的视频video,我们叫他new_video new_video的URL地址沿用video的视频地址加上随机数(加随机数的目的是防止被缓存),最重要的一点new_video要设置crossOrigin属性

3.修改video的时间轴,要联动修改new_video的时间轴

解决办法:增加一个对old_video的监听方法,动态赋值

代码

<!doctype html>
<html lang="zh-CN">
<head>
    <title>OSS跨域视频截取封面图实现方案</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no,maximum-scale=1,minimum-scale=1">
</head>
<style>
    #output img {
        border: 1px solid red;
    }

    #video {
        width: 200px;
    }

    #new_video {
        display: none;
    }
</style>
<body>
<video id="video" controls="controls">
    <source id="src" src="http://cdn.domain.com/set/nice_bird.mp4">
</video>
<video id="new_video"></video>
<button id="capture">截取封面图</button>
<div id="output"></div>
<script src="jquery.js"></script>
<script>
    $(function () {
        let old_video, output;
        output = document.getElementById('output');
        old_video = document.getElementById("video");
        // 监听按钮点击事件
        $('#capture').on('click', function () {
            captureImage();
        })

        // 获取新的视频
        let new_video = document.getElementById('new_video')
        // 获取老的视频链接地址
        let url = $("#src").attr("src")

        // 重点 为新video的src赋值 这里给URL增加后缀是防止浏览器对视频进行缓存,否则截图无法成功
        new_video.src = url + "?t=" + new Date();
        // 重点 此处新video的视频进度如果是0则无法截取图片,随意这是一个比0大的数字即可
        new_video.currentTime = 0.000001

        // 重点 开启跨域支持
        new_video.crossOrigin = 'anonymous';

        // 重点 使用事件监听方式捕捉事件(通过改变老的视频播放时间改变新的视频播放时间)
        old_video.addEventListener("timeupdate", function () {
            new_video.currentTime = old_video.currentTime
        }, false);

        // 截图函数
        let captureImage = function () {
            let canvas = document.createElement("canvas");
            canvas.width = new_video.videoWidth * 0.5;
            canvas.height = new_video.videoHeight * 0.5;

            console.log('宽', new_video.videoWidth, '高', new_video.videoHeight);
            // 将所截图片绘制到canvas上,并转化成图片
            canvas.getContext('2d').drawImage(new_video, 0, 0, canvas.width, canvas.height);
            let image = document.createElement('img');
            //将base64传递给image.src
            image.src = canvas.toDataURL();

            // 打印图片base64字符串
            console.log(canvas.toDataURL());
            //添加到展示区域
            output.prepend(image);
        }
    })
</script>
</body>
</html>

SmallForest
239 声望12 粉丝

github: