国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Js使用ffmpeg在視頻中添加png或gif

這篇具有很好參考價值的文章主要介紹了Js使用ffmpeg在視頻中添加png或gif。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Js使用ffmpeg在視頻中添加png或gif

ffmpeg

使用場景是需要在web端對視頻進行編輯 添加圖片和gif。


注意:

以下所有的使用案例均基于vue3 setup。

同時由于@ffmpeg版本不同會導致使用的api不同,使用案例前需要注意@ffmpeg版本問題。

如果使用的是0.12+需要使用新的api,詳情請看 文檔


npm

npm install @ffmpeg/ffmpeg@^0.11.0

npm install @ffmpeg/core@^0.11.0

視頻添加png

<template></template>

<script setup>
import { ref, onUnmounted, onMounted } from 'vue'
import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';

const ffmpeg = createFFmpeg({ log: true });
const fileType = ref("") // 視頻文件類型

/**
 * 將圖片合成到視頻中
 * @param {string} url 視頻在線地址
 * @param {object} picItem 圖片素材對象
 * @param {string} picItem.startT 圖片素材出現(xiàn)的開始時間
 * @param {number} picItem.duration 素材的出現(xiàn)持續(xù)時間
 * @param {number} picItem.scale 素材的放大比例
 * @param {string} picItem.url 圖片素材url地址
 * @param {number} picItem.x 素材離視頻頂部的距離
 * @param {number} picItem.y 素材離視頻左側(cè)的距離
 * @return {Promise<{outputName: string, fileUrl: string}> | undefined}
 */
const videoCompose = async (url, picItem) => {
    if (!ffmpeg.isLoaded()) {
        await ffmpeg.load();
    }
    if (!url) return;

    const { duration, scale, startT, url: picUrl, x, y } = picItem;
    fileType.value = url.split(".").pop();
    const inputName = `input.${fileType.value}`;
    const outputName = `output.${fileType.value}`;
    const imageType = picUrl.split(".").pop();
    const imageFileName = `image.${imageType}`;

    await ffmpeg.FS('writeFile', inputName, await fetchFile(url));
    await ffmpeg.FS('writeFile', imageFileName, await fetchFile(picUrl));

    // 運行 FFmpeg 命令
    try {
        await ffmpeg.run(
            `-i`, `${inputName}`,
            `-i`, `${imageFileName}`,
            `-filter_complex`, `[1:v]scale=iw*${(scale).toFixed(1)}:ih*${(scale).toFixed(1)}[scaled];[0:v][scaled]overlay=${x}:${y}:enable='between(t,${+startT},${+startT + duration})'`,
            `${outputName}`,
            "-hide_banner"
        );

        // 讀取輸出文件
        let arrayBuffer = ffmpeg.FS('readFile', outputName).buffer; // 讀取緩存

        // 創(chuàng)建下載鏈接并通過回調(diào)下載保存到本地
        const fileUrl = URL.createObjectURL(new Blob([arrayBuffer])); // 轉(zhuǎn)為Blob URL

        // 釋放內(nèi)存
        ffmpeg.FS('unlink', inputName);
        ffmpeg.FS('unlink', outputName);

        return {
            fileUrl,
            outputName
        };
    } catch (e) {
        console.log(e);
    }
}

const downloadFile = (url, fileName = `clip.mp4`) => {
    const link = document.createElement('a');
    link.href = url;
    link.download = fileName;
    link.click();
}

onMounted(async () => {
    const {fileUrl} = await videoCompose("http://xxx.mp4", {
        duration: 3,
        scale: 1,
        startT: "0.00",
        url: 'http://xxx.png',
        x: 100,
        y: 100
    })
    downloadFile(fileUrl)
})

onUnmounted(() => {
    ffmpeg.exit();
})
</script>

視頻添加gif

流程與添加圖片類似,但添加濾鏡的命令不相同。

