JS利用ffmpeg和sharp玩转音视频和图片

 更新时间:2023年10月24日 10:16:34   作者:Moment  
ffmpeg 是一个非常流行的开源软件套件,用于处理音频和视频数据,而要想对图片之类的进行压缩,我们可以选择 sharp 来进行操作,所以下面我们就来学习一下前端如何利用ffmpeg和sharp玩转音视频和图片吧

前端时间刚从 windows 上切换过去 mac 进行开发,我想找一个能录制 gif 的软件,但是发现并没有比较好的软件,有的都是收费的。

在 mac 上自带的录屏倒是挺不错的,所以我就想有没有什么办法可以将这些视频的格式转换为 gif 格式的。

可能是因为并不是很刚需吧,并没有去找解决方案,直到我今天刷到了一篇文章,我就大概看了一下。

使用 ffmpeg 将视频转 GIF 格式

在开始之前我们大概来了解一下什么是 ffmpeg。

ffmpeg 是一个非常流行的开源软件套件,用于处理音频和视频数据。它提供了多种工具集,如 ffmpegffplayffprobe,这些工具可以用于:

  • 转码:可以将视频和音频从一种格式转换为另一种格式。
  • 播放:使用 ffplay 可以播放多种格式的音频和视频文件。
  • 提取信息:使用 ffprobe 可以获取关于音频和视频文件的详细信息。
  • 流处理:可以捕获和编码实时音频/视频流。
  • 过滤:可以应用各种过滤器来处理音频和视频数据,例如调整亮度、裁剪、调整速度等。

ffmpeg 支持多种音频、视频、字幕和其他相关媒体数据的格式,它的功能非常丰富且灵活,可以满足许多媒体处理的需求。由于其强大的功能和开源的特性,ffmpeg 在多个平台和应用程序中得到了广泛的应用。

大概了解了之后,我们来看看如何在 node 中实现视频转 webp 的,首先安装相关的依赖包:

pnpm add @ffmpeg-installer/ffmpeg fluent-ffmpeg

然后编写一下代码:

const ffmpegPath = require("@ffmpeg-installer/ffmpeg").path;
const ffmpeg = require("fluent-ffmpeg");

const video2Gif = async (videoPath, gifPath, width, fps) => {
  ffmpeg.setFfmpegPath(ffmpegPath); // 设置二进制客户端路径
  ffmpeg(videoPath) // 读入路径
    .outputOptions("-pix_fmt", "rgb24") // 设置像素格式为rgb24
    .output(gifPath) // 输出路径
    .withFPS(fps) // 设置输出GIF的帧率
    .size(`${width}x?`) // 设置输出GIF的宽度,高度等比缩放
    .noAudio() // 禁用音频输出
    .setStartTime("00:00:10") // 开始时间
    .setDuration(15) // 持续时间
    .videoFilters({
      filter: "crop",
      options: {
        out_w: `iw/1.5`, // 裁剪到原始宽度
        out_h: "ih", // 高度保持不变
        x: "(iw-out_w)/2", // 从中心开始裁剪
        y: 0, // y坐标保持在顶部
      },
    })
    .on("end", () => {
      console.log("转换完成!");
    })
    .on("error", (err) => console.error(err))
    .run();
};

video2Gif("./i.mp4", "./index.gif", 600, 80);

这段代码利用 ffmpeg 将一个视频文件的特定 15 秒段落(从 10 秒开始)转换为 GIF 格式。在转换过程中,视频的宽度被裁剪到其原始的 2/3,高度保持不变,同时移除了音频部分。最后,生成的 GIF 保存到指定的路径。

这个时候我们使用 node 运行该文件,内容变输出了。查看文件大小的时候,我们发现文件太大了,虽然我们可以在上面调整参数,但是我偏不哈哈哈哈哈,我就要倔

使用 sharp 压缩 gif

要想对图片之类的进行压缩,我们可以选择 sharp 来进行操作,这里我就不过多说了,直接上代码:

const sharp = require("sharp");
const fs = require("fs");

async function compressGif(filePath, outputPath) {
  const data = await sharp(filePath, {
    animated: true,
    limitInputPixels: false,
  })
    .gif({
      colours: 60,
    })
    .toBuffer();

  // 写入Buffer到文件
  fs.writeFileSync(outputPath, data);
}

compressGif("./index.gif", "./php.gif");

上面这段代码使用 sharp 库对 GIF 文件进行压缩,将其颜色范围减少到 60 fps,从而减小文件大小。压缩后的数据被保存为一个 Buffer,然后写入到新的 GIF 文件路径。

这个时候,gif 被我们压缩到了 20mb 了,也终于能在掘金上面上传了。

将任何格式的图片转换为 webp 格式并添加水印

WebP 是 Google 开发的图片格式,它提供比 JPEG 和 PNG 更高效的压缩,从而达到更小的文件大小而不牺牲图像质量。同时,它支持透明度和动画,且得到了大多数现代浏览器的支持,使其成为网站和应用中优化图像性能的理想选择。

在下面,我们就来使用 sharp 来实现这种转换,如下代码所示:

