接上篇 js图片/视频预览 - URL.createObjectURL() [iframe]https://mp.weixin.qq.com/mp/readtemplate?t=pages/video_player_tmpl&action=mpvideo&auto=0&vid=wxv_913496302246428672[/iframe]
当视频能够预览并上传后,非要来一张视频第一帧的截图贴上,第一帧是黑的怎么办,下一帧。
[h2]一、文件上传[/h2]使用事件作为预览的的触发条件
新鲜源码:
[h2]二、canvas截取图片[/h2]关于截取或者处理图片/视频/富文本编辑器,是一个非常nice的选择。
1.创建画布或在中直接写入。
- var canvas = document.createElement('canvas');
复制代码 2.创建基于的绘图环境
- var ctx = canvas.getContext('2d');
复制代码 附 Q&A:
网络上的常规理解是“在准备画布后,需要一些‘染料、画笔、绘图工具’的准备工作。”
比较官方的说话是返回的上下文环境,
说人话是'你能够更好的操作你的'。
方法中的参数目前可以理解为是,表示想要一个绘制环境。虽然大家都认为有自然应该有,然而实际上本身设计时也是这么考虑的,不过大家有点等不起了,所以都去选择了。是啥?浏览器端借助系统显卡进行 3D 绘图。这是另一个故事了(别想了)。
返回一个对象,也就是上文所说的能够支持绝大多数对画布的操作。
3.在上绘制图片
- // ctx.drawImage(file,sx,sy,swidth,sheight,x,y,width,height);
复制代码- ctx.drawImage(this, 0, 0, swidth, sheight);
复制代码 在不需要剪裁的情况下,使用上述参数即截取操作的全部,绘制到上
关于参数(w3school)
参数描述file规定要使用的图像、画布或视频。sx可选。开始剪切的 x 坐标位置。sy可选。开始剪切的 y 坐标位置。swidth可选。被剪切图像的宽度。sheight可选。被剪切图像的高度。x在画布上放置图像的 x 坐标位置。y在画布上放置图像的 y 坐标位置。width可选。要使用的图像的宽度。(伸展或缩小图像)height可选。要使用的图像的高度。(伸展或缩小图像)4.将导出成图片放入- var src = canvas.toDataURL('image/jpeg');
复制代码 关于方法。将的内容导出
- canvas.toDataURL(type, encoderOptions);
复制代码 : 图片格式,默认,:图片质量,取值范围为0到1,默认0.92。:包含的,也就是格式。
[h2]三、截取视频第一帧[/h2]上传文件OK,用截取OK,怎么找呢?(啥时候开始截取呢?)
当然是多媒体的事件来触发。关于的事件非常多(全部事件),这里只讨论能够影响到截取到第一帧的各个事件。
- video.addEventListener('loadeddata', consoleString.bind(video, 'loadeddata')) // 当前帧加载完毕
复制代码- video.addEventListener('loadedmetadata', consoleString.bind(video, 'loadedmetadata')) // 视频元数据加载完毕
复制代码- video.addEventListener('canplay', consoleString.bind(video, 'canplay')) // 视频缓冲能够开始播放
复制代码- video.addEventListener('timeupdate', consoleString.bind(video, 'timeupdate')) // 播放位置发生改变时
复制代码- video.addEventListener('play', consoleString.bind(video, 'play')) // 开始播放时
复制代码- video.addEventListener('waiting', consoleString.bind(video, 'waiting')) // 要播放下一帧而需要缓冲时
复制代码
- function consoleString(string) {
复制代码
- // 没有waiting, 因为视频较小不需要缓冲
复制代码
- 根据顺序,第一个被触发的竟然是事件,按设想来说,最先执行的应该是,元数据加载完毕。关于这一点,在MDN上没有明确的说明,但是可以推理一下:
来源:MDN的元数据恰好是指,也就是说在未定义的时候是或,当元数据中时长加载完毕后,更新至,因此触发。
结论:虽然最先触发,但是此时视频文件尚未加载,截取的是的无内容本身。注:事件根据使用的系统不同,每秒触发4-66次,且由于触发频率高,单位过小(毫秒级别),事件响应需要延迟等原因,无法完全精准的控制。
loadedmetadata
上文提到,元数据加载完毕之后即触发,但数据中并不包括视频文件本身。结论:如果视频文件较大,加载时间较长,仍然无法截取到已加载的第一帧。补充:通过方法能够基本做到无察觉,但并不保险。
loadeddata
当前帧数(第一帧)加载完毕触发,没毛病。结论:可用。补充:万一第一帧是黑屏想用下一帧怎么办,对不起,余下帧数加没加载完不在它的考虑范围之类,这个事件不管。
canplay
视频能够开始播放时触发,也就是根据上传的视频帧数决定加载多少帧(24/25/30/60等等)后满足播放画面后触发。总结:因为加载相对于的事件来说更多(多一丢丢),总体可行。补充:通过控制可以满足(但不可能是第二帧那么准确),可以看做“当前播放帧”。
play
开始播放时才会触发,和上传快速截取的需求不是很符合。
waiting
已播放但下一画面没缓冲好时触发,适合插播小广告。
文件、方法、事件都OK了。截就完事儿了。
- video.addEventListener('loadeddata', function (e) {
复制代码- canvas.width = this.videoWidth
复制代码- canvas.height = this.videoHeight
复制代码- height = this.videoHeight
复制代码- ctx.drawImage(this, 0, 0, width, height);
复制代码- var src = canvas.toDataURL('image/jpeg');
复制代码- // var currentTime = this.currentTime
复制代码- // duration = this.duration
复制代码- // var fps = duration / 30
复制代码
Dome:https://243341386.github.io/review_dome/
|
|