FLVRecorder for Adobe AIR
About
When I was researching earlier this year whether or not I could capture a webcam feed and save it to the Flash Video Format, I stumbled on a guys blog called Zero Point Nine. He made a class that could save frames (BitmapData objects) passed to it as an FLV.
This was nice, but not very performant, as the parsing of the BitmapData to ByteArrays took way too long and was extremely CPU intensive and your app froze up, I decided to adjust the class and make it usable within an Adobe AIR app without losing a single frame, or freezing the app. For this, I started out with a new class, only copied the algorithms for writing an FLV and started building my own api.
The main target of developing this FLV-recorder was performance on the CPU and RAM side.
FLVRecorder
The purpose of this revolutionary new class is to record a stream of BitmapData to a FLV-file, because writing directly, and especially the converting-BitmapData-to-ByteArrays-with-byteshifting-part, made everything run shaky. I solved that issue by saving the BitmapData to a temporary file on the system. This to protect your RAM from overloading, and when done recording, the class converts that temporary file to an FLV-file.
For developing comforts, I build in a few events as well, when recording starts and stops, and an event while saving, with an indication of your progress.
The class offers the user to record via inputting BitmapData, Bitmaps and even your custom components, Flex component, like your VideoDisplay and also Flash components, like the FLVPlayBack or your custom Sprites and MovieClips.
The class does not yet support adding sound to the flv-file, this is the next step of development, to enable sound recording and add sound to the flv-file.
AirCam
As a proof-of-concept, I built a small application that enables you to record your webcam and saved it on your desktop as an flv-file.
Download the AirCam installer here.
To view the source used in this project, right-click somewhere, and choose view source.
The FLVRecorder and all related classes are open source, they are not fully tested and may contain bugs.
I’m happy to share it with the community, use them, play with them and certainly enhance them!
These classes are NOT FOR COMMERCIAL USE and property of BoulevArt nv.
Download the source.
API
The class offers the developer an API to easy implement this in your app.
You should respect a certain flow:
1. Make an instance of the class, it’s a singleton class, so just ask for the instance:
var recorder:FLVRecorder=FLVRecorder.getInstance()
2. Define the target FLV-file’s properties, the file instance to your flv-file, width & height, framerate and the systemManager instance, that’s a Flash internal declared variable and the optional duration in seconds:
file=File.desktopDirectory.resolvePath(“recording.flv”);
recorder.setTarget(file,640,480,fps,systemManager, durationInSeconds)
the duration is optional, it will be automaticly filled in when left blank.
3. Insert some bitmaps, bitmapdatas or a screenshot of a component into the flv-file:
recorder.captureComponent(vidDisplay) //DisplayObject, takes a screenshot from that component
recorder.saveFrame(bmpdata) //Bitmapdata, does nothing with it
recorder. saveSmoothedBitmapFrame(bmp) //Bitmap, smooths before saving
recorder. saveSmoothedFrame(bmpdata) //Bitmapdata, smooths bitmapdata before saving
4. To stop recording, simply command the class to stop, it will start to convert your saved data to the flv-file
recorder.stopRecording()
It will throw 3 events, when saving starts, when savings stops and one while saving to pass on the savings progress
FLVRecorderEvent.FLV_START_CREATION
FLVRecorderEvent.FLV_CREATED
FLVRecorderEvent.PROGRESS //event contains progress property, is a value between 0-1 to indicate progress
5. All done, that’s how simple things can be in life.
6. Test it, use it and give me feedback of your experiences!
How–to-use code example
private var tmr:Timer
private var recorder:FLVRecorder
private var file:File
private function startRecording():void{
if(recorder==null){
recorder=FLVRecorder.getInstance()
}
file=File.desktopDirectory.resolvePath(“recording.flv”);
recorder.setTarget(file,640,480,fps,systemManager)
if(tmr==null){
tmr=new Timer(1000/fps)
}
tmr.addEventListener(TimerEvent.TIMER,record)
tmr.start()
}
private function record(e:TimerEvent):void{
recorder.captureComponent(vidDisplay) //DisplayObject
//recorder.saveFrame(bmpdata) //Bitmapdata
//recorder. saveSmoothedBitmapFrame(bmp) //Bitmap
//recorder. saveSmoothedFrame(bmpdata) //Bitmapdata
}
private function stopRecording():void{
tmr.stop()
//when saving is done
recorder.addEventListener(FLVRecorderEvent.FLV_CREATED,fileMade)
//when saving starts
recorder.addEventListener(FLVRecorderEvent.FLV_START_CREATION,startCreatingFLV)
recorder.stopRecording()
}
private function startCreatingFLV(e:FLVRecorderEvent):void{
recorder.addEventListener(FLVRecorderEvent.PROGRESS,onFLVCreationProgress)
}
private function onFLVCreationProgress(e:FLVRecorderEvent):void{
//e.progress: percent complete (0 to 1)
//pbSaving: ProgressBar component in Flex
pbSaving.setProgress(e.progress,1)
}
Downloads
Contact!
Share your opinion with us, leave a comment!
Also tell me if you’re using the class, what you wanted to see different, share your enhancements!
Don’t forget to show me what apps you made with these classes!
You can always reach me:
just leave a comment!
*UPDATE 1*
Thanks for your feedbacks, I’ve updated the classes to help out a few of you.
What is new:
An enableCompression property: will compress the captured image with the JPGEncoder
Warning! Using this property will slow you application down.
Codecs:
Pick a codec. You can find the available codecs in the FlvRecorderCodecs class.
Pausing & Resuming recordings:
You can pause & resume recordings.
If you stop feeding the class frames, and not call the stopRecording() function, and after a while, feeding it some frames again, it will add those frames to the current movie.
*UPDATE 2*
Because I am using a Pseudo-Threading class that is using a specific Flex class, and a lot of you are Flash-only developers, I have released a library for Flash (AS3) on Google Code.
Here is a link.





