A C++ Class to encode raw frames with an external FFmpeg process on a separate thread. Useful for creative coding applications where high quality output is desired.
FFmpegPipeEncoder has no dependencies.
In your CMakeLists.txt
:
include(FetchContent)
FetchContent_Declare(
ffmpegPipeEncoder
GIT_REPOSITORY https://github.com/somecho/FFmpegPipeEncoder
GIT_TAG 0.1.1
GIT_SHALLOW TRUE
)
FetchContent_MakeAvailable(ffmpegPipeEncoder)
target_link_libraries(YOUR_PROJECT PRIVATE FFmpegPipeEncoder)
#include <FFmpegPipeEncoder/PipeEncoder.hpp>
EncoderSettings settings = EncoderSettingsBuilder().resolution(w, h).build();
PipeEncoder encoder(settings);
encoder.start();
unsigned char* data = GET_DATA_FROM_SOMEWHERE();
encoder.encode(data);
// Note: doesn't immediately finish encoding, only tells the encoder not to
// accept anymore frames.
encoder.stop();
With rlFastPixelReader:
#include <raylib.h>
#include <rlgl.h>
#include <FFmpegPipeEncoder/PipeEncoder.hpp>
#include <rlFastPixelReader.hpp>
static int w = 1000;
static int h = 1000;
int main() {
InitWindow(w, h, "Pipe Encoding");
EncoderSettings settings = EncoderSettingsBuilder().resolution(w, h).build();
PipeEncoder encoder(settings);
RenderTexture2D fbo = LoadRenderTexture(w, h);
rlFastPixelReader reader(w, h);
unsigned int frameNum = 0;
SetTargetFPS(60);
encoder.start();
while (!WindowShouldClose()) {
BeginDrawing();
BeginTextureMode(fbo);
ClearBackground(BLACK);
rlTranslatef(w * .5, h * .5, 0);
rlRotatef(GetTime() * 20.0, 0, 0, 1);
DrawPoly({0, 0}, 4, 300, 0, RED);
EndTextureMode();
if (frameNum < (60 * 10)) {
reader.readPixels(fbo);
auto data = reader.getData();
encoder.encode(data);
}
if (frameNum > (60 * 10)) {
encoder.stop();
}
DrawTextureRec(fbo.texture, {0, 0, (float)w, (float)h}, {0, 0}, WHITE);
EndDrawing();
frameNum++;
}
}
With ofxFastFboReader
:
#include <memory>
#include <FFmpegPipeEncoder/PipeEncoder.hpp>
std::unique_ptr<PipeEncoder> encoder;
ofFbo fbo;
ofPixels pix;
ofxFastFboReader reader;
void setup(){
fbo.allocate(ofGetWidth(), ofGetHeight());
EncoderSettings settings = EncoderSettingsBuilder().resolution(w, h).build();
encoder = std::make_uniquqe<PipeEncoder>(settings);
encoder->start();
}
void draw(){
fbo.begin();
ofClear(0,0,0,0);
ofDrawCircle(ofGetWidth()*0.5, ofGetHeight()*0.5, 300);
fbo.end();
if(ofGetFrameNum() < (60 * 10)){
reader.readToPixels(fbo, pix);
encoder->encode(pix.getData());
}
if(ofGetFrameNum() > (60 * 10)){
encoder->stop();
}
}
MIT License, Copyright © 2024 Somē Cho