发布视频时候,经常需要上传同时上传视频的缩略图,近日,应产品经理的的要求,需要做一个发布视频动态的功能,我第一反应就想到了H5的标签vidio和canvas,在这里记录下我完成该功能的过程:

首先,整体思路是创建一个vidio,然后创建一个canvas和一个画笔,调用画笔的drawImage方法,将vidio作为参数,就会画出该视频的缩略图。

二话不说撸代码:

function creatImg() {

const video = document.getElementById('videoPreview');

const canvas = document.createElement('canvas');

const ctx = canvas.getContext('2d');

const imgHeight = video.videoHeight;

const imgWidth = video.videoWidth;

ctx.drawImage(video, 0, 0, imgWidth, imgHeight);

const imgSrc = canvas.toDataURL('image/png');

console.log(imgSrc);

}

该方法是在上传视频发送ajax成功的回调函数中调用的,

// 上传视频

$('#video').on('change', (e) => {

const video = e.currentTarget.files[0];

const formData = new FormData();

formData.append('file', video);

$.ajax({

url: videourl,

crossDomain: true,

data: formData,

dataType: 'json',

method: 'POST',

contentType: false,

processData: false,

timeout: 0,

}).done((jsonData) => {

//设置video标签的src操作

setTimeout(() => {

creatImg();

}, 500);

}).fail(() => {

layer.alert('上传失败', { shift: 5 });

})

});

这样就完成这个功能了......开玩笑,怎么能让你好过?运行后报了如下bug:

这个bug的意思是:脏的canvas不会被引入,出现这个问题的原因是canvas中引用的视频对象跨域了,从而污染了canvas,解决问题的方法是在canvas中引入本地的视频对象,其实做法很简单,改变一下creatImage引用的位置,在类型为file的input标签数组中取到video对象,这里的video对象是本地的,从而不会出现跨域的现象,如下面代码所示:

$('#video').on('change', (e) => {

const video = e.currentTarget.files[0];

creatImg(video);

// const videoName = video.name;

const formData = new FormData();

formData.append('file', video);

const index = layer.load(2);

$.ajax({

url: `${upload_url}/toServer`,

crossDomain: true,

data: formData,

dataType: 'json',

method: 'POST',

contentType: false,

processData: false,

timeout: 0,

}).done((jsonData) => {

//这是video的src属性值的相关操作

}).fail(() => {

layer.alert('上传失败', { shift: 5 });

})

});

const video = e.currentTarget.files[0];这里的video是本地的video对象,接下来,我们优化一下creatImg函数,如下代码所示:

function creatImg(stream) {

const video = document.createElement('video');

video.addEventListener('loadedmetadata', function loadedmetadata() {

setTimeout(() => {

const canvas = document.createElement('canvas');

canvas.width = this.videoWidth;

canvas.height = this.videoHeight;

const ctx = canvas.getContext('2d');

ctx.drawImage(this, 0, 0);

const image = new Image();

image.src = canvas.toDataURL('image/png');

image.onload(() => {

const formData = new FormData();

formData.append('file', dataURItoBlob(canvas.toDataURL('image/png')), `${+new Date()}.png`);

$.ajax({

url: upload_url,

crossDomain: true,

data: formData,

dataType: 'json',

method: 'POST',

contentType: false,

processData: false,

}).done((jsonData) => {

//.....

//将值存储在id为thumbnail的input标签当中的value属性当中

const body = jsonData.body;

$('#thumbnail').val(body);

}).fail(() => {

layer.alert('上传失败');

});

});

}, 300);

}, false);

video.src = URL.createObjectURL(stream);

video.play();

}

创建canvas,创建画笔,将video对象传入画出图片,这一系列操作都是在video加载之后完成的,所以,所有操作都在video监听的loademetadata的回调函数当中完成的,在图片画好以后需要将该图片上传到服务器,通过FormData对象来生成用于ajax向服务器发送的name:value的键值对,在给FormData添加键值对是调用append方法,append方法的第一个参数字段名,第二个参数是字段值,这里的字段值是一个Blob对象,第三个参数是文件名称,这里创建Blob的方法是 dataURItoBlob方法,如下面代码所示,因为canvas.toDataURL的方法返回的是图片的Base64的编码,所以这个函数的作用就是将Base64的编码转换成Blob对象,具体过程如代码所示:

function dataURItoBlob(dataURI) {

const binary = atob(dataURI.split(',')[1]);

const array = [];

for (let i = 0; i < binary.length; i += 1) {

array.push(binary.charCodeAt(i));

}

return new Blob([new Uint8Array(array)], { type: 'image/png' });

}

这里首先调用window的atob的方法,将被编译成的Base64的数据解码成二进制的数据,接下来调用binary对象的charCodeAt方法来将制定位置上的二进制数据进行unicode编码,并把所有的编码后的数据存储在数组当中,最后根据这个数组创建一个Unit8Array的对象,该对象是无符号8位整数,因为初始化Blob时的第一个参数必须是数组,所以要把这个8位无符号整数存放在数组当中。

总结:在完成这个功能的过程中涉及道几个重要的知识点,罗列在下面,我将在后面的相关文章当中逐一具体介绍:

1、canvas的video必须是同域的,如果video跨域了,那么将会污染canvas

2、在向服务器发送图片的时候,需要用到几个重要的对象和方法