/*
 執(zhí)行FFmpeg命令的部分替換
 
 `-ignore_loop`, `0` 讓gif圖片循環(huán)播放 否則只播放一次
 `-itsoffset`, `${+startT}` gif圖片在視頻中出現(xiàn)時間
 fade=t=in:st=${+startT}:d=1:alpha=1[wm]; gif圖片在視頻中淡入的時間
 :shortest=1 視頻的時長為初始視頻時長 否則由于gif添加會導致視頻時間增長
 :enable='between(t,${+startT},${+startT + duration})' gif的出現(xiàn)時間
 "-hide_banner" 隱藏ffmpeg的部分信息
*/
await ffmpeg.run(
                `-i`, `${inputName}`,
                `-ignore_loop`, `0`,
                `-itsoffset`, `${+startT}`,
                `-i`, `${imageFileName}`,
                `-filter_complex`, `[0:0]scale=iw:ih[a];[1:0]scale=iw*${(scale).toFixed(1)}:ih*${(scale).toFixed(1)},fade=t=in:st=${+startT}:d=1:alpha=1[wm];[a][wm]overlay=x=${x}:y=${y}:shortest=1:enable='between(t,${+startT},${+startT + duration})'`,
                `${outputName}`,
                "-hide_banner"
            );

整合

可以在添加時對圖片的類型進行判斷,執(zhí)行不同的添加邏輯文章來源地址http://www.zghlxwxcb.cn/news/detail-759952.html

/**
 * 將圖片合成到視頻中
 * @param {string} url 視頻在線地址
 * @param {object} picItem 圖片素材對象
 * @param {string} picItem.startT 圖片素材出現(xiàn)的開始時間
 * @param {number} picItem.duration 素材的出現(xiàn)持續(xù)時間
 * @param {number} picItem.scale 素材的放大比例
 * @param {string} picItem.url 圖片素材url地址
 * @param {number} picItem.x 素材離視頻頂部的距離
 * @param {number} picItem.y 素材離視頻左側(cè)的距離
 * @return {Promise<{outputName: string, fileUrl: string}> | undefined}
 */
const videoCompose = async (url, picItem) => {
    if (!ffmpeg.isLoaded()) {
        await ffmpeg.load();
    }
    if (!url) return;

    const {duration, scale, startT, url: picUrl, x, y} = picItem;
    const type = url.split(".").pop();
    const inputName = `input.${type}`;
    const outputName = `output.${type}`;
    const imageType = picUrl.split(".").pop();
    const imageFileName = `image.${imageType}`;

    // 將輸入文件保存到虛擬文件系統(tǒng)
    if (url.startsWith('blob:')) {
        // 處理 Blob URL
        const arrayBuffer = await fetchBlobAsArrayBuffer(url);
        ffmpeg.FS('writeFile', inputName, new Uint8Array(arrayBuffer));
    } else if (url.startsWith('http://') || url.startsWith('https://')) {
        // 處理網(wǎng)絡(luò)地址
        await ffmpeg.FS('writeFile', inputName, await fetchFile(url));
    }
    await ffmpeg.FS('writeFile', imageFileName, await fetchFile(picUrl));

    // 運行 FFmpeg 命令
    try {
        if (imageType === 'gif') {
            await ffmpeg.run(
                `-i`, `${inputName}`,
                `-ignore_loop`, `0`,
                `-itsoffset`, `${+startT}`,
                `-i`, `${imageFileName}`,
                `-filter_complex`, `[0:0]scale=iw:ih[a];[1:0]scale=iw*${(scale).toFixed(1)}:ih*${(scale).toFixed(1)},fade=t=in:st=${+startT}:d=1:alpha=1[wm];[a][wm]overlay=x=${x}:y=${y}:shortest=1:enable='between(t,${+startT},${+startT + duration})'`,
                `${outputName}`,
                "-hide_banner"
            );
        } else {
            await ffmpeg.run(
                `-i`, `${inputName}`,
                `-i`, `${imageFileName}`,
                `-filter_complex`, `[1:v]scale=iw*${(scale).toFixed(1)}:ih*${(scale).toFixed(1)}[scaled];[0:v][scaled]overlay=${x}:${y}:enable='between(t,${+startT},${+startT + duration})'`,
                `${outputName}`,
                "-hide_banner"
            );
        }

        // 讀取輸出文件
        let arrayBuffer = ffmpeg.FS('readFile', outputName).buffer; // 讀取緩存

        // 創(chuàng)建下載鏈接并通過回調(diào)下載保存到本地
        const fileUrl = URL.createObjectURL(new Blob([arrayBuffer])); // 轉(zhuǎn)為Blob URL

        // 釋放內(nèi)存
        ffmpeg.FS('unlink', inputName);
        ffmpeg.FS('unlink', outputName);

        return {
            fileUrl,
            outputName
        };
    } catch (e) {
        console.log(e);
    }
}

