vite+vue3中使用FFmpeg@0.12.15實現視頻編輯功能,不依賴SharedArrayBuffer!!!

FFmpeg@0.12.15完全不依賴SharedArrayBuffer!!!強烈推薦使用

本文章主要是在vite+vue3項目中使用FFmpeg,只展示了如何在項目中引入和基礎的使用

更多詳細參數可參照?ffmpeg官網https://ffmpeg.org/

一、安裝FFmpeg

可通過npm直接安裝

npm install @ffmpeg/core@0.12.10 @ffmpeg/ffmpeg@0.12.15 @ffmpeg/util@0.12.2

二、在代碼中使用

1、初始化FFmpeg

首先找到node_modules/@ffmpeg/core/dist/esm下的這兩個文件,并放到public文件夾下,例如

import { FFmpeg } from '@ffmpeg/ffmpeg'
import { fetchFile, toBlobURL } from '@ffmpeg/util'
import { ref, onMounted } from 'vue'
let ffmpeg = null
const initFFmpegFn = async () => {if (ffmpeg) return// 初始化ffmpeg ffmpeg = new FFmpeg();// 如果需要當前編輯視頻進度let progress = ref(0);ffmpeg.on('log', ({ type, message }) => {if (type === 'stderr') {// 匹配日志中的時間信息(例如:time=00:00:05.12)const timeMatch = message.match(/time=(\d+:\d+:\d+\.\d+)/);if (timeMatch && totalDuration.value) {const currentTime = parseTimeToSeconds(timeMatch[1]);const newProgress = Math.min(Math.round((currentTime / totalDuration.value) * 100), 100);progress.value = newProgress;}}});// 加載FFmpeg核心try {// ffmpeg.loaded 核心是否加載if (!ffmpeg.loaded) {let ffmpegBaseUrl = '/FFmpeg/dist'await ffmpeg.load({coreURL: await toBlobURL(`${ffmpegBaseUrl}/ffmpeg-core.js`, 'text/javascript'),wasmURL: await toBlobURL(`${ffmpegBaseUrl}/ffmpeg-core.wasm`, 'application/wasm'),});console.log('加載完成', ffmpeg);}} catch (err) {console.error('FFmpeg核心加載失敗:', err);}}
// 工具函數:將時間字符串(如00:00:05.12)轉換為秒
const parseTimeToSeconds = (timeStr) => {const [hours, minutes, seconds] = timeStr.split(':').map(Number);return hours * 3600 + minutes * 60 + seconds;
};
onMounted(() => {initFFmpegFn()
})

2、加載出錯處理(如果通過上一步能正常加載完成,可忽略)

由于ffmpeg中會使用vite中的worker,可能會導致控制臺中有一個鏈接為http://localhost:9090/node_modules/.vite/deps/worker.js?worker_file&type=module一直處于pending狀態,無法加載成功

需要在vite.config.js中使用optimizeDeps.exclude?是指定不需要進行依賴預構建。

3、編輯視頻:是否靜音-調整視頻寬高-裁剪視頻時長

const processVideoFn = async (fileBlob, processOptions = {}) => {// fileBlob 視頻文件blob對象if (!fileBlob || !(fileBlob instanceof Blob)) {console.error('錯誤:請傳入有效的視頻Blob對象');return { success: false, error: '無效的視頻Blob', url: null, blob: null };}if (fileBlob.size === 0) {console.error('錯誤:傳入的Blob為空(大小0字節)');return { success: false, error: '輸入Blob為空', url: null, blob: null };}const {needClearVoice = false,//裁剪后是否靜音resizeInfo = {width:800,height:800},//裁剪后視頻寬高cropInfo = { startTime:0, duration:60 }// startTime:裁剪視頻開始時間   duration:總裁剪時長} = processOptions;const { startTime = 0, duration = 60 } = cropInfo;progress.value = 0;//進度條歸0totalDuration.value = duration;//總裁剪時長,用于計算進度條const timestamp = Date.now();const inputFileName = `input_video.mp4`;const outputFileName = `output_video_${timestamp}.mp4`;let outputData = null; // 存儲輸出數據,避免提前清理try {if (!ffmpeg || !loadSuccess.value) {throw new Error('FFmpeg核心未加載完成');}const fileData = await fetchFile(fileBlob); // fetchFile返回Uint8Arrayawait ffmpeg.writeFile(inputFileName, fileData); // 直接傳文件名+數據const ffmpegCommand = ['-i', inputFileName];// 裁剪處理(校驗參數)if (cropInfo) {if (startTime < 0 || duration <= 0) {throw new Error(`裁剪參數無效:startTime=${startTime}(需≥0),duration=${duration}(需>0)`);}ffmpegCommand.push('-ss', startTime.toFixed(2), '-t', duration.toFixed(2));}// 尺寸調整(校驗參數)if (resizeInfo) {let { width, height } = resizeInfo;if (width <= 0 || height <= 0) {throw new Error(`尺寸參數無效:width=${width}(需>0),height=${height}(需>0)`);}const scaleFilter = `scale=w=${width}:h=${height}:force_original_aspect_ratio=decrease`;const padFilter = `pad=w=${width}:h=${height}:x=(ow-iw)/2:y=(oh-ih)/2:color=white`;//視頻寬高不夠時填充白色邊框ffmpegCommand.push('-vf', `${scaleFilter},${padFilter}`);}// 音頻處理if (needClearVoice) {ffmpegCommand.push('-an'); // 移除音頻} else {ffmpegCommand.push('-c:a', 'aac', '-strict', 'experimental'); // 保留音頻}ffmpegCommand.push('-c:v', 'libx264',       // H.264編碼(通用)'-pix_fmt', 'yuv420p',   // 兼容所有播放器(避免僅支持yuv444p的問題)'-crf', '30',            // 控制質量(值越小質量越高,28為平衡值)'-preset', 'ultrafast',  // ultrafast/superfast/veryfast/faster/fast/medium(默認值)/slow/slower/veryslow 從前到后處理速度越來越慢,處理視頻越精致'-b:v', '1M',            // 視頻比特率(避免輸出過小/過大)'-y',                    // 覆蓋已有文件outputFileName);await ffmpeg.exec(ffmpegCommand);outputData = await ffmpeg.readFile(outputFileName);if (!outputData || outputData.length === 0) {throw new Error('FFmpeg讀取輸出文件為空');}const resultBlob = new Blob([outputData], { type: 'video/mp4' });if (resultBlob.size === 0) {throw new Error('生成的Blob為空');}const previewUrl = URL.createObjectURL(resultBlob);return {url: previewUrl,//生成的臨時視頻urlblob: resultBlob,//生成的新視頻blob對象};} catch (err) {console.error('視頻處理失敗:',err);} finally {if (ffmpeg && outputData) {if (await ffmpeg.listDir(inputFileName).catch(() => false)) {await ffmpeg.unlink(inputFileName).catch(err => console.warn('清理輸入文件失敗:', err));}if (await ffmpeg.listDir(outputFileName).catch(() => false) && outputData) { // 確保讀取后再刪除輸出await ffmpeg.unlink(outputFileName).catch(err => console.warn('清理輸出文件失敗:', err));}}}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/923573.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/923573.shtml
英文地址,請注明出處:http://en.pswp.cn/news/923573.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

構網型5MW中壓儲能變流升壓一體機技術方案

1 構網型儲能背景概述1.1 新型電力系統亟需構網支撐眾所周知&#xff0c;新型電力系統具有兩高特征&#xff1a;高比例新能源大規模并網、高比例電力電子大范圍接入。近年來風光裝機占比越來越高&#xff0c;而傳統火電裝機占比越來越低&#xff0c;并在2023年首次降至50%以下…

SRE 系列(七)| 從技術架構到團隊組織

目錄SRE落地與組織架構實踐技術架構與組織架構的匹配技術架構示例運維職責分工技術保障體系SRE 多角色團隊總結SRE落地與組織架構實踐 在落地 SRE 時&#xff0c;很多團隊最關心的問題之一就是組織架構&#xff1a;我們究竟需要怎樣的團隊形態&#xff0c;才能支撐微服務和分…

香港期權市場的主要參與者有哪些?

本文主要介紹香港期權市場的主要參與者有哪些&#xff1f;香港期權市場作為全球重要的金融衍生品市場&#xff0c;其參與者結構呈現多元化、專業化的特征&#xff0c;主要涵蓋以下核心群體。香港期權市場的主要參與者有哪些&#xff1f;1. 機構投資者&#xff08;主導力量&…

搜維爾科技:全身可穿戴Teslasuit動捕服的功能,自立式FES裝置

功能性電刺激 (FES) 設備廣泛應用于康復和醫療實踐。其底層技術利用低能量電脈沖&#xff0c;在中風、脊髓損傷、多發性硬化癥、腦癱等各種疾病患者中人工產生身體運動。一般來說&#xff0c;FES系統可以分為三類&#xff1a;開環、有限狀態控制和閉環方法。這三種方法描述了 F…

【深度學習新浪潮】MoE是什么技術?

混合專家模型(Mixture of Experts,MoE)是大模型時代提升計算效率與模型能力的核心技術之一。其核心思想是將復雜任務分解為多個子任務,通過動態路由機制激活特定專家網絡處理輸入數據,從而在保持模型容量的同時大幅降低計算成本。以下是技術細節與實際應用的深度解析: 一…

Java進階教程,全面剖析Java多線程編程,實現Callable接口實現多線程,筆記05

Java進階教程&#xff0c;全面剖析Java多線程編程&#xff0c;實現Callable接口實現多線程&#xff0c;筆記05 參考資料 多線程&JUC-05-多線程的第三種實現方式一、實現Callable接口實現多線程 二、三種方式對比 優點缺點繼承Thread類編程比較簡單&#xff0c;可以直接使…

軌道交通絕緣監測—軌道交通安全的隱形防線

軌道交通絕緣監測作為保障行車安全的核心環節&#xff0c;正面臨多重技術與環境挑戰。復雜運營環境是首要痛點&#xff0c;隧道內高濕度&#xff08;月均濕度達95%&#xff09;會增大鋼軌表面電導率&#xff0c;霧氣中的鹽分更會加速扣件絕緣性能下降&#xff0c;導致過渡電阻驟…

tar-符號連接(軟連接)

1.符號連接是什么符號鏈接&#xff08;symbolic link&#xff0c;也叫軟鏈接&#xff09;本質上是一個 指向路徑的特殊文件。例如&#xff1a;ln -s /etc/passwd passwd_link這會創建一個叫 passwd_link 的文件&#xff0c;但它本身不存放 /etc/passwd 的內容&#xff0c;而是存…

ffmpeg切割音頻

ffmpeg切割音頻 我希望對指定音頻切割&#xff0c;按照開始時間&#xff0c;結束時間&#xff0c;切割成新文件&#xff0c;自動保存&#xff0c;非常好用 step1: from pydub import AudioSegment import os# 配置FFmpeg路徑&#xff08;確保路徑正確&#xff09; ffmpeg_path …

Python 批量處理:Markdown 與 HTML 格式相互轉換

文章目錄引言與同類工具的優勢對比Python 將 Markdown 轉換為 HTMLPython 將 HTML 轉換為 Markdown批量轉換與自動化處理引言 在多平臺內容分發與管理的場景中&#xff0c;文檔格式轉換已成為內容生態系統中的關鍵環節。Markdown 作為輕量級標記語言&#xff0c;以其語法簡潔、…

御控物聯網遠程控制水泵啟停智能自控解決方案

在農業灌溉、城市排水、工業供水等場景中&#xff0c;水泵作為核心設備&#xff0c;長期面臨以下難題&#xff1a;人工依賴度高&#xff1a;需24小時值守&#xff0c;暴雨或干旱時響應滯后&#xff1b; 能耗浪費嚴重&#xff1a;空轉、過載運行導致電費居高不下&#xff1b; …

RedisI/O多路復用:單線程網絡模型epoll工作流程

epoll1. 在內核創建eventpoll結構體&#xff0c;返回句柄epfd&#xff08;唯一標識&#xff09;eventpoll包含存放被監聽的fd的紅黑樹&#xff0c;和存放已就緒的fd的鏈表2. 將要監聽的fd加入到epoll紅黑樹中&#xff0c;并設置callback回調函數callback觸發時&#xff0c;就將…

SmartBear API Hub助力MCP開發,無縫、安全的連接AI與外部工具

人工智能&#xff08;AI&#xff09;技術的應用場景日益廣泛&#xff0c;如何讓不同的AI系統之間實現高效、無縫的交互&#xff0c;成為了業界的重要課題。隨著人工智能技術的不斷進步&#xff0c;模型上下文協議&#xff08;MCP&#xff09;應運而生。MCP為不同AI系統之間提供…

如何選擇高性價比的iOS簽名服務?關鍵因素與價格區間

作為一名摸爬滾打多年的開發者&#xff0c;我來和你聊聊怎么挑一個靠譜又不坑的iOS簽名服務。這玩意兒選不好&#xff0c;輕則測試團隊干瞪眼&#xff0c;重則App下架&#xff0c;用戶投訴&#xff0c;簡直是我們開發者的噩夢。別光看價格&#xff01;先想清楚你的核心需求在選…

MoonBit 正式加入 WebAssembly Component Model 官方文檔 !

我們非常高興地宣布&#xff0c;MoonBit 已正式收錄在 WebAssembly Component Model 的官方文檔中。這不僅是對 MoonBit 技術路線的一次肯定&#xff0c;也讓我們有機會和 Rust、Go、C# 等語言一起&#xff0c;出現在開發者查閱組件模型的入口頁面中。一、 關于 WebAssembly Co…

Python快速入門專業版(三十二):匿名函數:lambda表達式的簡潔用法(結合filter/map)

目錄引一、lambda表達式的基本語法&#xff1a;一行代碼定義函數示例1&#xff1a;lambda表達式與普通函數的對比二、lambda表達式的應用場景&#xff1a;臨時與靈活1. 臨時使用&#xff1a;無需定義函數名的簡單功能2. 作為參數傳遞給高階函數三、結合filter()&#xff1a;篩選…

【LeetCode 每日一題】3025. 人員站位的方案數 I——(解法一)暴力枚舉

Problem: 3025. 人員站位的方案數 I 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(N^3)空間復雜度&#xff1a;O(1)整體思路 這段代碼旨在解決一個幾何計數問題&#xff1a;給定平面上的 n 個點&#xff0c;計算滿足特定條件的“點對” (i, j) 的數量。 根據代…

Roo Code 診斷集成功能:智能識別與修復代碼問題

這里是引用在日常編程中&#xff0c;遇到代碼錯誤或警告是再常見不過的事。但如何高效定位并解決這些問題&#xff0c;往往考驗開發者的經驗和工具鏈的支持。 Roo Code 中有一項非常實用的功能——診斷集成&#xff08;Diagnostics Integration&#xff09;。它能夠與 VSCode 的…

Redis 與微服務架構結合:高并發場景下的架構藝術

&#x1f50c; Redis 與微服務架構結合&#xff1a;高并發場景下的架構藝術 文章目錄&#x1f50c; Redis 與微服務架構結合&#xff1a;高并發場景下的架構藝術&#x1f9e9; 一、微服務架構下的挑戰?? 典型痛點分析&#x1f4ca; 性能瓶頸對比?? 二、Redis作為配置中心&a…

鴻蒙應用冷啟動優化:本地 KV 緩存預熱實戰指南

在鴻蒙&#xff08;HarmonyOS&#xff09;應用開發中&#xff0c;冷啟動速度直接影響用戶的初始體驗。許多應用在啟動后需要加載大量常用配置&#xff08;如用戶偏好設置、主題配置&#xff09;或基礎數據&#xff08;如上次登錄信息、常用功能參數&#xff09;&#xff0c;若每…