[PHP] Hoe verkrijg ik de meta data van een flv movie?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • R0K13
  • Registratie: Januari 2003
  • Laatst online: 12-08 19:36
Hoi,

Ik probeer m.b.v php informatie te krijgen over de duur, videobitrate, audiobitrate en framerate van een FLV (flash) filmpje dat zich bevindt op een andere server dan waar de website op staat. De flv movies staan namelijk op een speciale video server terwijl de website zelf weer op een andere server staat. Tot nu toe is het me gelukt om de duur uit het bestand te halen (met hulp van google):

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  function GetFLVDuration($file){
        
          // get contents of a file into a string
            $contents = file_get_contents($file,FILE_BINARY,NULL,0);
            //
            
            if (strlen($contents) > 3){
              if (substr($contents,0,3) == "FLV"){
                $taglen = hexdec(bin2hex(substr($contents,strlen($contents)-3)));
                if (strlen($contents) > $taglen){
                  $duration = hexdec(bin2hex(substr($contents,strlen($contents)-$taglen,3)))  ;
                  return $duration;
                }
              }
            }
            
            return "OOPS";

        }


Hier wordt gebruik gemaakt van de metadata van het flv bestand dat er alsvolgt uitziet:

FLV õ onMetaData duration@*\(õwidth@†€height@y@ videodatarate@@ canSeekToEnd videocodecid@ audiodatarate@` audiocodecid@ framerate@9 creationdateThu Nov 15 10:29:33 2007 ¢/ÿû@K€ p. %

Het is me nu gelukt om de duration eruit te halen met wat hulp van voorbeelden op het internet. Maar ik begrijp niet helemaal wat er in deze functie gebeurt. Wat wordt er met $taglen uitgerekend? Hoe manipuleer ik deze code zodat ik ook de videodatarate eruit kan halen en audiodatarate etc?

Als iemand mij een beetje op weg kan helpen zou ik dat erg waarderen :):P

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Het lijkt me dat alles wat je weten moet hierin te lezen valt? :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • R0K13
  • Registratie: Januari 2003
  • Laatst online: 12-08 19:36
-NMe- schreef op zondag 13 juli 2008 @ 13:48:
Het lijkt me dat alles wat je weten moet hierin te lezen valt? :)
Bedankt voor deze hint. Dit is natuurlijk veel handiger dan een bestand proberen te parsen. Dat ik hier niet zelf aan gedacht heb |:(

In combinatie met de volgende link: http://www.half-serious.c...at/basic-types/index.html
moet ik nu een stuk verder komen hoop ik.

En ik was ff vergeten dat substr dus gewoon bytes inleest.

Nu heb ik dat document doorgelezen en de volgende functie gemaakt:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
function GetFLVInfo($file){
        
            //.. get contents of a file into a string
            //.. Remember that content is an array of bytes.. not bits!
            $contents = file_get_contents($file,FILE_BINARY,NULL,0);
            
            //.. string is binary. So it contains bits
            //.. With substr we read bytes. The first three bytes contain the file signature
            $signature = substr($contents,0,3);

            //.. Now lets get the FLV version
            $version = hexdec(bin2hex(substr($contents,3,1)));
            
            //.. Now get TypeFlags which are together 1 byte
            $TypeFlags = hexdec(bin2hex(substr($contents,4,1)));
            
            //.. Get the dataOffset which are 4 bytes long
            $DataOffset = hexdec(bin2hex(substr($contents,5,4)));
            
            // ***********************************************************************************
            //  The rest of the FLV file consists of tags. We are looking for the onMetaData tag
            // ***********************************************************************************
            
            //.. Assume the first tag contains the onMetaData
                    
            $PreviousTagSize        =   hexdec(bin2hex(substr($contents,9,4))); //.. Always 0
            $Tag_Type               =   hexdec(bin2hex(substr($contents,13,1)));
            $Tag_DataSize           =   hexdec(bin2hex(substr($contents,14,3)));
            $Tag_Timestamp          =   hexdec(bin2hex(substr($contents,17,3)));
            $Tag_TimestampExtended  =   hexdec(bin2hex(substr($contents,20,1)));
            $Tag_StreamID           =   hexdec(bin2hex(substr($contents,21,3)));
            $Tag_Data               =   substr($contents,24,$Tag_DataSize);
            
            //.. Now $Tag_data contains all the onMetaData. Remember that $Tag_data can be seen
            //.. as an array of bytes (=string)
            
            //if ($Tag_Data != 18) return false;        //.. Should be 18 otherwise its not the onMetaData
            
            //.. SCRIPTDATAOBJECT is what we got. Lets parse it
            $Object_NameStringLength    =   hexdec(bin2hex(substr($Tag_Data,0,2)));
            $Object_NameStringData      =   substr($Tag_Data,2,$Object_NameStringLength);
            
            $Object_DataType            =   hexdec(bin2hex(substr($Tag_Data,2+$Object_NameStringLength,1)));
            $Object_DataValue           =   hexdec(bin2hex(substr($Tag_Data,3+$Object_NameStringLength,8)));
            $Object_END                 =   hexdec(bin2hex(substr($Tag_Data,11+$Object_NameStringLength,3)));


        }


Helaas raak ik begeven moment de draad kwijt. Dat document van adobe is alles behalve overzichtelijk.

De variable $Tagdata bevat nu de onMetaData. Om precies te zijn omvat $Tagdata hetvolgende:

onMetaData duration@*\(õwidth@†€height@y@ videodatarate@@ canSeekToEnd videocodecid@ audiodatarate@` audiocodecid@ framerate@9 creationdateThu Nov 15 10:29:33 2007

Nu ga ik deze tagdata weer parsen volgens het document. Mijn $Object_NameStringData (zie ook document) heeft de volgende waarde:

onMetaData duration@*\(õwidth@†€height@y@ videodatarate@@ canSeekToEnd videocodecid@ audiodatarate@` audiocodecid@ framerate@9 creationdateThu Nov 15 10:29:33 2007

Terwijl ik toch iets had verwacht in de zin van ''onMetaData" of iets dergelijks. De volgende stap is nu om het datatype te bepalen en de data value van deze tag. Dit is wat ik vond:

$Object_DataType = 0
$Object_DataValue = 0

En $Object_END zou nu 9 moeten zijn (zie document). Helaas klopt dit ook niet. Waar gaat het nu precies fout. Moet ik nu de TagName ofzo gaan parsen om aan de duration, videodatarate etc te komen? En hoe moet ik dat doen ik kan nergens iets vinden over hoeveel bytes er worden gebruikt voor duration. Want een double (=8 bytes) volgens het document klopt niet. Als ik 8 bytes lees na duration krijg ik een onnozel groot getal. :P

[ Voor 76% gewijzigd door R0K13 op 13-07-2008 18:07 ]


Acties:
  • 0 Henk 'm!

  • ChessSpider
  • Registratie: Mei 2006
  • Laatst online: 01-08 19:01
Probeer eens met http://ffmpeg-php.sourceforge.net/ te spelen?

Acties:
  • 0 Henk 'm!

  • R0K13
  • Registratie: Januari 2003
  • Laatst online: 12-08 19:36
Ja dat ken ik maar ik kan hier helaas niet veel mee aangezien ik alleen upload en download rechten heb. Ik kan niets veranderen of toevoegen aan de installatie van php.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Overigens een kleine (offtopic) tip, open de file met fopen() en gebruik fgets() en eventueel fseek() om de bytes die je nodig hebt in te lezen, dan hoef je niet eerst die hele file in je geheugen te proppen ;)

Acties:
  • 0 Henk 'm!

  • R0K13
  • Registratie: Januari 2003
  • Laatst online: 12-08 19:36
Ik heb het al opgegeven om de hele flv te begrijpen. Nu probeer ik onMetaData zelf te decoderen. Dit is wat ik krijg:

onMetaData duration@*\(õwidth@†€height@y@ videodatarate@@ canSeekToEnd videocodecid@ audiodatarate@` audiocodecid@ framerate@9 creationdateThu Nov 15 10:29:33 2007

Nu weet ik dat de width van de video 720 is. Binair is dit 1011010000. De bits die zich tussen width en height bevinden zijn:

01000000 10000110 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Hier zit nergens 720 in???

Zelfde gedaan met framerate. Deze moet 25 zijn. Dus 11001. Als ik kijk naar de bits tussen framerate en creationdate vind ik:

01000000 00111001 00000000

Hier zit wel ergens 25 in alleen op een heel onlogische plek. Namelijk ergens midden in de tweede byte. Volgens het document van adobe (zie post hierboven) zou de framerate maar ook de width een DOUBLE (=8 byte) moeten zijn. Nu is de framerate 10 bytes en width maar 3 byte??

Ik doe iets helemaal fout of ik begrijp er niets van. Misschien beide maar zou iemand mij hiermee kunnen helpen :)

Acties:
  • 0 Henk 'm!

  • Noork
  • Registratie: Juni 2001
  • Niet online
Ik zit ook even te Googelen. Ik kwam id3 tag tegen. Eigenlijk bedoeld om de metadata van mp3's op te halen, maar er zit ook een flv module bij. Misschien kun je daar even naar kijken. Als je de code van die module doorneemt, kun je misschien achterhalen hoe je de resolutie eruit kan filteren.

Zie hier, http://getid3.sourceforge.net/

Acties:
  • 0 Henk 'm!

  • R0K13
  • Registratie: Januari 2003
  • Laatst online: 12-08 19:36
Het is me gelukt :).
Het probleem was dat de indeling van de onmetadata in een AMF formaat is. Verder werkt bij mij ftell, fseek niet omdat ik filmpjes open op een andere server. Gebruik makend van de AMF reader van getid3 en die omgebouwd zodat hij werkt zonder fseek en ftell en zonder de hele library nodig te hebben van getid3 is het me nu gelukt de metadata snel te kunnen halen uit een flv filmpje met alleen php. Bedankt voor alle hulp!
Pagina: 1