1

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

 4 months ago
source link: https://www.zhangxinxu.com/wordpress/2024/04/node-fluent-ffmpeg-screenshot-every-second/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=11175 鑫空间-鑫生活
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

封面占位图,草泥马先生

一、需求产生的背景

之前有撰文(使用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天半,所以,本周日会请年假,到时候,去河边吹吹风,做做简单的休闲运动——就是钓鱼啦,哈哈哈。

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

渔获示意

(本篇完)1f44d.svg 是不是学到了很多?可以分享到微信
1f44a.svg 有话要说?点击这里

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=11175


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK