Update (Dec 20, 2008): The AMF0Parser library has been updated to better handle broken AMF0 packets. The FLVInfo2 library PHPDoc has been updated.

Update (Aug 15, 2008): The AMF0Parser library has been updated to support the Date type in the metas, added among others by the “inlet media FLVTool2″ tool.

Update (Jun 11, 2009): The project has been moved to Google Code. MP4Info, an F4V file (or more genericaly MP4 file) class is also available: check out blog post and project at Google Code.

If you’ve done Flash banners or micro-sites that embed video with cue points for synchronization before, you know that it’s a pain in the arse. There doesn’t seem to be any tool around to modify the damn points once the file is encoded, so you’ve got to re-encode the file over and over to have your things synced correctly.

If you’ve tried to reverse engineer the FLV format before, you know that it’s a pain in the arse as well. The AMF0 format is anything but intuitive, and the documentation has been lacking for a long long time — although there’s apparently an SDK now. Luckily, there was OSFlash, and SabreAMF and AMFPHP that could be used as a documentation source.

If you recognize yourself, this might be your lucky day. After many hours of trial and error, I’ve finally been able to reverse engineer it, and to build a library that extract essential FLV information, reads the Meta, and allows you to write them back — including the cue points.

First, you’ll need to FLVInfo2 and the AMF0Parser libraries, below. The FLVInfo2 library has three main functions:

  • getInfo, which returns information gotten from analyzing the FLV file and it’s meta. Frame rate, bit rate, audio/video codec, width, height, etc.
    (
        [signature] => 1
        [hasVideo] => 1
        [hasAudio] => 1
        [minimalFlashVersion] => 8
         => stdClass Object
            (
                [codec] => 4
                [width] => 320
                [height] => 240
                [keyframeRatio] => 0.0180537208278
                [keyframeEvery] => 55.3902439024
                [fps] => 15
                [bitrate] => 448
                [codecStr] => On2 VP6
            )
    
         => stdClass Object
            (
                [codec] => 2
                [frequency] => 22
                [depth] => 16
                [channels] => 2
                [bitrate] => 48
                [codecStr] => MP3
            )
    )
  • getMeta, which returns the meta data, and the cue points
    Array
    (
        [metas] => Array
            (
                [0] => Array
                    (
                        [0] => onMetaData
                        [1] => Array
                            (
                                [duration] => 151.46
                                [width] => 320
                                [height] => 240
                                [videodatarate] => 500
                                [canSeekToEnd] => 1
                                [videocodecid] => 4
                                [audiodatarate] => 48
                                [audiocodecid] => 2
                                [framerate] => 15
                                [creationdate] => Tue Jun 17 13:06:15 2008
                                [Encoded_By] => orangetango Video Encoder
                                [Encoded_With] => orangetango Video Encoder
                                [metadatacreator] => orangetango FLV meta data writer
                            )
                    )
            )
        [cuepoints] => Array
            (
                [0] => Array
                    (
                        [0] => onCuePoint
                        [1] => Array
                            (
                                [name] => name1
                                [time] => 4.41
                                [type] => event
                            )
                    )
                [1] => Array
                    (
                        [0] => onCuePoint
                        [1] => Array
                            (
                                [name] => name1_end
                                [time] => 6.7
                                [type] => event
                            )
                    )
            )
    )
  • rewriteMeta, which inputs an FLV file, meta data and cue points, and outputs a new FLV file.

As a practical example, you find the rewriteTagsForFile function in the example.php file, that rewrites the meta data and gets the cue points from a FLVCoreCuePoints XML file.

PHP Source flvinfo2.php (20k , updated Dec 20, 2008)

PHP Source AMF0Parser.php (16k, updated Dec 20, 2008)

PHP Source example.php (12k)

Flash Video logo found on Wikipedia.


If you like this article, leaving a comment, tweeting ofr liking it is always appreciated.