const sharp = require("sharp");
const fs = require("fs");
const path = require("path");

const sourceDirectory = "./image";
const outputDirectory = "./webp_images";

if (!fs.existsSync(outputDirectory)) {
  fs.mkdirSync(outputDirectory);
}

fs.readdir(sourceDirectory, (err, files) => {
  if (err) {
    console.error("Error reading the directory:", err);
    return;
  }

  files.forEach((file) => {
    const extname = path.extname(file).toLowerCase();
    const filename = path.basename(file, extname);

    const allowedFormats = [
      ".jpg",
      ".jpeg",
      ".png",
      ".tif",
      ".tiff",
      ".bmp",
      ".gif",
    ];

    if (allowedFormats.includes(extname)) {
      const inputFile = path.join(sourceDirectory, file);
      const outputFile = path.join(outputDirectory, `${filename}.webp`);

      const watermarkSvg = `
                <svg width="200" height="80" xmlns="http://www.w3.org/2000/svg">
                    <text x="10" y="40" font-family="Arial" font-size="30" fill="pink" stroke="black" stroke-width="2">Moment</text>
                </svg>
            `;

      sharp(inputFile)
        .webp()
        .composite([
          {
            input: Buffer.from(watermarkSvg),
            gravity: "southeast",
          },
        ])
        .toFile(outputFile, (err, info) => {
          if (err) {
            console.error(`Failed to convert and watermark ${file}:`, err);
          } else {
            console.log(`Converted and watermarked ${file} to WebP format.`);
          }
        });
    }
  });
});

在上面这段代码从一个指定的文件夹中读取图片,将其转换为 WebP 格式并添加一个 SVG 水印在右下角,然后保存转换后的图片到另一个文件夹中。

最终输出结果如下图所示:

水印也被加上去了。

总结

通过巧妙地利用这两者,我们可以做到平时很多我们平时想做的事情,发挥你的想象,去做一些有意义有想法的事情吧。

到此这篇关于JS利用ffmpeg和sharp玩转音视频和图片的文章就介绍到这了,更多相关JS ffmpeg sharp内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript设计模式 – 工厂模式原理与应用实例分析

    javascript设计模式 – 工厂模式原理与应用实例分析

    这篇文章主要介绍了javascript设计模式 – 工厂模式,结合实例形式分析了javascript工厂模式基本概念、原理、定义、应用场景及相关操作注意事项,需要的朋友可以参考下
    2020-04-04
  • js判断数据类型如判断是否为数组是否为字符串等等

    js判断数据类型如判断是否为数组是否为字符串等等

    js判断数据类型如判断是否为数组类型、判断是否为字符串类型、判断是否为数值类型等等,本文有几个不错的示例,大家可以学习下
    2014-01-01
  • JavaScript使用canvas实现flappy bird全流程详解

    JavaScript使用canvas实现flappy bird全流程详解

    这篇文章主要介绍了JavaScript使用canvas实现flappy bird流程,canvas是HTML5提供的一种新标签,它可以支持JavaScript在上面绘画,控制每一个像素,它经常被用来制作小游戏,接下来我将用它来模仿制作一款叫flappy bird的小游戏
    2023-03-03
  • 在线所见即所得HTML编辑器的实现原理浅析

    在线所见即所得HTML编辑器的实现原理浅析

    这篇文章主要介绍了在线所见即所得HTML编辑器的实现原理浅析,本文用初始化、打开编辑功能、获取编辑器的内容、增加样式设置、再进一步等步骤阐述在线编辑器的基本实现原理,需要的朋友可以参考下
    2015-04-04
  • javascript实现图片跟随鼠标移动效果的方法

    javascript实现图片跟随鼠标移动效果的方法

    这篇文章主要介绍了javascript实现图片跟随鼠标移动效果的方法,涉及javascript鼠标事件及页面元素的相关操作技巧,需要的朋友可以参考下
    2015-05-05
  • js获取当月最后一天实例代码

    js获取当月最后一天实例代码

    这篇文章主要介绍了js获取当月最后一天实例代码,有需要的朋友可以参考一下
    2013-11-11
  • Fullpage.js固定导航栏-实现定位导航栏

    Fullpage.js固定导航栏-实现定位导航栏

    FullPage.js 是一个简单而易于使用的插件,用来创建全屏滚动网站(也被称为单页网站)。接下来通过本文给大家介绍Fullpage.js固定导航栏-实现定位导航栏,对fullpage.js导航栏相关知识感兴趣的朋友一起学习吧
    2016-03-03
  • layer.alert自定义关闭回调事件的方法

    layer.alert自定义关闭回调事件的方法

    今天小编就为大家分享一篇layer.alert自定义关闭回调事件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • javascript对HTML字符转义与反转义

    javascript对HTML字符转义与反转义

    这篇文章主要介绍了javascript对HTML字符转义与反转义,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • javascript每日必学之基础入门

    javascript每日必学之基础入门

    javascript每日必学之基础入门,从了解javascript开始,一步一步地进阶到大神境界,想要成为javascript大神的朋友不要错过,阅读一下
    2016-02-02

最新评论