Skip to content


FLVRecorder for Adobe AIR

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.

Screenshot of AirCam

Screenshot of AirCam

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.

Download update here.

*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.



Posted in AIR, AS3, BoulevArt, Flash, Flex.

Tagged with , , .


49 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Michiel says

    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. ;)

  2. Mike says

    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)

  3. Brombvamb says

    nice, really nice!

  4. Pier says

    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?

  5. Joris Timmerman says

    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.

  6. Stewie says

    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?

  7. will says

    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

  8. Joris Timmerman says

    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 :)

  9. Joris Timmerman says

    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.

  10. Evan Gifford says

    Hey Joris,

    Amazing work. I used cam.setMode(640,480,15) to get a much better resolution out of the web cam. :)

  11. Evan Gifford says

    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/

  12. Jonas J. says

    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??

  13. Basti says

    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

  14. Andrea says

    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?

  15. Joris Timmerman says

    Hey,

    feel free to change the code, the project is open-source.
    The generated FLV is indeed uncompressed.

    FLV is simply a container format – the actual codecs used within an FLV vary. Additionally, the codecs themselves are patented, meaning there are legal barriers for using them.

    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.

  16. Flv Recorder says

    Excellent work….

    Thanks for the post.

  17. drdig says

    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?

  18. Joris Timmerman says

    In this case, I think you’re better of with a FMS server like Red5…

  19. kkm says

    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.

  20. Jesus says

    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.

  21. Joris Timmerman says

    @Jesus
    That’s possible, check out this: http://www.neave.com/webcam/

  22. Jesus says

    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.

  23. Joris Timmerman says

    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.

  24. Alexander says

    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.

  25. Victor Y. Sklyar says

    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.

  26. Joshep says

    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

  27. Phil says

    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?

  28. qiter says

    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?

  29. claudiu says

    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

  30. Peter Goes says

    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

  31. TheOne says

    hi,
    I have same problem as Peter.

  32. Bryce says

    Would this work for mobile AIR? Has anyone tried it?

  33. Bryce says

    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]

  34. Lexxx says

    Thanks for Scripts!

    Peter Goes, you should use same size in setTarget method and display object which you wont record.

  35. Lotus says

    Hi, without saving the file (AIR), is it possible to store it as a ByteArray and send it to a server?

  36. Matt says

    Also interested in a mobile app with this. Anyone tried this?

  37. Danyllo says

    Hi, Peter.

    Maybe your problem is in the call of recorder.setTarget. The width and height must be equals to resolution cam.

  38. Camdenmoo says

    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?

  39. mattlink says

    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.

  40. Vadym says

    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

  41. Michael says

    @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

  42. Giles Roadnight says

    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?

  43. moonlight says

    hello im new in adobe air can i run the flash air version of this aircam in browser?? thanks

  44. Manoj Kumar says

    Can you give me a working demo please? I’m on a deadline :)

  45. Manu says

    Hello,
    is it possible to be recorded the video in mp4 instead of flv? Thanks
    Manu

  46. Joris Timmerman says

    Hi, no, you can’t since AIR is a desktop environment. The code uses desktop related API’s like writing to disk.

  47. Joris Timmerman says

    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.

  48. Joris Timmerman says

    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! :)



Some HTML is OK

or, reply to this post via trackback.