不会视频截图怎么办?用这些方法分分钟搞定
接之前开发的一个项目,其中有个短视频上传的功能,遭运营人员百般吐槽,原因就是每次都要分别上传视频和视频封面,还得麻烦他们每次先打开视频截取第一帧的视频作为视频封面,今天我就来为您解忧了!
解决的方案有两种,前后端都可解决,这样的话就导致了前后端程序员的互相推诿,奈何本人是全栈,自然没办法推诿了。
前端处理
其原理就是利用了canvas,将视频某一刻画在了canvas。通常我们都是在上传的时刻进行操作,我这里就以element-ui为例演示下过程吧。
创建video对象
1 | var oVideo = document.createElement('video'); |
设置video链接
1 | oVideo.setAttribute('src', 视频blob链接); |
监听视频帧加载
当音频/视频处于加载过程中时,会依次发生以下事件:
loadstart
当浏览器开始寻找指定的音频/视频时,会发生 loadstart 事件。即当加载过程开始时。
语法
在 HTML 中:
1 | <audio|video onloadstart="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.onloadstart=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("loadstart", function() |
durationkchange
当指定音频/视频的时长数据发生变化时,发生 durationchange 事件。
当音频/视频加载后,时长将由 “NaN” 变为音频/视频的实际时长。
语法
在 HTML 中:
1 | <audio|video ondurationchange="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.ondurationchange=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("durationchange", function() |
loadedmetadata
当指定的音频/视频的元数据已加载时,会发生 loadedmetadata 事件。
音频/视频的元数据包括:时长、尺寸(仅视频)以及文本轨道。
语法
在 HTML 中:
1 | <audio|video onloadedmetadata="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.onloadedmetadata=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("loadedmetadata", function() |
loadeddata
当当前帧的数据已加载,但没有足够的数据来播放指定音频/视频的下一帧时,会发生 loadeddata 事件。
语法
在 HTML 中:
1 | <audio|video onloadeddata="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.onloadeddata=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("loadeddata", function() |
progress
当浏览器正在下载指定的音频/视频时,会发生 progress 事件。
语法
在 HTML 中:
1 | <audio|video onprogress="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.onprogress=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("progress", function() |
canplay
当浏览器能够开始播放指定的音频/视频时,发生 canplay 事件。
语法
在 HTML 中:
1 | <audio|video oncanplay="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.oncanplay=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("canplay", function() |
canplaythrough
当浏览器预计能够在不停下来进行缓冲的情况下持续播放指定的音频/视频时,会发生 canplaythrough 事件。
语法
在 HTML 中:
1 | <audio|video oncanplaythrough="SomeJavaScriptCode"> |
在 JavaScript 中:
1 | audio|video.oncanplaythrough=SomeJavaScriptCode; |
使用 addEventListener():
1 | audio|video.addEventListener("canplaythrough", function() |
以上事件好多都能利用,我们随便拿loadeddata为例进行说明
1 | // 设置视频开始播放的当前时间 |
此时就可以将图片截取下来了,截取的正是oVideo.currentTime我们设置的时间,使用火狐等其他浏览器测试正常,拿到了视频和截图的datauri就可以进行上传操作了,但是使用chrome截取的是一张透明图片,根据观察oVideo.addEventListener(“canplay”, function)时第一张也是透明图片,第二张及以后都是正常的图片,大家可以利用这个来解决chrome上的问题。
后端处理
我们这里后端以python为例,用到了OpenCV。
安装方式
1 | pip install opencv-python |
代码实例
1 | # 获取验证通过的视频字段对象 |
此时同样获取到了提交的视频并且截取了图片,就可以将视频进行保存返回给前端保存后的视频地址及图片地址