hey all!
FIRST OF ALL: sorry for the long post, this is rather cause i tried be comprehensive, not becasue it’s crazy complicated.
Download (with sample code) is at the end of this post.
i’m working on a/v export for soundythingie which resulted in this little addon that renders audio/video to a file. for portability reasons i’ve decided to go for ffmpeg instead of quicktime so this should work on most platforms.
the package contains the source files of the main class “FFMovieMaker.mm” (just rename to .cpp if you’re on windows) as well as a very minimal ffmpeg universal binary that is compiled for newer macos and armv7 (iphone4/ipad). if those binaries aren’t suitable for you please compile your own (i’ll get into that later).
how to export video (optionally with audio)
first somewhere in setup you’ll want to create your moviemaker and adjust the options:
// output video will be 640x480. if your app runs at a different
// resolution you can pass in an additional two params for the
// source width/height
movieMaker = new FFMovieMaker( "my-filename.mpg", 640, 480 );
// now go nuts on the options, check FFMovieMaker.h for the
// struct definition with short explanations
movieMaker->config.v_destFrameRate = 25;
// those are only needed if you have audio as well
// again, check the defaults in the struct,
// maybe you don't need to change anything!
movieMaker->config.a_srcSampleRate = SAMPLE_RATE;
movieMaker->config.a_srcChannels = NR_CHANNELS;
// all options set? go!
movieMaker->begin();
once you’ve done this you’ll want to add frames into the video (presumably inside draw), the easiest way of doing so is to write
movieMaker->addScreen();
you can also pass in an pixels array directly. there’s a function movieMaker->addPixels( int * pixels ); look at the source of addScreen() to see how to use it.
if you don’t need audio skip this paragraph. but if you also want to record audio it gets a bit more complicated. the easiest way to accomplish it is by disabling audio output during record. i do that as follows:
void audioRequested( float * data, int buffSize, int channels ){
if( isYourThingRecording )
// uh... don't generate audio!
for( int i = 0; i < buffSize*channels; i++ ) data[i] = 0;
else{
calculateAudio( data, buffSize, channels );
}
void calculateAudio( float * data, int buffSize, int nChannels ){
// your original audioRequested code goes here!
}
// finally, inside draw add this:
if( movieMaker->wantsAudio() ){
float temp[BUFFER_SIZE*CHANNELS];
calculateAudio( temp, BUFFER_SIZE, CHANNELS );
movieMaker->addAudio( temp, BUFFER_SIZE*CHANNELS );
}
when you recorded enough material call:
movieMaker->finish();
DON’T call any function on the movieMaker after that, your app will crash!
how to export just audio
that is much easier, setting the FFMovieMaker up is the same, just pass in 0 for the width and the height
movieMaker = new FFMovieMaker( "my-file.mp2", 0, 0 );
and no video stream will be added to the output.
now, because there are no threading issues, you can just forward the audio generated inside audioRequested using
void audioRequested( float * output, int bufferSize, int nChannels ){
// fill the buffer... and then:
movieMaker->addAudio( output, BUFFER_SIZE*CHANNELS );
}
when you’re done don’t forget to call movieMaker->finish();
where to get the proper ffmpeg binaries
as i said above, this download contains a very very minimal set of ffmpeg binaries (only compiled for macos+armv7, only mpeg1-video and mpeg2-audio, everything else excluded from the build).
if you want to build for windows/linux/mac os it should be straight forward,
download the ffmpeg source, then run the usual ./configure [your options] && make
this is the minimum set of configure options you’ll need:
–enable-swscale --enable-encoder=mpeg1video --enable-encoder=mp2 --enable-encoder=pcm_s16le --enable-muxer=mpeg1video
if you want to compile your own iphone version (e.g. armv6) i point you to this great project:
https://github.com/gabriel/ffmpeg-iphone-build
it’s a bit of a mess and needs some tweeking, but with some love you can get it working.
another thing you can do is look around for pre-built binaries. i’ve seen a few movie players based on ffmpeg in this forum, if you’re lucky there’s one for your platform and they have the right stuff compiled into it.
there are many more things this addon could support (like choosing codecs) but i just don’t have the time.
please paste back here if you have fixes, ffmpeg binaries, examples or whatnot.
allright, hope this is a good starting point.
enjoy…
best, hansi.
p.s. here’s the download:
ofxFFMovieMaker v2.10764 + minimal ffmpeg binaries for iphone/mac os + sample code for recording audio and video together.
http://asdfg.me/up/ofxFFMovieMaker-with-sample.zip
also look for posts by “plong0” below, he posted a very simple example for exporting just video.
p.p.s. Troubleshooting:
whatever kind of problem you run into, first you should enable debugging output, i.e.
movieMaker = new FFMovieMaker( ... );
av_log_set_level( AV_LOG_INFO ); // this needs to be done _after_ creating the FFMovieMaker instance. by default it's set to AV_LOG_FATAL.
this should give you a whole lot of additional output.