# Infos aus Videodateien auslesen



## gbest5 (12. September 2005)

Hi,

 wie kann ich Informationen - wie z.B. die Auflösung - aus Videodateien wie AVI, WMV und MPEG auslesen? Ich habe bisher im www nur folgendes gefunden:

*AVI Header Format*

  AVI files contain a 56-byte header, starting at offset 32 within the file.





*offset* 

*size* 

*description* 

        0   

    4   

    time delay between frames in microseconds   

        4   

    4   

    data rate of AVI data   

        8   

    4   

    padding multiple size, typically 2048   

        12   

    4   

    parameter flags   

        16   

    4   

    number of video frames   

        20   

    4   

    number of preview frames   

        24   

    4   

    number of data streams (1 or 2)   

        28   

    4   

    suggested playback buffer size in bytes   

        32   

    4   

    width of video image in pixels   

        36   

    4   

    height of video image in pixels   

        40   

    4   

    time scale, typically 30   

        44   

    4   

    data rate (frame rate = data rate / time scale)   

        48   

    4   

    starting time, typically 0   

        52   

    4   

    size of AVI data chunk in time scale units  
 Also wie kann ich den Header auslesen? Googeln hat mich bisher zu nichts geführt.

 Gruß
 gbest5


----------



## MeinerEiner_80 (12. September 2005)

hi,
 mach das doch einfach so:


```
RandomAccessFile r = new RandomAccessFile("movie.avi");
 byte[] bytes = new byte[length] ;
 r.read(bytes,offset,lenght);
```
 
 für offset und lenght dann einfach die entsprechenden werte einsetzen, um höhe und breite zu bekommen..

 *grüssle*
 MeinerEiner


----------



## gbest5 (12. September 2005)

hab bisher mit:

```
File DieDatei = new File("....avi");
    FileInputStream DerDateiStrom  = new FileInputStream( DieDatei );
    byte[] DerHeaderUndMehr = new byte[88];
    DerDateiStrom.read( DerHeaderUndMehr );
    for ( int i = 0; i < 88; i++ ){
        System.out.print( (char)DerHeaderUndMehr[i] );
    }
```
 
    folgende Audgaben zu 3 verschiedenen Dateien erzeugt:

 RIFF?.AVI LISTH...hdrlavih8...@?..$?..........?...........?s......?...................
  RIFF.? .AVI LISTH...hdrlavih8...@?..R^..........D...........Q?......?...................
  RIFFnD?.AVI LIST?...hdrlavih8...@?..? ..........? ..........?t..`... ...................

  wobei aus . in der Eclipse-Konsole im Editor " " geworden ist.

 Manches sieht ja ganz gut aus. Es taucht zumindest die Bezeichnung AVI auf. Nur bekomme ich immer noch nicht die gewünschten Infos. Muss ich den Header anders auslesen?

    Gruß
    gbest5


----------



## MeinerEiner_80 (12. September 2005)

hi,
 ich hab das video test.avi eingelesen:

```
try {
 		RandomAccessFile r = new RandomAccessFile("test.avi", "r");
 		byte[] width = new byte[1] ;
 		byte[] height = new byte[1] ;
 		r.seek(64); 
 		r.read(width,0,1);
 		r.seek(68); 
 		r.read(height,0,1);
 		
 		 System.out.println(new BigInteger(width).intValue());
 		 System.out.println(new BigInteger(height).intValue());
 		}
 	catch (FileNotFoundException e) {
 		// TODO Auto-generated catch block
 		e.printStackTrace();
 	} catch (IOException e) {
 		// TODO Auto-generated catch block
 		e.printStackTrace();
 	}