Hi there,
I tried to use your flv recorder to use in flash.
But if I try to compile in flash
I get an error about the IS SystemManager.
If I look inside your source files I find that you use :
import mx.managers.ISystemManager;
what is what I believe something of the flex builder.
How could I use your classes in Flash.
I hope you can answer my question.
michiel
—
Heya,
You find a solution on my Pseudo-Threading blogpost on how to get rid of that SystemManager (that is a Flex SDK class).
I have uploaded a flashlib of the flvrecorder on google code, download it.,
Hope that helps.
Whoops, I was setting the incorrect size for the display object to be recorded, working fine now. Thanks
—
No problem,
You’ll get a EOF-error when AIR tries t o write something out of ByteArray that isn’t bitmapdata.
Enjoy playing with this!
(oh btw, You can capture a display object by using the flvrecorders captureComponent(displayObject) method, this will take a screenshot of the component)
nice, really nice!
Nice project!
Hi can I use the Flash classes with a flash projector and save flv on the local machine?
Would that be better/worst in terms of performance than using AIR?
Thx,
I’m sorry but that is not possible, because one of AIR’s benefits is that it offers direct acces to the file system.
AIR stands for Adobe Integrated Runtime, meaning its’s a framework for desktop apps developed by Adobe with integration with their software.
It’s build to be a desktop environment, so I reccon it’s much better in terms of performance.
hi there,
I downloaded the flex version and have implemented it and all works amazingly..
however i noticed you made an update for compression, and codecs.. but im not sure where i can edit these values in the code?
would it be possible that i do not have the updated version of the files?
Hello, I am having problem find out what the systemManager is in this line
recorder.setTarget(file,640,480,fps,systemManager, durationInSeconds)
Please help,
thanks, will
There is function to encode the bitmaps, but I wouldn’t recommend it, it was experimental but it slows your app down A LOT
The codecs, I was developing it, but when my time ran out I gave up on it
The SystemManager class is only available in Flex.
To see how to implement it, take a look at the AIRCam app.
There is a right-click menu “View Source” that reviels the source code.
If your building your AIR app in Flash, you can download the library for Flash under downloads.
Hey Joris,
Amazing work. I used cam.setMode(640,480,15) to get a much better resolution out of the web cam.
It just occured to me why you are scaling video like that. Instead of using bitmap.smoothing and scaling video like that, check out this post: http://blog.onthewings.net/2009/08/25/bicubic-resampling-by-pixel-bender/
I’ve been looking for something like this, I manage to make a working sample with your code and it works. The problem is that if I have a 2 minutes recording it consumes upto 400~500 mb of RAM (during saving process), I try this on different machines (windows and mac) and RAM usage always peeks… so a 10 mins video will be unbereable.
I didnt use additional code for this example, only the provided here and normal mx:componentes… anyone has notice all of this??
Hello,
I was wondering if it is really not possible to run that in AS without using AIR? Flashplayer 10 allows you to access the local file system after user permission. I don’t like that I have to install AIR before running the program.
Thanks, Basti
Hello,
wonderful code!
the generated FLV is very very big…
i think that is because the code generate only keyframe and not frame.
how can i change the code?
and also…
i see that some flv player as FlowPlayer and JWPlayer dont stop the file correctly.
Do you have some solution?
Hey,
feel free to change the code, the project is open-source.
The generated FLV is indeed uncompressed.
You can try to build in codecs, wish you good luck doing that
Be sure to call the API methods in the right sequence so the EOF is written right.
Excellent work….
Thanks for the post.
Hey,
great work. I am currently looking for a solution which I would like to run on a linux/windows webserver (prefered linux), that is capable of receiving a series of bitmapData objects and will then generate a (compressed) flv out of the bitmapDatas… do you know if this could be done with your solution? I am wondering whether i can run air apps on the server?
In this case, I think you’re better of with a FMS server like Red5…
yeah Red5 is really good, I have tried, and works.
@Joris
can you give original source of flash (*.fla) , please. I am not as3 well.
thanks for answer.
Hello Joris,
Im working with adding video effects from webcam input, blurry, brightness or sprites into the image, etc. and Id like to capture the resulting video for the user to playback. I am designing it in flash, with as3. Do you know any simple way to do that?? do you think your source code could be helpful for my purposes??? thanks a lot in advance, Jesús.
@Jesus
That’s possible, check out this: http://www.neave.com/webcam/
I’ve checked the source code of neave webcam, truly awsome!!! cool effects. But the code doesn’t provide any way to record the video…so I suppose your code would provide that feature to me, recording all BitmapData frames to a FLV-file. But the problem for me is the space… is there no way to post apply some basic effects like brightness or blurry with a compressed flv file? thanks for your help, Jesús.
Hi,
Sorry, no uncompressed is all I can do, since the FLV codecs aren’t free to use without a license.
Else you could try using a server like Red5.
great job. i am now working in a personal application that is similar. but i need to add audio to the resulting flv. are you still working on it?. what would be necessary to accomplish this?.
í’m interested in expanding the class so it can do the complete video/audio recording.
hi, thanks for you work
is it possible to write result flv in memory (not in file)?
I think it would be great to post after stop recording (30 sec max – about 500K) result file to server (works without FMS).
What do you think about? (It is linked with last question about record audio)
Thanks.
http://www.adobe.com/devnet/air/flex/articles/air_screenrecording.html
Hello,
I download AIRCAM and test in my desktop, and it work well, but when i can’t preview video. I also can’t open it with FLVplayback
Any help
I am having the same problem as Joshep… I’ve built an application using your code (thanks!) and it works when I run it within the FlexBuilder IDE, but when I export it as a release and install it using Adobe Air, it will not create the flv correctly, and will not play it back either. Any suggestions Joris? Anyone?
hi Joris
I download AIRCAM ,but i don’t heard the audio in this flv.
what method is add audio into the flv.
please,help.thx!
What method is add audio in this FLVRecorderclass with ByteArray?
i tried this class to make a flv movie out of a movieclip, and it works great, but the background is opaque white. how can i make it transparent ? Thanks
Hi Joris,
Awesome work you are doing here!
I have downloaded the as3 version (update 2) and tried to make an application by myself. But when the stopRecording() method is called, I get a “End of file was encountered” error with the following addition:
at flash.display::BitmapData/setPixels()
at be.boulevart.video::FLVRecorder/doStop()
at be.boulevart.threading::PseudoThread/renderHandler()
Do you know how I can solve this?
And since I was not able to test this yet, do you know if your class is able to record a full HD (1920×1080) video?
Regards,
Peter
hi,
I have same problem as Peter.
Would this work for mobile AIR? Has anyone tried it?
Update: I’m trying this in Mobile AIR and running into the same error as Peter.
Error: Error #2030: End of file was encountered.
at flash.display::BitmapData/setPixels()
at be.boulevart.video::FLVRecorder/doStop()[/Users/bryce/Documents/Adobe Flash Builder 4.5/DeleteMe/src/be/boulevart/video/FLVRecorder.as:308]
at be.boulevart.threading::PseudoThread/renderHandler()[/Users/bryce/Documents/Adobe Flash Builder 4.5/DeleteMe/src/be/boulevart/threading/PseudoThread.as:65]
Thanks for Scripts!
Peter Goes, you should use same size in setTarget method and display object which you wont record.
Hi, without saving the file (AIR), is it possible to store it as a ByteArray and send it to a server?
Also interested in a mobile app with this. Anyone tried this?
Hi, Peter.
Maybe your problem is in the call of recorder.setTarget. The width and height must be equals to resolution cam.
Does anyone have any idea how to implement this? How do I go about including the source files?
I have a webcam live broadcast app that saves FLV video directly to a flash media server, but I want to have the ability to save the FLV file to the users computer as well.
Can anyone help?
excellent work, then I have a question for you Joris Timmerman, do you know if you can only record a certain amount of time, for example: if it reaches 100 mb the file I am creating stop recording, the 100 mb be the limit for the video I’m creating.
Here is POC to record the video locally in AIR using embedded Red5 media server http://mydevrecords.blogspot.com/2012/01/local-recording-in-adobe-air-using-red5.html
@camdenmoo:
Which webcam live broadcast app do you use for streming to the media server? Any recommandations for me as I am looking for something like that at the moment…
Greets,
Michael
Hi Joris
I am very interested in using your class as a possible solution for the problem I outline here:
http://stackoverflow.com/questions/10216767/is-it-possible-to-generate-a-movie-file-in-flex-air
Another option I am considering is using native extensions and encoding the video in java but your class is a great first step.
I am have set up a very simple test application and I am getting a lot of errors when I run it.
ArgumentError: Error #2015: Invalid BitmapData.
at flash.display::BitmapData/getPixel()
at be.boulevart.video::FLVRecorder/videoData()[C:\Users\Giles Roadnight\workspace\FLVRecordedTest\src\be\boulevart\video\FLVRecorder.as:443]
at be.boulevart.video::FLVRecorder/flvTagVideo()[C:\Users\Giles Roadnight\workspace\FLVRecordedTest\src\be\boulevart\video\FLVRecorder.as:375]
at be.boulevart.video::FLVRecorder/writeFrame()[C:\Users\Giles Roadnight\workspace\FLVRecordedTest\src\be\boulevart\video\FLVRecorder.as:135]
at be.boulevart.threading::PseudoThread/renderHandler()[C:\Users\Giles Roadnight\workspace\FLVRecordedTest\src\be\boulevart\threading\PseudoThread.as:79]
Can I have your e-mail address so I can send you my sample apps?
hello im new in adobe air can i run the flash air version of this aircam in browser?? thanks
Can you give me a working demo please? I’m on a deadline
Hello,
is it possible to be recorded the video in mp4 instead of flv? Thanks
Manu
Hi, no, you can’t since AIR is a desktop environment. The code uses desktop related API’s like writing to disk.
There is a working code example in the post, called AIRCam, it’s a couple of years old but it should still work.
http://flvrecorder.googlecode.com/files/AirCam.air
To view it’s source, install it, run it and right click anywhere to view source.
Yes,
it is.
If you change the encoding algorithms to encode to a MP4 codec instead of an FLV codec.
If you managed to do so, send me your patch and I’ll update the class.
Good luck!