Felix Riesterer: FLV - Abmessungen und Aspect Ratio

Beitrag lesen

Liebe Mitleser,

ich möchte serverseitig die Abmesungen eines Videos im FLV-Format bestimmen. Ingo Turski hatte mir dazu schon einen sehr guten Tipp gegeben (Archivpost), mit dem ich in den meisten Fällen auch sehr gut zurecht komme. Meine Lösung (falls es wer mal wissen wollte):

function flv_metadaten ($dateipfad) {  
    $f = fopen($dateipfad, 'r');  
    $dat = '';  
    while (substr_count($dat, 'width') < 1 && substr_count($dat, 'height') < 1) {  
        $dat .= fread($f, 100);  
    }  
    $dat .= fread($f, 64);  
    fclose($f);  
  
    $meta_daten = array(  
        'width' => ord(substr($dat, strpos($dat, 'width') + 7, 1)),  
        'height' => ord(substr($dat, strpos($dat, 'height') + 8, 1))  
    );  
  
    // Dimensionen dekodieren  
    foreach ($meta_daten as $key => $val) {  
        // Wertigkeit der Angaben ermitteln (Danke an Ingo Turski http://forum.de.selfhtml.org/archiv/2008/8/t176089/#m1158126)  
        $wert = pow(2, ($val & 0xf0) /16 - 5) * 64  
            + pow(2, ($val & 0xf0) /16 - 5) * 4 * ($val & 0x0f);  
  
        $meta_daten[$key] = $wert;  
    }  
  
    $metadaten['filename'] = preg_replace('~^(.*?/)?~', '', $dateipfad);  
    return $meta_daten;  
}

Obige Lösung hat leider einen kleinen Schönheitsfehler. Sie liefert nur dann korrekte Werte, wenn das Seitenverhältnis (aspect ratio) 4:3 beträgt, und dann auch nicht immer. Bei Filmen im Verhältnis von 16:9 werden die ermittelten Werte immer zu klein. Dazu ein Beispiel:

Video 1:
echte Abmessungen 600x348 (~16:9)
ermittelte Abmessungen 576x336

Video 2:
korrekt ermittelte Abmessungen 512x384 (4:3)

Die echten Abmessungen bestätigt mir mein Mediaplayer. Da Ingos Rechenbeispiel anscheinend nicht immer gilt, habe ich versucht, Hinweise zu finden, die mir ermöglichen, diese "Abweichungen" zu kompensieren.

Mein erster Schritt war, nachzusehen, ob denn nicht ein weiteres Byte Aufschluss darüber geben könnte, um welches Seitenverhältnis es sich hier handelt. Und da fand ich bei Video 1 als "Folgebyte" jeweils nach dem besagten Byte für den x- oder y-Wert _keine_ Null (0x00) vor, sondern 192 (0xC0). Also habe ich mich zu Adobe aufgemacht, um irgendwelche Spezifikationen zu finden, in denen sich mein Verdacht bestätigen ließe, dass dieses weitere Byte etwas mit dem Seitenverhältnis zu tun haben könnte.

Die Specs habe ich zwar gefunden, aber mein Anliegen wird darin entweder nicht besprochen, was mich sehr verwundern würde, oder ich habe es schlicht und ergreifend nicht geschnallt und deswegen übersehen (was mich weniger wundern würde).

Mein nächste Schritt war, bei Youtube nach 16:9-Videos zu suchen, um meinen Verdacht mit ein paar Beispielen zu überprüfen. Hier das Ergebnis:

ein 16:9-Youtube-Video:
echte Abmessungen 456x240 (~16:9)
ermittelte Abmessungen 448x240

  • nach "width" steht 0x00 0x40 0x7c 0x80
  • nach "height" steht 0x00 0x40 0x6e 0x00

Zum Vergleich mein 16:9-Video:
echte Abmessungen 600x348 (~16:9)
ermittelte Abmessungen 576x336

  • nach "width" steht 0x00 0x40 0x82 0xc0
  • nach "height" steht 0x00 0x40 0x75 0xc0

Um die Dinge nun noch weiter zu verkomplizieren, habe ich ein viertes (eigenes) Video mit folgenden Werten:
echte Abmessungen 400x300 (4:3!!)
ermittelte Abmessungen 400x288 (???)

  • nach "width" steht 0x00 0x40 0x79 0x00
  • nach "height" steht 0x00 0x40 0x72 0xc0

Ich komme nicht darauf, wie das alles miteinander zusammenhängt. Wer kann mir weiterhelfen und sagen, wie ich verlässlich die tatsächlichen Abmessungen (aspect ratio) eines FLV serverseitig ermittle?

Liebe Grüße,

Felix Riesterer.

--
ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)