node环境中使用fluent-ffmpeg每隔一秒视频截图

这篇文章发布于 2024年04月22日,星期一,11:20,归类于 JS实例。 阅读 1055 次, 今日 8 次 4 条评论

 

封面占位图,草泥马先生

一、需求产生的背景

之前有撰文(使用JS快速获取video视频任意位置的缩略图)介绍过纯前端获取视频的截图,按照每秒获取一张的频率去获取,性能还是可以的。

但是,怪事发生了,最近几个版本的Chrome不知道改动了什么东西,使用<video>元素获取视频缩略图的性能变得极差,注意这里的副词,是“极”,区别非常明显。

这可就非常影响用户体验了。

当然,也不是没有解决方法,那就是使用mp4box.js加WebCodecs去解码,但是,这个方法门槛有点高,很多前端小伙伴是玩不转的。

所以就想着,要不缩略图就不实时获取了,直接写个Node.js服务,线下提前跑任务生成好就好了。

于是就有了这次的需求。

二、不哔哔直接上代码

如何安装 node-fluent-ffmpeg 我这里就不啰嗦了,安装失败自己想办法哈。

假设已经新建了一个名为temp的临时文件夹,用来存放缩略图。

const ffmpeg = require("fluent-ffmpeg");

// 每间隔2秒截取缩略图
const videoPath = './sources/zhangxinxu.mp4';
console.log('正在获取视频缩略图...');
const time = Date.now();
// 下面是核心执行方法
ffmpeg(videoPath)
  .fps(0.5)
  .size('128x?')
  .save('./temp/thumb-%04d.jpg')
  .on('error', (err) => {
    console.log('获取视频缩略图失败', err);
  })
  .on('end', () => {
    console.log('获取视频缩略图成功,耗时:', (Date.now() - time) / 1000 + 's');
});

各语句作用说明

  • fps()方法可以改变视频的帧率,fps(0.5)表示每秒视频的帧数是0.5,也就是没2秒才有一帧视频。
  • size(‘128x?’)表示改变原始视频的尺寸,宽度为128px像素,高度按照原始视频比例自动计算。
  • thumb-%04d.jpg中的%04d表示图片序列安装0000.jpg、0001.jpg这种四位补全的方式命名(保证排序)。具体多少位补零,要根据图片数量来,例如,一个10min的视频,总共600s,会产生300张缩略图,因此,图片序列的最大值也就是300。

    如果你能保证你你要处理的视频时长都在10分钟以下,那么使用%03d.jpg就足够。%04d.jpg可以保证2小时的视频都不会有序列不足的问题。

如果不出意外,就可以输出如下图所示的图片序列结果。

缩略图运行结果示意

三、如果希望对缩略图打包?

图片序列虽然是最终需要的资源,但是要是文件数量太多,传输的成本就会大大增加。

例如,Web网页前端需要使用这些缩略图的时候,总不可能一下子发出几十、上百个请求去拉取这些图片吧。

浏览器愿意干这件事,人家服务器还不愿意呢。

如果走ZIP打包,那么前端就只有一个请求,前端再使用JavaScript解压,效果也是一样的。

我是使用zip-local这个项目实现ZIP打包的,因为语法简单,而我们这里的打包操作比较简单,因此,这个项目就比较适合,Github地址:https://github.com/Mostafa-Samir/zip-local

使用示意:

const zipper = require("zip-local");
// 打包图片文件夹
const zipBuffer = zipper.sync.zip('./temp').memory();

此时,zipBuffer就是zip文件的buffer数据,我们可以用来上传到cos存储上,也可以下载到本地,代码示意:

fs.writeFileSync(`./videoThumb-by-zhangxinxu.zip`, zipBuffer);

PS: 前端解压可以使用jszip,之前有个ZIP打包合成并下载的需求,我就用过此项目。

四、就扯这么多吧

噢啦,就扯这么多吧。

日常工作的一点小小记录。

fluent-ffmpeg这个项目的使用示意文档还是比较全的,基本上常见的视频操作都有示意。

大家如果有什么不懂的,欢迎评论交流,我还是累积了不少使用经验的。

本周日似乎要补五一的假,要上班。

我的工作原则是绝对不会恋上6天半,所以,本周日会请年假,到时候,去河边吹吹风,做做简单的休闲运动——就是钓鱼啦,哈哈哈。

看看,这是昨天下午的钓货,两个鱼护,上百斤了。😏

渔获示意

(本篇完)

分享到:


发表评论(目前4 条评论)

  1. 代码如诗如画说道:

    前端数几载,不会Node,这在前端圈属于什么水平

  2. meepo说道:

    好多鱼啊

  3. helsonlin说道:

    更新的很勤快