到了這里,關(guān)于Js使用ffmpeg在視頻中添加png或gif的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • C# 使用Bitmap 將byte[] 轉(zhuǎn)成.jpg/.png/gif等圖片

    在 C# 中,你可以使用 System.Drawing 命名空間中的 Bitmap 類來將 byte[] 轉(zhuǎn)換為 .jpg 圖片。以下是一個示例代碼: 在上面的示例中,GetImageBytes 方法是一個用于獲取圖片的 byte[] 數(shù)據(jù)的示例方法。你需要根據(jù)實際情況自行實現(xiàn)該方法,從文件、網(wǎng)絡(luò)等地方讀取圖片數(shù)據(jù),并返回 byt

    2024年01月19日
    瀏覽(22)
  • 【FFmpeg】視頻與圖片互相轉(zhuǎn)換 ( 視頻與 JPG 靜態(tài)圖片互相轉(zhuǎn)換 | 視頻與 GIF 動態(tài)圖片互相轉(zhuǎn)換 )

    【FFmpeg】視頻與圖片互相轉(zhuǎn)換 ( 視頻與 JPG 靜態(tài)圖片互相轉(zhuǎn)換 | 視頻與 GIF 動態(tài)圖片互相轉(zhuǎn)換 )

    執(zhí)行 命令 , 將 輸入文件 input.mp4 中的 第 2 秒 開始的 1 幀數(shù)據(jù) 轉(zhuǎn)為一張 848x480 像素的圖片 , 輸出到 output.jpg 文件中 ; 上述命令解析 : -i input.mp4 : 指定輸入文件為 input.mp4 , -i 參數(shù)用于設(shè)置輸入文件 ; -y : 設(shè)置 如果輸出文件已存在 , 直接覆蓋 , 如果不設(shè)置該選項 , 會中斷執(zhí)行

    2024年04月23日
    瀏覽(31)
  • 使用ffmpeg實現(xiàn)給音頻,視頻添加水印的操作

    使用ffmpeg實現(xiàn)給音頻,視頻添加水印的操作

    本文主要針對ffmpeg進行整理,從而解決在現(xiàn)實中可能存在的問題。 這里參考的是 Java后臺用ffmpeg命令給視頻添加水印 - ^身后有尾巴^ - 博客園 (cnblogs.com) 1:先去ffmpeg官網(wǎng)下載其壓縮包??Download FFmpeg 下載,解壓到指定位置? 2.將壓縮包拷貝到你想的任意位置并解壓,正常解壓出

    2023年04月08日
    瀏覽(21)
  • 音視頻剪輯|FFMPEG|windows10下的音視頻格式轉(zhuǎn)換,遮擋填充,GIF動圖制作,背景音頻抽取,替換

    音視頻剪輯|FFMPEG|windows10下的音視頻格式轉(zhuǎn)換,遮擋填充,GIF動圖制作,背景音頻抽取,替換

    最近對于音視頻和圖像的處理問題比較感興趣,但發(fā)現(xiàn)很多目前需要的功能要么需要付費但不會過于麻煩,要么比較麻煩,很可能某個功能實現(xiàn)需要安裝很多軟件 例如,視頻轉(zhuǎn)GIF動圖,該功能的實現(xiàn)要么使用Photoshop全家桶,要么找在線網(wǎng)站,或者是wps充會員,或者找其它方法

    2024年02月20日
    瀏覽(26)
  • gocv讀取gif多幀圖像,mp4視頻圖像,opencv,VideoCaptureFile,opencv_ffmpeg

    讀取GIF圖像 opencv中無法讀取gif圖像,這是由于license原因。轉(zhuǎn)而使用 videocapture 或者第三方的 PIL 庫(Python),但是其實Golang的基礎(chǔ)庫 image 中就有讀取gif圖像的。于是一個簡單的示例如下 這里只會播放一遍gif圖像,我們還可以解析gif中的LoopCount來增加循環(huán)播放的邏輯。 讀取

    2024年02月12日
    瀏覽(50)
  • Js使用ffmpeg進行視頻剪輯和畫面截取

    使用場景是需要在web端進行視頻的裁剪,包括使用 在線視頻url 或 本地視頻文件 的裁剪,以及對視頻內(nèi)容的截取等功能。 前端進行視頻操作可能會導致性能下降,最好通過后端使用java,c++進行處理,本文的案例是備選方案。 注意: 以下所有的使用案例均基于vue3 setup。 同時

    2024年02月07日
    瀏覽(24)
  • Vue 3 + ffmpeg + wasm 實現(xiàn)前端視頻剪輯、音頻剪輯、音波展示、視頻抽幀、gif抽幀、幀播放器、字幕、貼圖、時間軸、素材軌道

    預覽 www.bilibili.com/video/BV1YT411Y7YJ 技術(shù)棧: ?? Vue 3、Vue-Router 4、Vite、pnpm、esbuild、TypeScript ?? Pinia 狀態(tài)管理 ?? Tailwind 原子css集成 ?? ffmpeg、wasm 底層音視頻處理集成 功能 多軌道時間軸,支持幀縮放,時間縮放 支持多種類型軌道的添加刪除 多功能軌道調(diào)節(jié),支持音視頻軌

    2024年02月11日
    瀏覽(31)
  • 【JS】純web端使用ffmpeg實現(xiàn)的視頻編輯器

    【JS】純web端使用ffmpeg實現(xiàn)的視頻編輯器

    廢話不多,先上視頻。 ffmpeg編輯器 這是一個純前端實現(xiàn)的視頻編輯器,用的ffmpeg的wasm,web框架用的vue3。界面手擼。 用vite的vue3模板創(chuàng)建一個就可以。 package.json 創(chuàng)建頁面和路由,用的vue-router,簡單的添加一下。 router.js 主要項目結(jié)構(gòu) 組件代碼 progress-dialog.vue resource-item.vue t

    2024年02月12日
    瀏覽(22)
  • windows使用ffmpeg將MP4轉(zhuǎn)m3u8使用參數(shù)詳解,視頻添加水印和壓縮

    windows使用ffmpeg將MP4轉(zhuǎn)m3u8使用參數(shù)詳解,視頻添加水印和壓縮

    目錄 背景: 一、什么是m3u8: 二、為什么使用m3u8: 三、安裝ffmpeg: 1、下載后直接解壓: 2、配置環(huán)境變量: 四、開始轉(zhuǎn)換m3u8: 五、視頻添加水印和壓縮: 1. 給視頻加上水印圖片 2.輸出視頻的尺寸 3.輸出文件的起始文件 4.輸出文件的最小大小 和 最大的大小(會影響視頻質(zhì)量

    2024年02月07日
    瀏覽(25)
  • 利用Python將照片按“拍攝日期”分類——包括JPG、PNG、GIF、HEIC

    ????????一切的起因是因為換了新手機 (-,-),舊手機上的照片實在是太多了所以想騰出大部分到PC上面來釋放一些存儲空間。但是首先出現(xiàn)的問題就是照片有6000多個文件而且全都集中在一起,沒有進行任何的分類。 ? ? ? ? 所以我初步的想法,是按照日期時間進行分

    2024年02月22日
    瀏覽(21)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包