最近接獲一個任務研究了一下 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);
沒有留言:
張貼留言