Close Show/hide page

SimpleFlvWriter.as - AS3 Class to Create FLV’s

An Actionscript 3 class for use with Adobe AIR to create uncompressed Macromedia Flash Video (FLV) files to the local filesystem. It will add proper onMetaData info as well. It’s very simple to use.

Example usage:

var myWriter:SimpleFlvWriter = SimpleFlvWriter.getInstance();
myWriter.createFile(myFile, 320,240, 30, 120);
myWriter.saveFrame( myBitmapData1 );
myWriter.saveFrame( myBitmapData2 );
myWriter.saveFrame( myBitmapData3 ); // ... etc.
myWriter.closeFile();

See the comment blocks in the source for more info. It doesn’t support audio.

This comes out of the app I made a little while ago, Webcam DVR. I’m posting the class file now because the app is fresh in my mind, as I just updated it to make it compatible with the current AIR runtime to enter it into the Adobe AIR Developer Derby.

Download Webcam DVR for AIR, updated for the beta AIR runtime (See the previous Webcam DVR post for usage notes).

Licensed under a Creative Commons Attribution 3.0 License.

23 Responses to “SimpleFlvWriter.as - AS3 Class to Create FLV’s”

  1. Benz Says:

    Cool stuff! I hope to include something like writing frames into my RichFLV tool soon.
    Keep up the good work!
    Benz

  2. admin Says:

    Thanks, Benz. Good luck with RichFLV.

    Lee

  3. Ben Says:

    How would one go about including audio recordings with this? I don’t expect any code, but just to be pointed in the right direction.

  4. admin Says:

    Ben,

    I don’t have any good ideas on that. I’ve never tried recording audio with Flash, and I skipped everything in the FLV spec that referred to audio (http://www.adobe.com/licensing/developer/). I’m assuming the biggest challenge would be managing the video and audio to stay in sync.

    Lee

  5. Benz Says:

    Syncing video and audio in an flv is actually pretty simple. My RichFLV tool does that. You can import an mp3 file and use that as the soundtrack for an flv and export the whole thing as a flv.
    The bigger problem would be to record the sound as it`s not possible to save the microphone input with AIR (for now).

  6. admin Says:

    > The bigger problem would be to record the sound as
    > it`s not possible to save the microphone input with AIR (for now).

    Hah. Good point! :)

  7. oliver_l1 Says:

    Please add audio support if possible! This class rocks!

  8. Henry Schmieder Says:

    Thanks for this. Im looking forward to seeing this class / package more complex. Killer was, if i could load any flv remote source via URLLoader to ByteArray and render a ByteArray representing a timeline region from that via e.g. var clip:ByteArray = cropper.extract( baFlvSource, 10000, 15000 ).
    This would produce a 5 seconds clip starting at 10 seconds. the returning ByteArray can be given to writer.saveClip( clip );
    I am not that skilled to do it on my own, so i hope you get motivated to at least give some hint ;)

  9. Henry Schmieder Says:

    The assembled movie could have a soundtrack as mp3 like Benz said. By the way, iam still hoping Benjamin will publish at least core parts of his RichFLV

  10. Jonathan Marecki Says:

    Thanks for the actionscript class. this gives me a great start on my new project. I was wondering if there was a way to create a buffer of the video in actionscript or another way to be able to grab a section of video that was previously recorded.

    Thanks again.

    Jon Marecki

  11. admin Says:

    Jonathan,

    Creating a buffer in memory is totally doable. It really doesn’t have anything to do with the SimpleFlvWriter class in any direct way. What you would do is create an array of BitmapData’s. Copy the video frames as they come in (whether they be from a streaming FLV or from the webcam) into the elements of that array. Just be careful of memory usage, of course. To play back, copy the frames from the array to a Sprite or whatever as needed, presumably on an onEnterFrame or setInterval loop.

    I actually do just that in the Webcam DVR AIR app. I save the most recent 100 or so frames of webcam video to a BitmapData array, which serves as a memory cache. If the user plays back the last 3 or 4 seconds of video, it doesn’t have to read off of the hard drive, but instead, gets the appropriate frame from memory.

  12. admin Says:

    [This is a response to Henry’s question…]

    Henry,

    Flash doesn’t allow you to capture BitmapData from FLV’s or other other assets from a different domain unless the crossdomain.xml settings on that domain allow you to.

    But in any case, what you’re describing sounds like a great idea for an online app. Something like VirtualDub, where you could select sections of a video to cut or retain (or even a multiple number of videos to combine into one).

    Anyway, the gist of how it could work would be to playback the video in question, probably by seek()’ing to each successive frame in the video, and copying each frame you want to keep into a BitmapData object which you would save to disk using the SimpleFlvWriter class. I don’t know if that’s too general to be of use to you. Good luck on it.

    Lee

  13. Todd Says:

    This is great to see someone is doing this, I have been looking for some kind of video encoding from out of Flash in AS3 and this is great!

    I noticed this is uncompressed, are there any open compression mechanisms for flv or are all the compression algorithms proprietary? I would definitely be interested if anyone is working on an AS3 h.264 compressor to export full DVD or HD quality video. Have you heard if anyone is working on this kind of solution?

    Todd

  14. Usenet Anbieter Says:

    Doesn’t RTMP solve that ? I think there is a great open-source software called red5 out there that allows you to stream .flvs - Anyway. As an Usenet Provider we are trying to work on a solution to actually stream content into usenet groups. Because of the peering there would be a delay, but it should be possible to prebuffer content out of the usenet and then fetch the headers every 10 secs.

  15. SimpleFLVFan Says:

    Lee,

    Awesome script. Unfortunately, I just tested it and a 4 second video is 32 mb! -gulp-

    No compression? Any tips for getting that filesize down? It’s 754×220 @ 30 fps.

  16. Chaminda Prasad Says:

    I need save on hard disk one minite swf file just one click capture from webcam, can any one know that please let me know

  17. nurah Says:

    thanks

  18. SimpleFLVFan Says:

    Lee,

    What would it take to add a compression CODEC to this?

    Per http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v9.pdf , here are the codecs available:

    1: JPEG (currently unused)
    2: Sorenson H.263
    3: Screen video
    4: On2 VP6
    5: On2 VP6 with alpha channel
    6: Screen video version 2
    7: AVC

    It would be great to be able to get the final file size down.

    Thanks!

  19. admin Says:

    SimpleFLVFan:

    I think the answer is… quite a lot :)

    If anyone has any ideas on this… please to tell.

    Lee

  20. Neeraj Says:

    Hey can you plz guide me as to how to go thru the process of making this work?
    this is what i did…
    public function init():void
    {
    var myWriter:SimpleFlvWriter = SimpleFlvWriter.getInstance();
    var myFile:File=new File(”c:/check1.flv”);
    var myArray:Array=new Array;
    var myBitmapData1:BitmapData=new BitmapData(100,100,false);
    var myBitmapData2:BitmapData=new BitmapData(100,100,false);
    var myBitmapData3:BitmapData=new BitmapData(100,100,false);
    var myBitmapData4:BitmapData=new BitmapData(100,100,false);
    var myBitmapData5:BitmapData=new BitmapData(100,100,false);
    var myBitmapData6:BitmapData=new BitmapData(100,100,false);
    var myBitmapData7:BitmapData=new BitmapData(100,100,false);
    var myBitmapData8:BitmapData=new BitmapData(100,100,false);
    var myBitmapData9:BitmapData=new BitmapData(100,100,false);
    var myBitmapData10:BitmapData=new BitmapData(100,100,false);
    var myBitmapData11:BitmapData=new BitmapData(100,100,false);
    var myBitmapData12:BitmapData=new BitmapData(100,100,false);
    var myBitmapData13:BitmapData=new BitmapData(100,100,false);
    var myBitmapData14:BitmapData=new BitmapData(100,100,false);
    var myBitmapData15:BitmapData=new BitmapData(100,100,false);
    var myBitmapData16:BitmapData=new BitmapData(100,100,false);
    var myBitmapData17:BitmapData=new BitmapData(100,100,false);
    var myBitmapData18:BitmapData=new BitmapData(100,100,false);
    var myBitmapData19:BitmapData=new BitmapData(100,100,false);
    var myBitmapData20:BitmapData=new BitmapData(100,100,false);
    myBitmapData1.floodFill(0,0,0xff0000);
    myBitmapData2.floodFill(0,0,0xff0000);
    myBitmapData3.floodFill(0,0,0xff0000);
    myBitmapData4.floodFill(0,0,0xff0000);
    myBitmapData5.floodFill(0,0,0xff0000);
    myBitmapData6.floodFill(0,0,0xff0000);
    myBitmapData7.floodFill(0,0,0xff0000);
    myBitmapData8.floodFill(0,0,0xff0000);
    myBitmapData9.floodFill(0,0,0xff0000);
    myBitmapData10.floodFill(0,0,0xff0000);
    myBitmapData11.floodFill(0,0,0xff0000);
    myBitmapData12.floodFill(0,0,0xff0000);
    myBitmapData13.floodFill(0,0,0xff0000);
    myBitmapData14.floodFill(0,0,0xff0000);
    myBitmapData15.floodFill(0,0,0xff0000);
    myBitmapData16.floodFill(0,0,0xff0000);
    myBitmapData17.floodFill(0,0,0xff0000);
    myBitmapData18.floodFill(0,0,0xff0000);
    myBitmapData19.floodFill(0,0,0xff0000);
    /*for(var i:int=0;i<80;i++)

    {
    myBitmapData1.floodFill(0,0,0xff0000);
    myArray.splice(i,0,new BitmapData(100,100,false));

    }*/

    myWriter.createFile(myFile, 320,240, 30, 120);
    /*for(var k:int=0;k++;k<80)
    {
    myWriter.saveFrame((BitmapData)(myArray[k]));
    } // etc.*/

    myWriter.saveFrame( myBitmapData1 );
    myWriter.saveFrame( myBitmapData2 );
    myWriter.saveFrame( myBitmapData3 );
    myWriter.saveFrame( myBitmapData4 );
    myWriter.saveFrame( myBitmapData5 );
    myWriter.saveFrame( myBitmapData6 );
    myWriter.saveFrame( myBitmapData7 );
    myWriter.saveFrame( myBitmapData8 );
    myWriter.saveFrame( myBitmapData9 );
    myWriter.saveFrame( myBitmapData10 );
    myWriter.saveFrame( myBitmapData11 );
    myWriter.saveFrame( myBitmapData12 );
    myWriter.saveFrame( myBitmapData13);
    myWriter.saveFrame( myBitmapData14 );
    myWriter.saveFrame( myBitmapData15 );
    myWriter.saveFrame( myBitmapData16 );
    myWriter.saveFrame( myBitmapData17 );
    myWriter.saveFrame( myBitmapData18 );
    myWriter.saveFrame( myBitmapData19 );

    myWriter.closeFile();
    }

    there is a .flv file being made,but that doesnt show me any videos,whereas i was expecting atleast a red screen.

  21. mels Says:

    Neeraj, tested your code and it worked..

  22. Jessie Says:

    capture flash video…

    ) Some individuals or companies have abused the TrackBack feature to insert spam links on some blogs (see sping). The TrackBack specification…

  23. Clip Frames Says:

    Clip Frames…

    I enjoyed reading your blog. What a great thing it is to be able to share information like this on the Internet….

Leave a Reply

Powered by WP Hashcash