```
 
 Und als ausgabe 120 und 113 erhalten, was genau der auflösung des videos entspricht. 
 Mit den anderen header daten würd ich genauso verfahren.. 
 *grüssle*
 MeinerEiner


----------



## gbest5 (13. September 2005)

moin,

 Danke erst einmal für Deine Hilfe. Ich habe Dein Code-Bsp. ausgeführt und er hat mir für 2 Videodateien mit Auflösungen von "512 x 384" bzw. "352 x 288" "0" und "-128" bzw. "96" und "32" ausgegeben. Müssen nicht eigentlich 4 Bytes gelesen werden? Ich habe damit schon mal experimentiert, bin aber auch nicht zu dem gewünschten Ergebnis gekommen.

 Gruß
 gbest5


----------



## MeinerEiner_80 (13. September 2005)

hi,
 das problem ist , dass mit einem byte ja nur maximal 256 dargestellt werden kann.
 daher bekommst du bei "352 x 288" auch "96" und "32" raus, wenn du nur das erste byte einliest
 würdest du das zweite byte einlesen, würdest du 1 und 1 erhalten,
 denn 1 *256 + 96 = 352 
 und 1*256 + 32 = 288


 bei "512 x 384" gibts einen Überlauf, und daher sollte man bei negativen zahlen 
 256+zahl rechnen
 würdest du hier die 2 bytes auslesen, würdest du 2 und 1 bekommen
 also rechnest du : 
 2*256 + 0= 512 und
 1*256 + 256+zahl = 384

 ich hoffe mal , dass stimmt so alles was ich mir da ausgedacht hab.
 Wahrscheints gibts ne elegantere methode das zu lösen.. aber was bessere fällt mir leider net ein..
 *greetz* MeinerEiner


----------



## gbest5 (15. September 2005)

Moin,

 Danke für die abermalige Hilfe. Hat mich auf jeden Fall weitergebracht. Ich verwende jetzt den ByteArrayInputStream. Der läuft auch nicht über.
 Und ich habe gemerkt bzw. erfahren, dass der Header einer AVI-Datei doch komplexer ist und nicht nur 56 Bytes umfasst.
 Eine Frage bleibt aber noch. Wie kann ich die Bitrate des Videos-Stream berechnen?
 Hab' versucht zu rechnen:

```
"Dateigröße"[bits] / "Dauer"[s] - "Audio-Bitrate"[bits/s]
```
 
 Ich bin Dabei aber immer nur nah (+,- 40 kb/s) an den von dem Programm GSpot errechneten Wert herangekommen.

 Gruß
 gbest5


----------



## kqe (28. Mai 2009)

Servus,

ist zwar schon etwas länger her ^^

aber kannst du mir zeigen wie du das mit dem ByteArrayInputStream gelöst hast?

Danke.


----------



## Der Heilige (8. November 2012)

Moin, 
auch wenn das hier schon erheblich älter ist hoffe ich doch das mir einer von euch sagen kann wie ich die Dauer/ die Länge des Filme aus einer .avi oder .vob auslesen kann .
Vielen Danke schon mal im voraus.
Gruß Der Heilige


----------



## sheel (8. November 2012)

Hi

http://www.fastgraph.com/help/avi_header_format.html

Datei zum binären Lesen öffnen.
Ab Byte 32 ist ein 4byte-int, wieviel Mikrosekunden zwischen Einzelbildern sind.
Ab Byte 48 ist ein 4byte-int, wieviel Einzelbildern es gibt.

Zeitliche Länge in Mikrosekunden = Bildanzahl*Bilddauer
Noch durch eine Million dividieren, sind Sekunden.


----------



## Der Heilige (9. November 2012)

Moin, erst mal vielen dank für die Hilfe.
Wenn ich das richtig versteh sollte das ganze so aussehen :


```
RandomAccessFile r = new RandomAccessFile("Titel.avi", "r"); 
        byte[] mikrosekunden = new byte[5] ;
        byte[] bilder = new byte[5] ;
        r.seek(32); 
        r.read(mikrosekunden ,0,4);
        r.seek(48); 
        r.read(bilder,0,4);
        System.out.println(new BigInteger(mikrosekunden).multiply(new BigInteger(bilder)).divide(new BigInteger("100000000")));// Die Dauer in Sekunden
```
Gruß Der Heilige


----------



## sheel (9. November 2012)

Was ist "width" und "height"?
Und warum BigInteger? Normale int reichen auch.


----------



## Der Heilige (9. November 2012)

Ups. Das habe ich wohl vergessen zu ändern  . Ich habe mich am Code von 
MeinerEiner_80 orientiert und habe die beiden Sachen vergessen  deswegen auch BigIneger.
Ansonsten ist das aber so richtig oder ?
Gruß Der Heilige


----------



## deepthroat (9. November 2012)

Hi.

Die Informationen in dem AVI Header kannst du eigentlich alle vergessen, da sie nicht verläßlich sind.

Siehe http://www.alexander-noe.com/video/documentation/avi.pdf

Alternativ könntest du z.B. die mediainfo (http://mediainfo.sourceforge.net/de) Bibliothek verwenden. Der PS3Mediaserver bindet diese auch ein um an Meta Informationen zu kommen. Dabei wird JNA benutzt um die _native _Bibliothek zur Laufzeit zu laden. Siehe http://code.google.com/p/ps3mediase...ediaserver/net/pms/dlna/MediaInfo.java?r=1110


----------

