ribbon image search rewind fast-forward speech-bubble pie-graph star

使用 JS 直接截取 视频片段 生成 gif 动画

最近大家对这个表情 非常熟悉。

最近看到 张大大 《纯前端实现可传图可字幕台词定制的GIF表情生成器》 写的关于 前端做 GIF 的文章。由于最近也一直接触的视频,所以就干脆直接再进一步,以后直接通过一个库快速生成 gif 。

直接放参考 DEMO 效果

实现原理

其实相对而言,也是利用了一个核心库 gif.js, 它可以直接将传入 canvas 对象实现截图然后保存为最后 blob 对象。

var gif = new GIF({  
  workers: 2,
  quality: 10
});

// add an image element
gif.addFrame(imageElement);

// or a canvas element
gif.addFrame(canvasElement, {delay: 200});

// or copy the pixels from a canvas context
gif.addFrame(ctx, {copy: true});

gif.on('finished', function(blob) {  
  window.open(URL.createObjectURL(blob));
});

gif.render();  

除此之外,自己还利用了 daycaca ,它可以将传入的 Video 元素实现转换成 base64 的图片输出。不光支持传入 video ,也可以将 IMG 元素 或者直接一个图片地址进行转码。

 daycaca.base64(this.video, (source, canvas) => {
          // ...
        this._gif.addFrame(canvas, {delay: intvalTime})
      })

然后我们可以通过 setTimeout/ setInterval 来实现 循环截图,因此你需要设置好自己的 fps, 比较gif和视频比较, gif 不需要那么高的频率,大概每秒 6 帧都是可以接受的。

core-video-to-gif

当然自己进行了一个封装,方便大家在今后的项目使用这样的功能。

core-video-to-gif是一款支持将视频截取为 gif 的前端 JavaSCript 类库。

NPM

$ npm install core-video-to-gif --save

CDN

<script src="./dist/core-video-to-gif.min.js"></script>  

在页面中代码:

const v2g = new CoreVideoToGif({  
    // specify the video element
    el: document.querySelector('video')
})
v2g.shot({  
    // options,
    start: 5, // ms
    end: 8
}, (result) => {
    // ...
    image.src = result
})
初始化的参数
key Type Details Value
“*” el Element 需要截取的视频元素 <video ... >
workerScript Element 启用 WebWorker 的 gif 脚本 在本地保留这段脚本[文件](https://github.com/JackPu/core-video-to-gif/blob/master/examples/gif.worker.js), 然后指定路径
width Number 输出 gif 的宽度 600(default: the video original height)
height Number 输出 gif 的高度 600(default: the video original height)
maxTime Number 限制 gif 的最长时间 5(default: 10)
fps Number 每秒多少帧 12(default: 6)
quality Number 输出图片你的质量 (1-10) The best is 10
onStartShot Function 当开始截图的时候触发
onGifProcess Function 当开始制作 Gif 的时候触发
onGifFinished Function 当完成 Gif 的时候触发

“*” 表示必须设置的

API

shot(params, callback)

截取某个片段的截图

 // get current screenshot
v2g.shot( (result) => {  
    // ...
    image.src = result
})
// get screenshot from 5s - 8s
v2g.shot({  
    // options,
    start: 5, // ms
    end: 8
}, (result) => {
    // ...
    image.src = result
})

##### 参数含义

key Type Details Value
start Number 开始的时间 6(s)
end Number 结束的时间 7(s)

目前还在开发中,后期打算支持上传等功能。

项目地址

扩展阅读

You Can Speak "Hi" to Me in Those Ways