需求背景
运营同事PC端发布的视频,可以直接在视频中选择时间,将当前时间的帧,作为视频的封面图。在这个过程中遇到了跨域问题,时间轴同步问题,video标签跨域问题,前端视频缓存问题
目标效果
遇到的问题
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>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。