热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

H5video标签列表渲染用canvas截取视频画面做封面

这是一个关于h5的video视频播放标签来做视频播放截取视频画面的问题。需求是这样的:要渲染一个视频资源列表,在列表中获取视频的画面来做列表的封面。看到这个需求就想,为什么要在列表
这是一个关于h5的video视频播放标签来做视频播放截取视频画面的问题。

需求是这样的:要渲染一个视频资源列表,在列表中获取视频的画面来做列表的封面。看到这个需求就想,为什么要在列表里截取视频画面做封面,为什么不是后端返回图片url呢?没有那么多为什么,做出来就是了。

首先是找百度,怎么截取h5视频的画面,搜了一遍,大都是通过canvas来画出来的。基本实现过程是:通过video标签把视频加载进来,设置display:none; 把video标签隐藏起来,然后通过canvas的drawImage方法把视频画面画出来,得到一个base6位的图片编码,然后将这个base64位的编码赋给img标签的src即可。

先来一串代码:

html:

"output">

js:
captureImage() {
const output = document.getElementById('output')
const video = document.getElementById('video')
const canvas = document.createElement('canvas')
canvas.width = video.videoWidth * 0.3
canvas.height = video.videoHeight * 0.3
const img = new Image()
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height)
const dataUrl = canvas.toDataURL('image/png')
img.src = dataUrl
output.appendChild(img)
},

这是截取一个视频画面的实现代码,可以监听视频加载好了之后执行captureImage() 方法(我这里是基于vue的写法,应该比较好理解)。那接下来进入主题,渲染视频列表,如何去画每个视频的画面呢?这里我写了个公共的方法:

html:

  • for="(item, index) in items" :key="index">
    "video-cover">

    {
    {captureImage(item.id, index, 'items')}}
    "item.cover">


  • js:
    // videoId: 视频标签的id; index: 列表数据的索引;key: this.$data读取列表数据的key
    captureImage(videoId, index, key) {
    const self = this
    setTimeout(function () {
    const videoEle = document.getElementById(videoId)
    const canvas = document.createElement('canvas')
    canvas.width = 265
    canvas.height = 180
    canvas.getContext('2d').drawImage(videoEle, 0, 0, canvas.width, canvas.height)
    const dataUrl = canvas.toDataURL('image/png')
    self.$set(self.$data[key][index], 'cover', dataUrl)
    }, 100)
    }

    这是基于vue的写法,首先写一个截取视频画面的公共方法,在进行列表渲染时,每渲染一个item,调用一次该方法(也可以在updated钩子里循环调用),传入对应的视频标签的id以便获取dom节点。这里加了延时器,一开始没加的时候,发现获取到的videoEle是null,可能是该方法执行的时候,video标签还没渲染好,给个小小的延时就可以了(不知有没有更好的解决方法,就先这样做着了,如果路过的大神有更好的解决方案,还望赐教)。

    以上的做法可以在列表里渲染出视频画面做封面了,高兴了一小会。后来发现,有bug!!!由于浏览器加载视频速度的问题,导致列表中有些封面画出来是一张透明的图片,甚至有时候全部都是透明的图片,可能是画的时候,视频画面还没加载。后来试了好多方法,最终做了小小的优化:

    html:

  • for="(item, index) in items" :key="index">
    class="video-cover"> <video :id="item.id" :src="item.src" x-webkit-airplay="allow" autoplay preload="auto" style="display: none">video> { {captureImage(item.id, index, 'items')}}
    "item.cover">


  • js:
    // videoId: 视频标签的id; index: 列表数据的索引;key: this.$data读取列表数据的key
    captureImage(videoId, index, key) {
    const self = this
    setTimeout(function () {
    const videoEle = document.getElementById(videoId)
    const canvas = document.createElement('canvas')
    canvas.width = 265
    canvas.height = 180
    videoEle.addEventListener('timeupdate', function () {
    canvas.getContext('2d').drawImage(videoEle, 0, 0, canvas.width, canvas.height)
    const dataUrl = canvas.toDataURL('image/png')
    self.$set(self.$data[key][index], 'cover', dataUrl)
    videoEle.pause()
    }, false)
    }, 100)
    }

    这里做了小小的改变,就是在渲染视频列表是让ta自动播放(autoplay),然后在画封面的方法里通过video的timeupdate事件来监听视频播放位置的改变,然后在进行canvas的绘制,绘制完调用video的pause()方法,暂停播放,这样就能保障每个item都能画出不是透明的图片啦。

    The end:可算是把视频列表的封面都画出来了,美中不足的是,视频加载的速度还是没法控制,列表中有些视频加载的慢的,会延时好几秒才画出来。
    以上就是H5 video标签列表渲染用canvas截取视频画面做封面的一个不完美的方法,如果路过的亲有更好的解决方法,望分享,么么哒。


    推荐阅读
    • vue使用
      关键词: ... [详细]
    • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
    • Html5-Canvas实现简易的抽奖转盘效果
      本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
    • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
    • 1、运行npmrundev命令在cmd上面也不算报错输出一些东西看不懂什么意思。报错页: ... [详细]
    • 技术分享:如何在没有公钥的情况下实现JWT密钥滥用
        ... [详细]
    • Webpack5内置处理图片资源的配置方法
      本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
    • Spring特性实现接口多类的动态调用详解
      本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
    • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
    • 本文介绍了如何使用vue-awesome-swiper组件,包括在main.js中引入和使用swiper和swiperSlide组件,以及设置options和ref属性。同时还介绍了如何在模板中使用swiper和swiperSlide组件,并展示了如何通过循环渲染swipes数组中的数据,并使用picUrl属性显示图片。最后还介绍了如何添加分页器。 ... [详细]
    • 网址:https:vue.docschina.orgv2guideforms.html表单input绑定基础用法可以通过使用v-model指令,在 ... [详细]
    • 微信民众号商城/小顺序商城开源项目介绍及使用教程
      本文介绍了一个基于WeiPHP5.0开发的微信民众号商城/小顺序商城的开源项目,包括前端和后端的目录结构,以及所使用的技术栈。同时提供了项目的运行和打包方法,并分享了一些调试和开发经验。最后还附上了在线预览和GitHub商城源码的链接,以及加入前端交流QQ群的方式。 ... [详细]
    • VUE中引用路径的配置
      在vue项目开发中经常引用JS、CSS、IMG文件。当项目较大时文件层级很多,导致路径很长,我们可以通过在bulidwebpack.base.conf.js设置简便的引用路径一、 ... [详细]
    • 本文由编程笔记#小编为大家整理,主要介绍了css回到顶部按钮相关的知识,希望对你有一定的参考价值。 ... [详细]
    • Scrapy 爬取图片
      1.创建Scrapy项目scrapystartprojectCrawlMeiziTuscrapygenspiderMeiziTuSpiderhttps:movie.douban.c ... [详细]
    author-avatar
    haha20101030
    这个家伙很懒,什么也没留下!
    PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
    Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有