這邊從 stdout 或 stderr 流輸入給 ffmpeg 做壓縮,主要就是利用 pipe 做 IPC
寫個小程式順便比較 javascript (nodejs) 和 C 語言的速度差異,最佳化的結果是 javascript 輸出到 stderr 幾乎等速於 C 語言,令人有點意外XD;反而直出到 stdout 的速度比 C 語言慢了 30%,這不太科學 。
題外話是 stderr 通常不會有 buffer 的問題,大多數時候都不用擔心沒有 flush 乾淨
最後我們會在 command line 把 stderr 流灌到 stdout 中,給 ffmpeg 接收,其實速度超快的,極限大概是 full HD 80FPS,若不考慮產生影像,已經足以 realtime 計算了
#include <stdio.h>
#include <stdlib.h>
// includes for setmode
#include <fcntl.h>
#include <io.h>
int imgSizeX = 1920;
int imgSizeY = 1080;
int imgNum = 0;
int mvX = 5;
int mvY = -2;
int main(int argc, char *argv[]) {
imgNum = atoi(argv[1]);
// change to binary stdout mode (avoid 0x0A be changed into 0x0D 0x0A)
setmode(2, _O_BINARY);
char *img = new char[imgSizeX*imgSizeY*3];
for (int i = 0; i < imgNum; ++i) {
for (int y = 0; y < imgSizeY; ++y) {
for (int x = 0; x < imgSizeX; ++x) {
int offset = y*imgSizeX*3 + x*3;
img[offset+0] = (y+i*mvY) & 0xFF;
img[offset+1] = (x+i*mvX) & 0xFF;
img[offset+2] = 0x00;
}
}
fwrite(img, 1, imgSizeX*imgSizeY*3, stderr);
}
fflush(stderr);
delete [] img;
return 0;
}
set inputSettings=-f rawvideo -pix_fmt rgb24 -video_size 1920x1080 -r 60 set outputSettings=-vcodec libx264 -qp 18 -x264opts opencl -pix_fmt yuv420p -r 60 set outputFile=output.mp4 del %outputFile% a.exe 1000 2>&1 | ffmpeg %inputSettings% -i - %outputSettings% %outputFile% pause
let imgSizeX = 1920;
let imgSizeY = 1080;
let imgNum = 1000;
let data = Buffer.alloc(imgSizeX*imgSizeY*3);
for (var i = 0; i < imgNum; i+=1) {
var offset = 0;
for (var y = 0; y < imgSizeY; ++y) {
for (var x = 0; x < imgSizeX; ++x) {
offset += 3;
data[offset+0] = (x+i*5) & 0xFF;
data[offset+1] = (y+i*(-2)) & 0xFF;
data[offset+2] = 0x00;
}
}
process.stderr.write( data );
}
set inputSettings=-f rawvideo -pix_fmt rgb24 -video_size 1920x1080 -r 60 set outputSettings=-vcodec libx264 -qp 18 -x264opts opencl -pix_fmt yuv420p -r 60 set outputFile=output.mp4 del %outputFile% node main.js 2>&1 | ffmpeg %inputSettings% -i - %outputSettings% %outputFile% pause
