栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > Web开发 > JavaScript

一起从零开始手写一个动态视频截图工具吧

JavaScript 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

一起从零开始手写一个动态视频截图工具吧

我们可能经常看到这样的一个功能,在视频播放的过程中,动态的将视频中的某一帧截下来。   或者一些更常见的比如视频首帧截图。那这样的一个功能,具体是怎样实现的?一起来做做吧。

  整体的方案大致是这样:首先需要准备几个子功能模块。首先,得有视频,能播视频,并且可以做到实时的监听视频的进度,其次就是截图了。核心功能有了,除此之外呢?既然是动态的,所以最好还要有一个动态的dom结构插入方便展示结果,还得能方便的更换视频,也就是视频上传,当然我们为了简单化,这里不涉及后台,但以上的功能同样都能实现。

  首先,可以播放视频,通过HTML5的video来实现,具体如何呢?

  下面是一个video标签,这样一个标签,就可以播放视频。


  video如何监听进度的呢?
  video的事件实际上非常多,这里就不一一列举了,我们看MDN,如下图:


  可以看到这里面有一个事件是timeupdate,这就是我们想要的进度监听。


_self.video.addEventListener('timeupdate', function (e) {

    console.log('当下进度为: ' + this.currentTime);
    console.log('视频总时长为: ' + this.duration);
});

  其次,处理截图,处理图片比如对图片做压缩做剪切做各种各样的处理,日常的软件其实就是类似photoshop这样的图片软件,或者更加原始的就是通过画图软件,但程序怎么做呢?画图画图,可能这时候你也意识到了,没有错,基本都可以通过HTML5的画布(canvas)来实现。看一段下面的代码。


//  创建画布
    createCanvas () {

 const canvas = document.createElement('canvas');
 const ctx = canvas.getContext('2d');
 
 this.canvas = canvas;
 this.ctx = ctx;
    }

这时候再配合一下刚刚的timeupdate进度监听,就可以基本实现我们的核心功能了。


var nowTime = 0;

_self.video.addEventListener('timeupdate', function (e) {

    if(this.currentTime > nowTime){

 _self.ctx.drawImage(this, 0, 0, this.videoWidth, this.videoHeight);

 let src = _self.canvas.toDataURL('image/jpeg');

 _self.appendImg(src);
 
 nowTime += _self.speed;
    }
});

  但这时候你会发现,截出来的图不对,好像只截了一部分,这时候就需要设置一下画布的大小了。但因为传入不同的视频,呈现的画面大小其实都是不一致的,所以需要根据视频上传后或者加载后的第一帧,取这时候的video大小。

  这时候video也同样提供一个当video加载完视频文件的第一帧时的事件。即loadeddata。看看:


_self.video.addEventListener('loadeddata', function () {

    _self.canvas.width = this.videoWidth;
    _self.canvas.height = this.videoHeight;
});

  这样我们基本上就完成了核心的功能。

  接下来,再附上一个视频上传的功能,这时候dom结构稍微做一下变动,这其实就是一个典型的隐式表单提交。



//  video文件上传
upLoadFile () {

    let _self = this;

    _self.input.addEventListener('change', function (e) {

 _self.file = this.files[0];
 _self.src = window.URL.createObjectURL(_self.file);

 _self.video.src = _self.src;
    });

    _self.btn.addEventListener('click', function () {

 _self.input.click();
    });
}

  当然,动态截取出来的图片需要让我们的感官有直观的体验,当然是将之动态的展现出来。当然加点Css3的动画效果就更好了。


appendImg (src) {

    var screenshotList = document.querySelector('.screenshotList');

    var oDiv = document.createElement('div'),
 img = document.createElement('img');
 img.src = src;

    oDiv.className = 'pd10 animated bounceInRight';
    oDiv.appendChild(img);

    screenshotList.insertBefore(oDiv, screenshotList.querySelector('div'));

    // screenshotList.appendChild(oDiv);
    // screenshotList.scrollTop = screenshotList.scrollHeight;
}

  这样基本就完成了我们的功能了。

  看一看总体的代码:


class videoCapture {

    constructor (options) {

 this.Dom = options.Dom;

 this.speed = options.speed || 2;

 this.input = this.Dom.querySelector('input');
 this.btn = this.Dom.querySelector('button');
 this.video = this.Dom.querySelector('video');
 this.image = this.Dom.querySelector('img');

 this.file = '';
 this.src = '';

 this.initEvent();
    }

    //  video文件上传
    upLoadFile () {

 let _self = this;

 _self.input.addEventListener('change', function (e) {

     _self.file = this.files[0];
     _self.src = window.URL.createObjectURL(_self.file);

     _self.video.src = _self.src;
 });

 _self.btn.addEventListener('click', function () {

     _self.input.click();
 });
    }
    //  创建画布
    createCanvas () {

 const canvas = document.createElement('canvas');
 const ctx = canvas.getContext('2d');
 
 this.canvas = canvas;
 this.ctx = ctx;
    }
    initEvent () {

 let _self = this;

 _self.upLoadFile();
 _self.createCanvas();
 
 _self.video.addEventListener('loadeddata', function () {

     _self.canvas.width = this.videoWidth;
     _self.canvas.height = this.videoHeight;
 });

 var nowTime = 0;

 _self.video.addEventListener('timeupdate', function (e) {

     if(this.currentTime > nowTime){

  _self.ctx.drawImage(this, 0, 0, this.videoWidth, this.videoHeight);

  let src = _self.canvas.toDataURL('image/jpeg');

  _self.appendImg(src);
  
  nowTime += _self.speed;
     }
 });
    }
    appendImg (src) {

 var screenshotList = document.querySelector('.screenshotList');

 var oDiv = document.createElement('div'),
     img = document.createElement('img');
     img.src = src;

 oDiv.className = 'pd10 animated bounceInRight';
 oDiv.appendChild(img);

 screenshotList.insertBefore(oDiv, screenshotList.querySelector('div'));

 // screenshotList.appendChild(oDiv);
 // screenshotList.scrollTop = screenshotList.scrollHeight;
    }
}
export default videoCapture;

  再看一看调用:


layout: false
title: "视频动态截图"
date: 2019-09-19 20:03:48
---



    
    
    
    
    
    视频动态截图


    

最后呢,当然是上效果了。

效果演示

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号