category Flash, PHP Friday 4 July 2008 Comments (11)

11 Responses :

  1. Mario H.

    Hi Tommy,
    it’s great, you’ve developed this scripts. I was thinking about programming a script like this too.
    But could you please upload/link flvinfo2.php too?
    Thx
    Mario H.

  2. tlacroix

    Hi Mario,

    Thanks for noticing, I made a mistake when created the link into the file. It has now been corrected.

    You’ll find the code here:
    http://www.tommylacroix.com/wp-content/uploads/2008/07/flvinfo2.phps

    Cheers,

    Tommy.

  3. Mario H.

    Thank you very much, also for your very quick reply! Your scripts/libraries are working great.
    You saved me a lot of work.

  4. David

    Very nice work, just what i was needing, thanks! :)

  5. Erick

    This is a powerful script.
    I need help with something, I have uploaded videos large (200MB) in flv format to my host, with your script I am very interested in the meta info but I get an error

    Allowed memory size of 33554432 bytes exhausted (tried to allocate 128 bytes) in /home2/eternopa/public_html/churchlivingword.com/broadcast/libraries/flvinfo2.phps on line 146

    I would be very grateful if you indicate me if I must change something in the script or something else to get the information.

    I need the info: height and width

    Regards

  6. michael

    nice work.

    however i cannot get it to completely work.
    the cue points in my output flv file from this script cannot be read by flash player while the input flv that contained embedded cue points is parsed fine.
    looking at the raw data seems to show that the output flv is missing the cuepoint metadata at the beginning of file contents.

    interested in seeing my example?

    thanks.

  7. Rodrigo Polo

    How can this be used as a an injection tool like flvtool2?

  8. Samuele

    Very nice work !
    Wich version of LGPL license?
    I hope version 2 becouse version 3 is too restrictive

  9. Samuele

    One of my .flv video file throw this error:

    Fatal error: Uncaught exception ‘Exception’ with message ‘Unhandled AMF type: Date (0B)’ in C:\wamp\www\test\amf0parser.php:185
    Stack trace:
    #0 C:\wamp\www\test\amf0parser.php(319): AMF0Parser->readPacket()
    #1 C:\wamp\www\test\amf0parser.php(368): AMF0Parser->readObject()
    #2 C:\wamp\www\test\amf0parser.php(176): AMF0Parser->readMixedArray()
    #3 C:\wamp\www\test\amf0parser.php(137): AMF0Parser->readPacket()
    #4 C:\wamp\www\test\flvinfo2.php(276): AMF0Parser->readAllPackets(‘???onMetaData??…’)
    #5 C:\wamp\www\test\example1.php(7): Flvinfo2->getInfo(‘example.flv’, true, true)
    #6 {main}
    thrown in C:\wamp\www\test\amf0parser.php on line 185

    my code is a simpler:
    getInfo(‘example.flv’,true,true);
    var_export($info);

    ?>

    I also checked with ultraedit the header of my flv file and it is correct, it start with FLV

  10. tlacroix

    This issue has been fixed, and the project has been moved to Google Code at http://code.google.com/p/php-flvinfo/

  11. Alexander Cronstrom

    Hi Tommy,

    great script!

    But I had some:

    Warning: fread() [function.fread]: Length parameter must be greater than 0 in C:\xampp\htdocs\php-flvinfo\libraries\flvinfo2.php on line 514, line 656, line 158

    Warning: unpack() [function.unpack]: Type C: not enough input, need 1, have 0 in C:\xampp\htdocs\php-flvinfo\libraries\flvinfo2.php on line 242

    I tried several ways to avoid this but could not get a solution, I did a dirty fix like:

    if (min($tagInfo['size'],16384) > 0) $body = fread($f, min($tagInfo['size'],16384));

    …and it worked! (?)

    So my question: Have I missed something here (or regarding metadata) doinf this quick fix?

    Happy Holidays
    Alexander

Leave a Reply