不生成本地文件,而是將編碼器輸出直接通過管道/流寫入 HTTP 請求體(Chunked Transfer Encoding),服務器端流式接收寫入磁盤或對象存儲。
┌─────────────┐ 原始視頻流 ┌─────────────┐ HTTP Chunked ┌─────────────┐
│ 屏幕捕獲 │ ─────────────────▶ │ FFmpeg編碼 │ ────────────────────▶ │ 服務器接收 │
│ (Desktop │ (管道/共享內存) │ (H.264/ │ (multipart/form-data │ (流式寫入 │
│ Duplication)│ │ VP8/HEVC) │ 或原始二進制流) │ 文件/OSS) │
└─────────────┘ └─────────────┘ └─────────────┘
Desktop Duplication API (DXGI) 效能最高,或 Graphics.CopyFromScreen(簡單但慢)。推薦成熟庫 ScreenCapture.NET、SharpDX。ffmpeg -f rawvideo -pix_fmt bgra -s 1920x1080 -r 30 -i pipe:0 \
-c:v libx264 -preset ultrafast -tune zerolatency -f mp4 -movflags frag_keyframe+empty_moov pipe:1
pipe:0 讀取 stdin(原始幀),pipe:1 輸出 stdout(MP4 片段)。-movflags frag_keyframe+empty_moov 產生可流式播放的 fMP4(無需 moov 原子在文件尾)。var psi = new ProcessStartInfo {
FileName = "ffmpeg.exe",
Arguments = @"-f rawvideo -pix_fmt bgra -s 1920x1080 -r 30 -i pipe:0 -c:v libx264 -preset ultrafast -tune zerolatency -f mp4 -movflags frag_keyframe+empty_moov pipe:1",
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true
};
var ffmpeg = Process.Start(psi);
// 寫入原始幀到 ffmpeg.StandardInput.BaseStream
// 讀取 ffmpeg.StandardOutput.BaseStream 並 POST 到服務器
using (var client = new HttpClient()) {
client.DefaultRequestHeaders.TransferEncodingChunked = true;
using (var content = new StreamContent(ffmpeg.StandardOutput.BaseStream)) {
content.Headers.ContentType = new MediaTypeHeaderValue("video/mp4");
var response = await client.PostAsync("https://api.example.com/upload/stream", content);
}
}
服務器端 需支持 Chunked 請求體流式讀取(ASP.NET Core Request.Body、Node.js req.pipe()、Java request.getInputStream()、Go r.Body、Nginx proxy_request_buffering off)。若是 Web 端錄屏,直接用 navigator.mediaDevices.getDisplayMedia() + MediaRecorder 產生 Blob 片段,WebSocket/WebRTC 實時推流到媒體服務器,完全無本地文件。
Process.StandardOutput.BaseStream 讀取速度 ≥ 寫入速度,或限制碼率(-b:v 2M)。ultrafast + zerolatency 將延遲壓至 100-200ms,適合實時場景。