WebAssembly+ffmpeg瀏覽器視頻處理


  • ffmpeg 編譯成 wasm 供瀏覽器使用
  • 瀏覽器上傳視頻后無縫對接 ffmpeg 能力

02.png

Emscripten

Emscripten 是一個 LLVM 到 JS 的編譯器,編譯出 JS 文件供瀏覽器使用,也可以生成 WASM 提供更好的性能體驗。

環境准備

cmake、git、python2.7

Mac 環境下,只需要通過 Homebrew 安裝 cmake 即可

安裝 Homebrew:https://brew.sh

  • brew install cmake

如果因為網絡問題無法使用 Homebrew,參考 8000 的這篇 Proxifier 教程:http://8000.oa.com/#/article?id=KB201905220003&from=km_search

安裝 emsdk

  • git clone https://github.com/juj/emsdk && cd emsdk
  • ./emsdk install sdk-incoming-64bit binaryen-master-64bit
  • ./emsdk activate sdk-incoming-64bit binaryen-master-64bit
  • # 配置環境變量,每次需要編譯的時候配置一次
  • source ./emsdk_env.sh
  • # source /Users/ringcrl/Documents/github/emsdk/emsdk_env.sh
  • # 校驗編譯成功
  • emcc --help
sh

編譯 FFmpeg 到 LLVM

  • # 克隆項目
  • git clone https://github.com/FFmpeg/FFmpeg
  • cd FFmpeg
  • # 編譯配置
  • CPPFLAGS="-D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600" \
  • emconfigure ./configure --cc="emcc" \
  • --prefix=$(pwd)/../dist --enable-cross-compile --target-os=none --arch=x86_64 \
  • --cpu=generic --disable-ffplay --disable-ffprobe \
  • --disable-asm --disable-doc --disable-devices --disable-pthreads \
  • --disable-w32threads --disable-network --disable-hwaccels \
  • --disable-parsers --disable-bsfs --disable-debug --disable-protocols \
  • --disable-indevs --disable-outdevs --enable-protocol=file
  • # 編譯
  • make
sh

以上編譯參數參考:https://github.com/bgrins/videoconverter.js/blob/master/build/build_lgpl.sh#L20

由於需要校驗上傳的視頻的音頻流長度和視頻流長度,我的編譯參數把 --disable-ffprobe 去掉了,因為我后面還需要用到 ffprobe 命令。

編譯 LLVM 到 WebAssembly

  • # 這里的 ffmpeg 是上一步編譯輸出的 LLVM bitcode,注意一定要是 .bc 后綴
  • cp ffmpeg ffmpeg.bc
  • # 然后把 ffmpeg.bc 移到一個單獨的文件夾作處理
  • # 我是在 fock 出來的 FFmpeg 項目下新建了 wasmbuild 做實驗
  • # ASSERTIONS 用於啟用運行時檢查常見內存分配錯誤
  • # VERBOSE 顯示詳細的信息
  • # TOTAL_MEMORY 控制內存容量,默認的內存容量為 16MB,棧容量為 5MB
  • # ALLOW_MEMORY_GROWTH Emscripten 堆一經初始化,容量就固定了,該選項支持自動拓展
  • # WASM 編譯到 wasm,默認是 asm.js
  • # -02 優化等級
  • # -v 制定 xx.bc 文件
  • # -o 制定前置鈎子、后置鈎子,也就是 JS IO 通信使用,傳遞文件、傳入參數,回調拿到產出結果
  • emcc -s ASSERTIONS=1 \
  • -s VERBOSE=1 \
  • -s TOTAL_MEMORY=33554432 \
  • -s ALLOW_MEMORY_GROWTH=1 \
  • -s WASM=1 \
  • -O2 \
  • -v ffmpeg.bc \
  • -o ./ffmpeg.js --pre-js ./ffmpeg_pre.js --post-js ./ffmpeg_post.js
sh

ffmpeg 前后置鈎子

上一步最后出現了兩個文件 ffmpeg_pre.js 鈎子和 ffmpeg_post.js鈎子,這里參考了:https://github.com/bgrins/videoconverter.js/blob/master/build/ffmpeg_pre.js 進行編寫。

  • 命令行運行之前在創建 /input/output 文件夾,並將瀏覽器上傳得到的文件放入 /input
  • 執行 ffmpeg 相關命令,在命令中控制輸出邏輯,將輸出文件放入到 /output
  • 在運行完成后讀取 /output 目錄,將文件轉成 ArrayBuffer 回調給瀏覽器

01.png

前端調用

02.png

源碼、體驗地址

參考鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM