php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > PHP Developer Forum
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


PHP Developer Forum Hier habt ihr die Möglichkeit, eure Skriptprobleme mit anderen Anwendern zu diskutieren. Seid so fair und beantwortet auch Fragen von anderen Anwendern. Dieses Forum ist sowohl für ANFÄNGER als auch für PHP-Profis! Fragen zu Laravel, YII oder anderen PHP-Frameworks.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 30-04-2008, 09:17
naitSirch
 Newbie
Links : Onlinestatus : naitSirch ist offline
Registriert seit: Apr 2008
Ort: Paderborn
Beiträge: 7
naitSirch ist zur Zeit noch ein unbeschriebenes Blatt
Standard Bitrate und Länge eines MP3s bestimmen

Hallo,

Ich bin dabei eine Klasse zu basteln, die die Bitrate und die Länge und eines MP3s bestimmen kann.

Allerdings scheint das nicht einwandfrei funktionieren zu wollen.

Die Vorgehensweise:
Der komplette Inhalt der Datei wird als String eingelesen.
Danach per

explode(chr(255),$string);

geteilt, weil ein Frame ja mit "11111111111" Bits beginnen muss.
Danach überprüfe ich mit einer Schleife wirklich jedes Frame, indem ich die MPEG Audio version und die Layer description bestimme und dadurch dann die Bitrate.

Die Bitrate eines MP3s, welches mit lame konstant mit 128kbit/s enkodiert wurde, hat jedoch folgende "Bitrate-Verteilung":

Zitat:
Array
(
[128] => 621
[bad] => 30
[32] => 34
[256] => 24
[56] => 24
[free] => 63
[160] => 26
[416] => 5
[224] => 21
[320] => 24
[112] => 30
[48] => 19
[80] => 24
[96] => 29
[288] => 8
[384] => 12
[40] => 15
[144] => 8
[64] => 19
[8] => 7
[352] => 7
[192] => 13
[24] => 7
[16] => 9
[448] => 4
)
Also die meisten Frames sind wirklich mit 128 kbits/s enkodiert, aber es gibt auch viele andere Bitraten.

Jetzt meine Frage: ist das normal? Eigentlich nicht, oder? Weil ich ja konstant kodiert habe. Also mit dem Befehl:
Code:
# C:\Programme\lame\lame.exe -b 128 Y:\supercops.wav Y:\supercops_128bit.mp3
// EDIT:

Das gleiche habe ich auch mit 32 kbit und 256 kbit enkodierten MP3s ausprobiert und das Ergebnis war immer ähnlich. Also mein Code scheint zumindest halbwegs richtig zu sein

Geändert von naitSirch (30-04-2008 um 09:21 Uhr)
Mit Zitat antworten
  #2 (permalink)  
Alt 01-05-2008, 13:55
frodenius
 Registrierter Benutzer
Links : Onlinestatus : frodenius ist offline
Registriert seit: Sep 2006
Ort: Germany, Frankfurt/Main
Beiträge: 156
frodenius ist zur Zeit noch ein unbeschriebenes Blatt
Standard

11 bits mit 1 sind nicht chr(255).. chr gibt einen 8-bit wert zurück.
also da mit strings zu arbeiten ist keine gute idee.

[edit]
http://www.fh-jena.de/contrib/fb/et/.../mp3_2_res.htm

also ich würd ja binary öffnen und ganze header lesen.
__________________
blllubb

Geändert von frodenius (01-05-2008 um 14:13 Uhr)
Mit Zitat antworten
  #3 (permalink)  
Alt 03-05-2008, 11:58
naitSirch
 Newbie
Links : Onlinestatus : naitSirch ist offline
Registriert seit: Apr 2008
Ort: Paderborn
Beiträge: 7
naitSirch ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Syncword (12 Bit) ID (1 Bit): Offiziell ist ID-Signatur nur ein Bit groß, um die verwendete MPEG-Version zu kennzeichnen. In der Urfassung steht der Wert 1 für MPEG 1 und der Wert 0 für MPEG 2. Mit dem inoffiziellen Standard MPEG 2.5 reicht ein Bit als Kennung jedoch nicht mehr aus. Anwendungen, die diesen Standard bereits unterstützen, verwenden das zwölfte Bit des Syncwords als zusätzliche MPEG-ID. Ist dieses auf 0 gesetzt, steht dies für MPEG 2.5. Standardmäßig sind alle Bits des Syncwords gesetzt.
Das ist aus dem Link, den Du mir geschickt hast.
Das Syncword ist ja 11 Bits lang. Und unter "Standardmäßig sind alle Bits des Syncwords gesetzt" verstehe ich eigentlich, dass die alle den Wert 1 tragen. Wobei bei der Version 2.5 dürften ja dann nur die ersten 10 Bits auf 1 gesetzt sein, oder?

Aber das komische ist ja immernoc, dass mein Script ja zumindest teilweise korrekt arbeitet. Vielleicht haben die falschen Werte etwas damit zu tun, dass die 2.5er MPEG Version falsch interpretiert wird?!

Aber warum meinst Du, dass mit Strings zu arbeiten keine gute Idee ist?
Klar chr(255) gibt einen String zurueck, aber ich lese dann ja auch noch die nächsten drei Bytes ein, und wandle die mit decbin in den Binärwert um. Da dann natürlich auch sowas wie "1001" 'rauskommen kann, habe ich eine Funktion, die dann vorne so viele Nullen drann hängt, bis es 8 Bits sind.
Somit erhalte ich dann immer 32 Bits (also den Frame-Header) und daraus hole ich mir dann die benötigten Informationen.

Aber was genau meinst Du mit
Zitat:
also ich würd ja binary öffnen und ganze header lesen.
Wie funktioniert das denn? Ich habe bisher noch nie wirklich etwas mit Binären Dateien gemacht...
Mit Zitat antworten
  #4 (permalink)  
Alt 03-05-2008, 15:32
tontechniker
 PHP Senior
Links : Onlinestatus : tontechniker ist offline
Registriert seit: Jul 2005
Beiträge: 1.972
tontechniker ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Wie funktioniert das denn? Ich habe bisher noch nie wirklich etwas mit Binären Dateien gemacht...
fread
__________________
Die Regeln | rtfm | register_globals | strings | SQL-Injections | []
Mit Zitat antworten
  #5 (permalink)  
Alt 03-05-2008, 18:16
frodenius
 Registrierter Benutzer
Links : Onlinestatus : frodenius ist offline
Registriert seit: Sep 2006
Ort: Germany, Frankfurt/Main
Beiträge: 156
frodenius ist zur Zeit noch ein unbeschriebenes Blatt
Standard

nein also eigentlich ist das syncword 12 bit lang. für mpeg 2.5 braucht man eben nur das 12te bit auf 0. dh 11 bits sind immer gesetzt.
das mit den strings machst du wahrscheinlich per file_get_contents(), oder?
das problem ist eben das strings in php aus 8 bit zeichen bestehen. und woher willst du wissen dass es in den ton-daten kein byte gibt, bei dem auch alle bits gesetzt sind?
das ist sogar sehr wahrscheinlich.

auf php-classes.org gibts einige klassen um mp3 inkl. id3 tags zu parsen. (als inspriration)
__________________
blllubb

Geändert von frodenius (03-05-2008 um 18:18 Uhr)
Mit Zitat antworten
  #6 (permalink)  
Alt 06-05-2008, 10:46
naitSirch
 Newbie
Links : Onlinestatus : naitSirch ist offline
Registriert seit: Apr 2008
Ort: Paderborn
Beiträge: 7
naitSirch ist zur Zeit noch ein unbeschriebenes Blatt
Standard

ich sehe grad, dass ich die Datei doch mit
PHP-Code:
$fp fopen($path,"rb");
$file fread($fp,filesize($path)); 
einlese. Dann ist das ja "binär".

Wenn Ihr wollt, könnt Ihr Euch ja mal den Code der Funktion ansehen, die die Bitrate und ähnliches bestimmt.

PHP-Code:
$zerlegt explode(chr(255),$this->file);
        
for(
$pos=0$pos<sizeof($zerlegt); $pos++) {
            
    
$frame chr(255).$zerlegt[$pos]; // hier wird das chr(255) wieder drann gehängt, was durch explode() "verloren gegangen" ist
           
    
$char1 substr($frame,0,1);
    
$byte[0] = $this->decbinFill(ord($char1),8); // hier steht sowas wie: "11111111"
           
    
$char2 substr($frame,1,1);
    
$byte[1] = $this->decbinFill(ord($char2),8); // hier steht sowas wie: "00100111"
           
    
$char3 substr($frame,2,1);
    
$byte[2] = $this->decbinFill(ord($char3),8); // hier steht sowas wie: "00100111"
           
    
$char4 substr($frame,3,1);
    
$byte[3] = $this->decbinFill(ord($char4),8); // hier steht sowas wie: "00100111"
            
    
$header implode("",$byte); // fügt die vier Bytes ohne Trennzeichen zusammen, so dass der Header genau 32 Bits lang ist
            
    
if(substr($header,0,11) == "11111111111" ) { // hier wird das Syncword überprüft
      
$version =     $this->versionsubstr($header,11,2) ];
      
$layer =     $this->layersubstr($header,13,2) ];
           
      if(
$version == $layer == 1)
         