FormData对象:可以让XMLHttpRequest发送键值对组成的对象

window.atob方法:将Base64的数据解码成二进制的数据

binary.charCodeAt方法:将二进制的数据进行unicode编码

Uint8Array对象:通过传入的数组创建一个无符号的八位整数

Blob对象:不可变的,原始数据的类似文件对象

html5 视频缩略图,应用canvas获取video的缩略图相关推荐

  1. 压缩视频 html5播放,将HTML5视频呈现为Canvas正在压缩图像

    我正在尝试使用getUserMedia从用户的网络摄像头拍摄照片. 来自相机的图像是640×480(可能是任何尺寸,具体取决于用户的网络摄像头). 我有一个视频标签,大小为320×240与css,我即 ...

  2. js倒计时结束后播放音乐html5,倒计时到HTML5视频结束(Countdown to the end of the HTML5 video)...

    倒计时到HTML5视频结束(Countdown to the end of the HTML5 video) 我可以倒数到HTML5视频的结尾吗? Video ends after XX second ...

  3. 视频截图html,canvas与html5实现视频截图功能(示例代码)

    这段时间一直在研究canvas,突发奇想想做一个可以截屏视频的功能,然后把图片拉去做表情包,哈哈哈哈哈哈~~ 制作方法: 1.在页面中加载视频 在使用canvas制作这个截图功能时,首先必须保证页面上 ...

  4. android获取图片缩略图,Android系获取图片和视频的缩略图

    获取手机里视频缩略图: public static Bitmap getVideoThumbnail(ContentResolver cr,Uri uri) { Bitmap bitmap = nul ...

  5. 平板电脑支持html吗,HTML5视频无法在平板电脑上播放(HTML5 video not playing on tablets)...

    HTML5视频无法在平板电脑上播放(HTML5 video not playing on tablets) 下午好,我早些时候发布了一些内容,但仍然需要帮助. 我有一个Nexus 7和一个IPad2. ...

  6. jquery video全屏_用videojs让HTML5视频在移动端全屏的方法

    用videojs让HTML5视频在移动端全屏的方法 文章标签: 视频 : 04-10 19:23 : 1859次 : 0条 1赞 点赞 简介在使用videojs插件时,如何让HTML5的视频在移动端里 ...

  7. video视频转成canvas(兼容至IE8+,全原生JS)

    video视频转成canvas(兼容至IE8+,全原生JS) <!DOCTYPE html> <html lang="en"> <head>&l ...

  8. HTML5 视频转换软件 Freemake Video Converter

    为什么80%的码农都做不了架构师?>>>    HTML5的Video标签可以说算是HTML5的重头戏,各大浏览器都纷纷响应,现代浏览器都能支持Video标签,基于Video标签的播 ...

  9. html5 video播放按钮放在中间,在html5视频控制区跟踪点击播放按钮(Track clicks to play button in html5 video control area)...

    在html5视频控制区跟踪点击播放按钮(Track clicks to play button in html5 video control area) 我点击了一张HTML5视频播放海报,并点击了控 ...

  10. HTML5视频标签 video 的 poster 属性

    <video> 标签定义视频,比如电影片段或其他视频流,可以放置视频资源,并添加视频控件. 支持的浏览器: Internet Explorer 9+, Firefox, Opera, Ch ...

最新文章

  1. 微信公众平台开发书籍推荐
  2. tensorflow函数总结
  3. sonar.exclusions 配置无效问题
  4. Linux服务之nginx服务篇一(概念)
  5. pythonb超分辨成像_深度原理与框架-图像超分辨重构-tensorlayer
  6. Bagging Classifier+Regressor
  7. [转载] c++list遍历_List、Set、数据结构、Collections
  8. Android study week1
  9. 神策分析 iOS SDK 架构解析
  10. 从零开始学OpenCV(一)——OpenCV的安装
  11. 发动机冒黑烟_发动机冒黑烟常见的24个原因和解决方法
  12. 四、异常(高琪java300集+java从入门到精通笔记)
  13. 视频剪辑工具,视频怎样批量加背景音乐和特效
  14. 雷电模拟器连接android studio教程
  15. 7、Callable接口
  16. java上传图片报404_如何解决SpringBoot集成百度UEditor图片上传后直接访问404
  17. Java邮件收发,以及获取收件箱和发件箱 自测可用 使用JavaMail
  18. VR——VRTK案例详解1-16
  19. allegro SPMHDB-225 The maximum number of text sizes has been reached.错误解决办法
  20. SpringBoot整合--配置文件

热门文章

  1. UVA 12304 2D Geometry 110 in 1! 六个直线与圆的问题+经典几何
  2. SMURF(5R)-Science封面文章使用的16S新流程(二)
  3. ASP.NET Core 中文文档 第四章 MVC(3.7 )局部视图(partial)
  4. GlusterFS(上)
  5. 2018年8月PMI全球认证人士及《项目管理知识体系指南(PMBOK® 指南)》发行量统计数据公布
  6. 四月送书活动获奖名单
  7. codewars Kata——Persistent Bugger问题
  8. 从host端对Windows虚机进行内存dump和分析
  9. 有看板娘的vuepress-theme-ting清新简易主题
  10. 弹性公网IP、私有IP、浮动IP、虚拟IP之间有何区别?