前端本地使用ffmpeg

安裝

npm install @ffmpeg/ffmpeg @ffmpeg/core -S

ffmpeg.load
ffmpeg.load() 返回一個 Promise,用來加載 ffmpeg-core.js 核心包,在瀏覽器環(huán)境中,ffmpeg.wasm-core 腳本默認(rèn)是從 CDN 中獲取的,可以在創(chuàng)建 ffmpeg 實例時通過 corePath 來指定到本地路徑。

ffmpeg.run
ffmpeg.run(...args) 返回一個 Promise,和原生的 ffmpeg 一樣

ffmpeg.FS
ffmpeg.FS(method, ...args) 用來運行 FS 操作。

對于 ffmpeg.wasm 的輸入/輸出文件,需要先將它們保存到 MEMFS 以便 ffmpeg.wasm 能夠使用它們。這里我們依賴 Emscripten 提供的 FS 方法♂?。

ffmpeg.exit
ffmpeg.exit() 用來殺死程序的執(zhí)行,同時刪除 MEMFS 以釋放內(nèi)存。

ffmpeg.setLogging
ffmpeg.setLogging(logging) 控制是否將日志信息輸出到控制臺。

ffmpeg.setLogger
ffmpeg.setLogger(logger) 設(shè)置和獲取 ffmpeg.wasm 的輸出消息。。

ffmpeg.setProgress
ffmpeg.setProgress(progress) 進度處理程序,用于獲取 ffmpeg 命令的當(dāng)前進度。

fetchFile
fetchFile(media) 返回一個 Promise, 用于從各種資源中獲取文件。要處理的視頻/音頻文件可能位于遠(yuǎn)程 URL 或本地文件系統(tǒng)中的某個位置。這個函數(shù)幫助你獲取文件并返回一個 Uint8Array 變量供 ffmpeg.wasm 使用。

注意:網(wǎng)頁需要在請求頭加上

# webpack
devServer: {
    headers: {
      "Cross-Origin-Opener-Policy": "same-origin",
      "Cross-Origin-Embedder-Policy": "require-corp",
    },
}

# nginx
add_header Cross-Origin-Opener-Policy same-origin; 
add_header Cross-Origin-Embedder-Policy require-corp;

示例代碼

import { createFFmpeg , fetchFile } from '@ffmpeg/ffmpeg'

const ffmpeg = createFFmpeg({
  // corePath: "https://unpkg.com/@ffmpeg/core@0.10.0/dist/ffmpeg-core.js", // 指定 ffmpeg-core.js 的加載路徑
  // log: true, // 是否打開所有日志,默認(rèn)為 false
  // logger: ({ message }) => console.log(message), // 獲取日志消息的函數(shù)
  // progress: p => console.log(p), // 跟蹤進度的函數(shù)
})

async function init () {
  ffmpeg.setProgress(({ ratio }) => {
    console.log(`${ratio * 100}% 進度===>`);
  });
  ffmpeg.setLogger(({ type, message }) => {
    console.log('???? ~ message', message);
    console.log('???? ~ type', type);
  });
  await ffmpeg.load()
}
init()

async function start (file) {
  // 獲取資源文件
  const result = await fetchFile(file)
  console.log('???? ~ result', result);

  // 對于 ffmpeg.wasm 的輸入/輸出文件,需要先將它們保存到 MEMFS 以便 ffmpeg.wasm 能夠使用它們
  await ffmpeg.FS('writeFile', `${file.name}`, result);

  await ffmpeg.run('-i', `${file.name}`, '-acodec', 'aac', '-vcodec', 'libx264', '-y', `${file.name.split('.')[0]}_transcod.mp4`)
  // 在內(nèi)存中讀取文件
  const data = await ffmpeg.FS('readFile', `${file.name.split('.')[0]}.mp4`);
  // 獲取內(nèi)存中的播放地址
  const videoFileUrl = URL.createObjectURL(new Blob([data.buffer], { type: 'video/mp4' }))
  console.log('???? ~  videoFileUrl', videoFileUrl);
  return videoFileUrl
  
}

const fileDom = document.querySelector('.file')
const videoDom = document.querySelector('.video')
fileDom.onchange = async function (e) {
  const file = e.target.files[0]
  console.log(file, '選擇完');
  try {
    const url = await start(file)
    videoDom.src = url
  } catch (err) {
    alert('出錯了')
    throw err
  }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容