$b 0;
      else if(
$version == $layer == 2)
            
$b 1;
      else if(
$version == $layer == 3)
               
$b 2;
      else if(
$version == $layer == 1)
              
$b 3;
      else if(
$version == & ( $layer == $layer == ) )
               
$b 4;
                   
      
$bitrate $this->bitratesubstr($header,16,4) ][$b];
      
$ergebnis[$bitrate]++;
    }

Die Funktion decbinFill(Dezimalzahl, erwünschte Länge)
PHP-Code:
    function decbinFill($dec,$length=0) {
        
$str decbin($dec);
        
$nulls $length-strlen($str);
        if(
$nulls>0) {
            for(
$i=0;$i<$nulls;$i++) {
                
$str '0'.$str;
            }
        }
        return 
$str;
    } 

Geändert von naitSirch (06-05-2008 um 10:48 Uhr)
Mit Zitat antworten
  #7 (permalink)  
Alt 07-05-2008, 22:07
frodenius
 Registrierter Benutzer
Links : Onlinestatus : frodenius ist offline
Registriert seit: Sep 2006
Ort: Germany, Frankfurt/Main
Beiträge: 156
frodenius ist zur Zeit noch ein unbeschriebenes Blatt
Standard

also wie gesagt:
du kannst dir nicht sicher sein dass 8 gesetzte bits in folge nur in den syncwords der frame-header vorkommen.
und außerdem halten sich die frames nicht an bytes sondern bits. dh die 11 bits könnten auch zu 5 und 6 in zwei bytes stecken, und der header wird gar nicht erkannt.
__________________
blllubb
Mit Zitat antworten
  #8 (permalink)  
Alt 19-05-2008, 13:13
naitSirch
 Newbie
Links : Onlinestatus : naitSirch ist offline
Registriert seit: Apr 2008
Ort: Paderborn
Beiträge: 7
naitSirch ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Original geschrieben von frodenius
also wie gesagt:
du kannst dir nicht sicher sein dass 8 gesetzte bits in folge nur in den syncwords der frame-header vorkommen.
Das stimmt. Aber wie testen das andere Programme?

Zitat:
Original geschrieben von frodenius
und außerdem halten sich die frames nicht an bytes sondern bits. dh die 11 bits könnten auch zu 5 und 6 in zwei bytes stecken, und der header wird gar nicht erkannt.
Also eigentlich kann das nicht sein, weil ich ja mit der Funktion debinFill() arbeite. Wenn bei einem Byte nur 5 bits gesetzt wird, wird es in 00011111 umgewandelt.

Wenn also zwei Bytes, einmal mit 5 und einmal mit 6 gesetzten Bits, hintereinander stehen, würde das so aussehen:
0001111100111111
es würde also nicht als syncword interpretiert werden. Zumindest, wenn ich das richtig verstehe...
Mit Zitat antworten
  #9 (permalink)  
Alt 19-05-2008, 22:31
frodenius
 Registrierter Benutzer
Links : Onlinestatus : frodenius ist offline
Registriert seit: Sep 2006
Ort: Germany, Frankfurt/Main
Beiträge: 156
frodenius ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Zitat:
Also eigtl kann das nicht sein, weil..
[...]
es würde also nicht als syncword iterpretiert werden. ...
...
ja eben doch wohl, nein, doch, nein, DOCH!
ja klar. wird nicht als syncword erkannt -> kein header erkannt.

andere programme lesen die datei als bitstream.

ich würde (wie gesagt) die header als ganzes analysieren.
erst mal die datei mit file_get_contents einlesen und dann erst mal gucken ob TAG also erstes steht, dann die tags lesen. wenn jetzt die frames anfangen, interpretierst du den ersten header und wenn da eine konstante bitrate drin steht, dann wird das auch im rest der datei so sein. wenn die bitrate variabel ist wirst du bei jedem frame seine größe berechnen müssen, um zum nächsten zu finden.
__________________
blllubb
Mit Zitat antworten
  #10 (permalink)  
Alt 26-05-2008, 15:27
naitSirch
 Newbie
Links : Onlinestatus : naitSirch ist offline
Registriert seit: Apr 2008
Ort: Paderborn
Beiträge: 7
naitSirch ist zur Zeit noch ein unbeschriebenes Blatt
Standard

Achso. Ich glaub' jetzt hat es klick gemacht
Wenn z.B. 2 Bytes hintereinanderstehen mit:
00111111,11111000

In dem Fall würde mein Script das gar nicht beachten, weil es ja mit "00" anfängt...
Okay, daran werd' ich arbeiten. Vielen Dank für die Hilfe frodenius
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 22:31 Uhr.