2021年6月27日 星期日

Node.js 筆記 - 以 HTTP API 提供 ffmpeg 轉檔,以 jpg 轉成 png 為例 @ node.js v10.24.1, macOS 11.4

最近接獲一個任務研究了一下 Javascript 與 H264 的解決方案,首先會立馬想到 ffmpeg 方案,就研究了以下 JS 專案:
其中 ffmpeg.wasm 無法在 node.js v10 運行。在不考慮 node.js 升級的前提上,就來把玩其他三者,而 tinyh264 的源頭是 h264bsd 專案,在 h264bsd 專案中有 js solution 可以挖出來跑,包括裡頭有 github.com/oneam/h264bsd/blob/master/js/test_node.js 這隻程式很小巧美麗,可以欣賞一下。而裡頭把玩最多的是 ffmpeg.js 這專案,有興趣可以看看他的 Makefile ,很簡單清楚,比較特別是他分別產出 ffmpeg-webm.js 和 ffmpeg-mp4.js ,兩者不同的地方是 ffmpeg 支援的 encoder/muxer 不同,可能是為了精簡 js code size 因此就拆成 webm 跟 mp4 的用法。這邊把玩的是善用 ffmpeg.js Makefile 去重編 ffmpeg-*.js 增加 demuxer/decoder 和 encoder/muxer。

這邊滿適合看一下 ffmpeg 框架:


接著,工作上的任務是讓 input 支援 h264,而 output 支援 jpg/png 等。這邊把範圍限縮到 input 支援 jpg ,輸出支援 png 來筆記。最後包裝個 HTTP API 出來筆記一下,結果花最多時間是在確認如何從檔案系統讀出檔案資料,以及透過 http.request 將圖片資料下載回來 Orz 還派上 md5sum 來檔案內容是否正常。

而 ffmpeg.js 真的設計得不錯,用起來很方便,可以參考 local-file-cmd.js 用法:

const ffmpeg = require('./ffmpeg-20210624_1550/ffmpeg-mp4.js');
//const ffmpeg = require('./ffmpeg-default/ffmpeg-mp4.js');
const fs = require('fs');
const crypto = require('crypto');

let from_local_file = '/tmp/test.jpg';
let raw_data = fs.readFileSync(from_local_file);
let testData = Uint8Array.from(raw_data);
const md5sum = crypto.createHash('md5');
md5sum.update(raw_data);
console.log('[INFO][from_local_file][size:'+raw_data.length+'][md5:'+md5sum.digest('hex')+'][path:'+from_local_file+']');

const result = ffmpeg({
MEMFS: [{name: 'test.jpg', data: testData}],
arguments: ['-i', 'test.jpg', 'test.png']
})
const out = result.MEMFS[0];
const outputContent = Buffer.from(out.data);

console.log('[INFO] Done. Input size: ' + raw_data.length +', testData size: '+testData.length+', output size: '+outputContent.length);

更多資訊:changyy/study-wasm-ffmpeg-jpg-to-png

沒有留言:

張貼留言