«

»

Apr 11

Simplified FFMPEG video writer (also for OpenFramework) [w/ code]

I want to share a little snippet in case anyone is interested in writing video files from cpp context using FFMPEG, I've made it for usage with OpenFrameworks.
It's basically a simple wrapper around the encoding mechanism of FFMPEG, so you can easily just say which file to write to and start dumping images into it. It will take care of choosing the codec, writing headers and trailers, encode (compress) the frames and write them to the file.

class ofxFFMPEGVideoWriter {
    //instance variables...

    bool initialized;

public:
    ofxFFMPEGVideoWriter():oc(NULL),codec(NULL),initialized(false),frame_count(1) {}
    
    /**
     * setup the video writer
     * @param output filename, the codec and format will be determined by it. (e.g. "xxx.mpg" will create an MPEG1 file
     * @param width of the frame
     * @param height of the frame
     **/
    void setup(const char* filename, int width, int height);
    /**
     * add a frame to the video file
     * @param the pixels packed in RGB (24-bit RGBRGBRGB...)
     **/
    void addFrame(const uint8_t* pixels);
    /**
     * close the video file and release all datastructs
     **/
    void close();
    /**
     * is the videowriter initialized?
     **/
    bool isInitialized() const { return initialized; }
};

So you can see the API is as simple as possible, and specialized for writing RGB images (24-bit packed, RGBRGBRGB...)
The setup() function will t

The internals are taken from the FFMPEG API examples: http://ffmpeg.org/doxygen/trunk/examples.html
But it's kind of long to put here, so check out the code.

In OpenFrameworks I used it to capture the screen and save it:

//--------------------------------------------------------------
void testApp::setup(){
    ofEnableSmoothing();
    ofBackground(0);
    
    videoWriter.setup("output.mpg", ofGetViewportWidth(), ofGetViewportHeight());
}

//--------------------------------------------------------------
void testApp::update(){
    if(videoWriter.isInitialized()) {
        ofscreenimg.grabScreen(0, 0, ofGetViewportWidth(), ofGetViewportHeight());
        videoWriter.addFrame((const uint8_t*)(ofscreenimg.getPixels()));
    }
}

//--------------------------------------------------------------
void testApp::draw(){
    ofFill();
    ofSetColor(255, 0, 255);
    ofCircle(mousept.x, mousept.y, 15);
}

//--------------------------------------------------------------
void testApp::mousePressed(int x, int y, int button){
    mousept.x = x; mousept.y = y;
}

//--------------------------------------------------------------
void testApp::mouseDragged(int x, int y, int button){
    mousept.x = x; mousept.y = y;
}

//--------------------------------------------------------------
void testApp::mouseReleased(int x, int y, int button){
    mousept.x = -50; mousept.y = -50;
}

Code

http://web.media.mit.edu/~roys/src/FFMPEGVideoWriter.zip

Enjoy!

Share