阅读 263

JS获取视频第N秒作为封面图片(js获取视频第一帧图片)

引言

最近开发的时候遇到了一个需求,截取视频第一帧作为视频的封面,结果第一帧是黑屏,所以产品提出,希望可以截取的不是黑屏的作为封面。
于是我们先定一个小目标:实现截取第N秒作为视频封面。

注意事项

  • 视频地址必须同源或者是支持跨域访问

  • 设置视频播放时间后,再监听canplay事件。

整体步骤

  1. 获取视频基本配置信息。

  2. 视频当前播放时间设置到第N秒。

  3. 当视频可以播放时,我们截取视频作为图片地址。

详细步骤

封装:获取视频基本配置信息

通过获取视频的基本信息,我们可以知道视频分辨率与时长,为后面的步骤提供必要的信息。

// 获取视频基本信息 function getVideoBasicInfo(videoSrc) {     return new Promise((resolve, reject) => {         const video = document.createElement('video')         video.src = videoSrc         // 视频一定要添加预加载         video.preload = 'auto'         // 视频一定要同源或者必须允许跨域         video.crossOrigin = 'Anonymous'         // 监听:异常         video.addEventListener('error', error => {             reject(error)         })         // 监听:加载完成基本信息,设置要播放的时常         video.addEventListener('loadedmetadata', () => {             const videoInfo = {                 video,                 width: video.videoWidth,                 height: video.videoHeight,                 duration: video.duration             }             resolve(videoInfo)         })     }) } 复制代码

封装:截取视频作为图片地址

这里我们进行封装,传入视频信息,当视频可以播放后,再视频绘入canvas,否则会导致在将canvas转换成图片地址,因为绘入canvas的缘故,所以我们的视频才需要同源或者允许跨域。

// 将视频信息转化为canvas function getPosterUrlByVideo(videoInfo) {     return new Promise(resolve => {         const { video, width, height } = videoInfo         video.addEventListener('canplay', () => {             const canvas = document.createElement('canvas')             canvas.width = width             canvas.height = height             const ctx = canvas.getContext('2d')             // 绘制到canvas中             ctx.drawImage(video, 0, 0, width, height)            // 将canvas转化为图片url             const posterUrl = canvas.toDataURL('image/png')             resolve(posterUrl)         })     }) } 复制代码

串联代码

我们将整体串联起来,先获取视频信息,在判断指定的秒数是否超出视频最大的时长,再设置视频的当前播放时间为指定的秒数,当视频可以播放了,再截取当前的视频为图片地址。

// 根据视频url截取视频第N秒 function getVideoPosterByFrame(videoSrc, targetTime) {     return getVideoBasicInfo(videoSrc).then(videoInfo => {         const { video, duration } = videoInfo         // 判断时长是否超出         if (targetTime > duration) {             throw new Error('指定的时长大于播放时长')         }         // 设置视频到指定时长         video.currentTime = targetTime         return getPosterUrlByVideo(videoInfo)     }) } 复制代码

整体代码与调试

// 获取视频基本信息 function getVideoBasicInfo(videoSrc) {     return new Promise((resolve, reject) => {         const video = document.createElement('video')         video.src = videoSrc         // 视频一定要添加预加载         video.preload = 'auto'         // 视频一定要同源或者必须允许跨域         video.crossOrigin = 'Anonymous'         // 监听:异常         video.addEventListener('error', error => {             reject(error)         })         // 监听:加载完成基本信息,设置要播放的时常         video.addEventListener('loadedmetadata', () => {             const videoInfo = {                 video,                 width: video.videoWidth,                 height: video.videoHeight,                 duration: video.duration             }             resolve(videoInfo)         })     }) } // 将获取到的视频信息,转化为图片地址 function getPosterUrlByVideo(videoInfo) {     return new Promise(resolve => {         const { video, width, height } = videoInfo         video.addEventListener('canplay', () => {             const canvas = document.createElement('canvas')             canvas.width = width             canvas.height = height             const ctx = canvas.getContext('2d')             ctx.drawImage(video, 0, 0, width, height)             const posterUrl = canvas.toDataURL('image/jpg')             resolve(posterUrl)         })     }) } // 根据视频url截取视频第N秒 function getVideoPosterByFrame(videoSrc, targetTime) {     return getVideoBasicInfo(videoSrc).then(videoInfo => {         const { video, duration } = videoInfo         // 判断时长是否超出         if (targetTime > duration) {             throw new Error('指定的时长大于播放时长')         }         // 设置视频到指定时长         video.currentTime = targetTime         return getPosterUrlByVideo(videoInfo)     }) } // 这里是通过http-server开启本地服务,让视频与本地的代码同源了 const videoSrc = 'http://127.0.0.1:8081/trailer.mp4' const targetTime = 15 const src = getVideoPosterByFrame(videoSrc, targetTime).then(posterSrc => {     const image = new Image()     image.src = posterSrc     document.body.append(image) }).catch(error => {     console.log(error) })


作者:春道
链接:https://juejin.cn/post/7036289153578827812


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