ffmpeg视频转GIF简单使用

352 阅读2分钟

当需要将视频转换为GIF图像时,使用FFmpeg,一个强大且灵活的工具。FFmpeg可以通过命令行或者集成到程序中来实现视频到GIF的转换。

一:安装依赖

npm i @ffmpeg/ffmpeg @ffmpeg/util

二:引入

ffmpeg 的官网获取 ffmpeg-core.jsffmpeg-core.wasm,并将其放置在项目中,通常可以将其放在 publicstatic 文件夹中。

三:代码实现

  • loadFFmpeg():初始化 ffmpeg 并加载库。
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { fetchFile, toBlobURL } from "@ffmpeg/util";
async loadFFmpeg() {
    let ffmpeg = new FFmpeg();
    const baseURL = "/static/js";
    await ffmpeg.load({
        coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`,"text/javascript"),
        wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`,"application/wasm"),
    });
    this.ffmpeg = ffmpeg;
}
  • uploadVideo():上传需要转化的视频。
uni.chooseVideo({
    count: 1,
    sourceType: ["camera", "album"],
    success: (res) => {
        this.videoSrc = res.tempFilePath
    },
});
  • convertToGIF():使用 ffmpeg 将视频文件转换为GIF格式。
    主要用到这个命令:

ffmpeg -i input.mp4 -c:v gif output.gif

-i input.mp4:指定输入的视频文件。
-c:v gif:设置输出文件的视频编解码器为GIF。
output.gif:指定输出的GIF文件名。

async convertToGIF() {
    const ffmpeg = this.ffmpeg;
    await ffmpeg.writeFile(`input.mp4`, await fetchFile(this.videoSrc));
    await ffmpeg.exec(["-i", `input.mp4`, "-c:v", "gif", "output.gif"]);
    const data = await ffmpeg.readFile("output.gif");
    const url = URL.createObjectURL(new Blob([data.buffer], { type: "image/gif" }));
}
  • download():下载GIF。

完整代码

<template>
    <view>
        <video :src="videoSrc" controls></video>
        <view class="upload-btn" @tap="uploadVideo">上传视频</view>
        <image :src="gifUrl" mode="aspectFill" class="image"></image>
    </view>
</template>
<script>
import { FFmpeg } from "@ffmpeg/ffmpeg";
import { fetchFile, toBlobURL } from "@ffmpeg/util";
export default {
    data() {
        return {
            ffmpeg: null,
            videoSrc: "",
            gifUrl: "",
        };
    },
    mounted() {
        this.loadFFmpeg();
    },
    methods: {
        async loadFFmpeg() {
            let ffmpeg = new FFmpeg();
            const baseURL = "/static/js";
            await ffmpeg.load({
                coreURL: await toBlobURL(`${baseURL}/ffmpeg-core.js`,"text/javascript"),
                wasmURL: await toBlobURL(`${baseURL}/ffmpeg-core.wasm`,"application/wasm"),
            });
            this.ffmpeg = ffmpeg;
        },
        uploadVideo() {
            uni.chooseVideo({
                count: 1,
                sourceType: ["camera", "album"],
                success: (res) => {
                    this.videoSrc = res.tempFilePath;
                    this.convertToGIF();
                },
            });
        },
        async convertToGIF() {
            if (!this.ffmpeg || !this.videoSrc) return;
            const ffmpeg = this.ffmpeg;
            await ffmpeg.writeFile(`input.mp4`, await fetchFile(this.videoSrc));
            await ffmpeg.exec(["-i", `input.mp4`, "-c:v", "gif", "output.gif"]);
            const data = await ffmpeg.readFile("output.gif");
            const url = URL.createObjectURL(new Blob([data.buffer], { type: "image/gif" }));
            this.gifUrl = url;
            this.download(url);
        },
        download(url) {
            const link = document.createElement("a");
            link.href = url;
            link.download = "output.gif";
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(url);
        },
    },
};
</script>

<style scoped lang="scss">
.upload-btn {
    line-height: 80rpx;
    text-align: center;
    color: #fff;
    background-color: green;
    margin: 20rpx;
}
</style>

ffmpeg 还支持很多的配置,例如分辨率和图像大小的配置,设置视频帧率,尺寸缩放(scale=320:-1表示宽度320高度自适应),使用lanczos算法优化

ffmpeg -i input.mp4 -vf "fps=10,scale=320:-1:flags=lanczos" -c:v gif output.gif

await ffmpeg.exec([ "-i",`input.mp4`,"-vf",`fps=10,scale=320:-1:flags=lanczos`,"-c:v","gif","output.gif"]);

使用FFmpeg将视频转换为GIF图像还是很方便的。

ffmpeg
ffmpegwasm
ffmpeg-core.js
ffmpeg-core.wasm