javascript实现截取视频第一帧的方法

  介绍

这篇文章将为大家详细讲解有关javascript实现截取视频第一帧的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

javascript截取视频第一帧

一、背景

在企业资料的开发中,除了涉及到视频上传之外,还需要使用视频中的第一帧或者或许几帧作为视频封面展示。

产生的问题:

因此,JS截取视频第一帧的难点就此诞生,但是查阅了资料发现,网上提供的资料无外乎俩种,第一种是<强> wasm + ffmpeg 强配合后端去截取,第二种是JS自行截取。优缺点也是显而易见的,第一种,配合成本比较高,而且不是很灵活;第二种可以满足一般条件下的使用,但是会有兼容问题(即再见)以及截取黑屏的问题。

二,wasm + ffmpeg

这种方式优缺点也是显而易见的,配合成本比较高,而且会造成网络内存的急剧飙升,但是支持的视频种类已经截取的帧数是很灵活的;由于涉及到服务端,具体可以参考wasm + ffmpeg截取视频。

三,javascript前端截取

这里前端截取的话就需要了解<强>视频,帆布强标签的兼容性和响应事件了。而且对IE可能不是那么友好。

1。画布的知识这里不做过多补充、下面主要看一下视频标签的响应事件有哪些:

<强>执行结果

根据顺序,第一个被触发的竟然是<强> timeupdate 事件,按设想来说,最先执行的应该是<强> loadedmetadata 强,元数据加载完毕。关于这一点,在MDN上没有明确的说明,但是可以推理一下:

当<强> currentTime 更新时会触发<强> timeupdate 事件

<强> 结论 :虽然最先触发,但是此时视频文件尚未加载,截取的是帆布的无内容本身。注:timeupdate事件根据使用的系统不同,每秒触发4 - 66次,且由于触发频率高,单位过小(毫秒级别),事件响应需要延迟等原因,无法完全精准的控制。

    <李>

    loadedmetadata上文提到,元数据加载完毕之后即触发,但数据中并不包括视频文件本身。结论:如果视频文件较大,加载时间较长,仍然无法截取到已加载的第一帧。补充:通过URL.createObjectURL()方法能够基本做到无察觉,但并不保险。

    <李>

    loadeddata当前帧数(第一帧)加载完毕触发,没毛病。结论:可用。补充:万一第一帧是黑屏想用下一帧怎么办,对不起,余下帧数加没加载完不在它的考虑范围之类,这个事件不管。

    <李>

    canplay视频能够开始播放时触发,也就是根据上传的视频帧数决定加载多少帧(24/25/30/60等等)后满足播放画面后触发。总结:因为加载相对于loadeddata的事件来说更多(多一丢丢),总体可行。补充:通过控制currentTime可以满足(但不可能是第二帧那么准确),可以看做“当前播放帧”。

    <李>

    玩开始播放时才会触发,和上传快速截取的需求不是很符合。

    <李>

    等待已播放但下一画面没缓冲好时触发,适合插播小广告。

2。了解上面的响应事件之后,让我们来看一下接下来截取操作:

上面的的结果是什么呢?

可以看到已经很成功的截取到了视频的第一帧,那么到此阶段,其实已经基本实现了需求,但是图片是否是有效的,这个还未可知,所以需要我们进一步去判断。

3。第一帧是否有效

其实,截取到的第一帧图片,有些时候由于视频的质量不佳或者一些其他因素影响,截取到的图片往往不是很符合预期,一直与会出现纯黑的图片,透明图片,白色图片等等无效图片。因此,我们需要进行一下图片有效性的识别。   那么,怎么去识别图片的有效性呢?

这时候,你就需要认识一个新属性了:<强> Uint8ClampedArray

Uint8ClampedArray(8位无符号整型固定数组)类型化数组表示一个由值固定在0 - 255区间的8位无符号整型组成的数组,如果你指定一个在[0255]区间外的值,它将被替换为0或255,如果你指定一个非整数,那么它将被设置为最接近它的整数。(数组)内容被初始化为0。一旦(数组)被创建,你可以使用对象的方法引用数组里的元素,或使用标准的数组索引语法(即使用方括号标记)。

如果对<强> Uint8ClampedArray 强感兴趣,可以异步这里进一步研究Uint8ClampedArray。

你是不是发现了什么? 0 ~ 255这个是不是常见的数值,颜色的十六进制对应的数值。好,那么,接下来就是按照我们所思考好的去实现,看看是不是这么一个原理。 javascript实现截取视频第一帧的方法

javascript实现截取视频第一帧的方法