前端截取视频第一帧作为封面
Posted 番茄炒蛋加鸡腿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端截取视频第一帧作为封面相关的知识,希望对你有一定的参考价值。
概述
1.做项目的时候突然想截取视频第一帧,作为视频的封面,然后搜了很多博客都发现得到空白的图片,最后得到了解决。
2.方法:通过创建canvas标签,利用其drawImage() 方法在画布上绘制该视频,然后运用toDataURL方法转换canvas上的图片为base64格式,并将base64格式的图片作为video标签的poster属性。
3.浏览器:chrome
代码关键
video.currentTime = 1
currentTime 属性设置或返回视频播放的当前位置(以秒计)。当设置该属性时,播放会跳跃到指定的位置。一定要设置该属性,不然会得到空白的图片。
知识点
video.onloadeddata
onloadeddata 事件在当前帧的数据加载完成且还没有足够的数据播放视频/音频(audio/video)的下一帧时触发。在当前帧的数据可用时执行相应 javascript代码。
canvas.toDataURL
是返回一个包含图片展示的 数据URL。可以使用 type 参数其类型,默认为 PNG 格式。图片的分辨率为96dpi。
video.setAttribute(‘crossOrigin’, ‘anonymous’)
canvas无法对跨域的图片进行操作,这样解决了跨域问题。
完整代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>capture screen</title>
</head>
<body>
<video id="video" controls="controls">
<source src="./0130_1.mp4">
</video>
<div id="output"></div>
<script type="text/javascript">
(function()
var video, output;
output = document.getElementById("output");
var canvas = document.createElement('canvas')
var img = document.createElement("img");
video = document.getElementById('video')
video.setAttribute('crossOrigin', 'anonymous')
video.currentTime = 1
canvas.width = video.clientWidth
canvas.height = video.clientHeight
video.onloadeddata = (() =>
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height)
var dataURL = canvas.toDataURL('image/png')
img.src = dataURL;
img.width = 400;
img.height = 300;
output.appendChild(img);
)
)();
</script>
</body>
</html>
javascript截取video视频第一帧作为封面方案
写在前边:因为项目是用vue.js框架实现,所以以下代码是vue.js语法。
首先,看一下Dom元素(video相关属性和事件):
<video
@loadeddata="createPreImg($event)" // loadeddata事件表示media中的首帧已经加载
class="content-video"
:src="item.videoUrl" // 视频地址(可以是当前域下的,也可以是其他域下的)
crossorigin="anonymous" // 允许跨域(由于浏览器的同源策略,如果视频是其他域,需要设置此属性)
preload="auto" // 预加载(移动端需要设置此属性,因为移动端有很多播放限制,很多都不会自动加载)
></video>
其次,是javascript部分代码:
createPreImg(event) { // event js原生事件
const videoEle = event.target; // 当前video dom节点
videoEle.currentTime = 1; // 设置视频开始播放时间(因为有些手机第一帧显示黑屏,所以这里选取视频的第一秒作为封面)
videoEle.addEventListener(\'canplay\', function () { // 监听video的canplay事件
// 创建canvas元素 并设置canvas大小等于video节点的大小
const canvas = document.createElement(\'canvas\');
const scale = 0.8; // 压缩系数
canvas.width = videoEle.videoWidth * scale;
canvas.height = videoEle.videoHeight * scale;
// canvas画图
canvas.getContext(\'2d\').drawImage(videoEle, 0, 0, canvas.width, canvas.height);
// 把canvas转成base64编码格式
const imgSrc = canvas.toDataURL(\'image/png\');
// 创建img元素 插入到文档中
const img = document.createElement(\'img\');
img.src = imgSrc;
img.style.position = \'absolute\';
img.style.left = \'0\';
img.style.top = \'0\';
img.style.objectFit = \'cover\';
videoEle.parentNode && videoEle.parentNode.appendChild(img);
});
}
经过测试,在小米手机Mix2机型上,可以展示封面;
建议:由于移动端手机机型众多,视频在移动端的播放限制也比较多,所以封面的处理最好放在服务端处理,以减少不同机型兼容性带来的问题。
以上是关于前端截取视频第一帧作为封面的主要内容,如果未能解决你的问题,请参考以下文章