Autor Zpráva
TomasJ
Profil
Zdravím, zkoušel jsem hledat, ale neúspěšně...
Potřeboval bych zjistit z MP3 u mě na FTP délku (popř. i název a interpreta) MP3ky, ale nemám s tím žádné zkušenosti. Mohl by mi prosím někdo poradit, jak to zjistím? Četl jsem o tom, že délka se počítá nějak takto: velikost_souboru - delka_id3_tagu / bitrate ... jenže jak zjistím bitrate? Děkuji předem za odpovědi.
Darker
Profil
Pokud se nechceš trápit, použij tohle:
http://www.getid3.org/
$info = GetAllMP3info($filename);
$info['playtime_string'];
Tag může lhát, ten trik s přímým použitím délky souboru je možná spolehlivější.
margin
Profil *
TomasJ:
jak zjistím bitrate?
To nevím, ale mp3 soubr může mít proměnlivý (variabilní) bitrate, ale je fakt, že většina mp3 souborů mí konstantní bitrate.
Nezapomeň ve výpočtu na počet kanálů (mono/stereo).


Nezapomeň ve výpočtu na počet kanálů (mono/stereo).
To je vlastně nesmysl, pro výpočet to není důležité.
TomasJ
Profil
Darker:
Děkuji, ale to mi na "pouhé" zjištění délky MP3 souboru přijde moc rozsáhlé...
Stačilo by mi něco "stručnějšího" a nemusí to být hotové, pouze nějaké nakopnutí, jak zjistit bitrate a jak přesně by měl vypadat ten výpočet délky...
--------------------------------------------------------
Našel jsem výpočet přesně takto (filesize - id3v2_tagsize) / bitrate * 0.008
V podstatě celou stránku... http://www.zend.com/code/codex.php?ozid=160&single=1
Jen jestli to je použitelné? Děkuji...
--------------------------------------------------------
Tak... Kód jsem upravil (zkrátil / osekal) dle své libosti a funguje. Jen to není spolehlivé. Vymýšlí si. U některých skladeb řekne, že bitrate je 160, jinde je správně, a u 1 skladby mi dokonce zahlásil, že má bitrate jen 48 (místo 192) > délka je několikrát větší. Neznáte tedy někdo spolehlivější řešení? Délka je pro mě opravdu důležitá, bude spouštět časovač na přepínání hudby... Zde je kód k nahlédnutí:
<?
/* převzato a upraveno z http://www.zend.com/ */

    class MP3 {
        var $info_bitrates = array(
            1    =>    array(
                1    =>    array( 0 => 0, 16 => 32, 32 => 64, 48 => 96, 64 => 128, 80 => 160, 96 => 192, 112 => 224, 128 => 256, 144 => 288, 160 => 320, 176 => 352, 192 => 384, 208 => 416, 224 => 448, 240 => false),
                2    =>    array( 0 => 0, 16 => 32, 32 => 48, 48 => 56, 64 =>  64, 80 =>  80, 96 =>  96, 112 => 112, 128 => 128, 144 => 160, 160 => 192, 176 => 224, 192 => 256, 208 => 320, 224 => 384, 240 => false),
                3    =>    array( 0 => 0, 16 => 32, 32 => 40, 48 => 48, 64 =>  56, 80 =>  64, 96 =>  80, 112 =>  96, 128 => 112, 144 => 128, 160 => 160, 176 => 192, 192 => 224, 208 => 256, 224 => 320, 240 => false)
            ),
            2    =>    array(
                1    =>    array( 0 => 0, 16 => 32, 32 => 48, 48 => 56, 64 =>  64, 80 => 80, 96 => 96, 112 => 112, 128 => 128, 144 => 144, 160 => 160, 176 => 176, 192 => 192, 208 => 224, 224 => 256, 240 => false),
                2    =>    array( 0 => 0, 16 =>  8, 32 => 16, 48 => 24, 64 =>  32, 80 => 40, 96 => 48, 112 =>  56, 128 =>  64, 144 =>  80, 160 =>  96, 176 => 112, 192 => 128, 208 => 144, 224 => 160, 240 => false),
                3    =>    array( 0 => 0, 16 =>  8, 32 => 16, 48 => 24, 64 =>  32, 80 => 40, 96 => 48, 112 =>  56, 128 =>  64, 144 =>  80, 160 =>  96, 176 => 112, 192 => 128, 208 => 144, 224 => 160, 240 => false)
            )
        );
        var $file = "";
        var $fh = false;
        var $error = false;
        var $info = array();
        
        function mp3($file, $exitonerror=true) {
            if (file_exists($file)) {
                $this->file = $file;
                $this->fh = fopen($this->file,"r");
            } else {
                $this->error = "No such file";
                if ($exitonerror) $this->exitonerror();
            }
        }
        function exitonerror() {
            echo($this->error);
            exit;
        }

        function length() {
          $length = floor(filesize($this->file) / $this->info["bitrate"] * 0.008);
          $min = floor($length / 60);
          $min = strlen($min) == 1 ? "0$min" : $min;
          $sec = $length % 60;
          $sec = strlen($sec) == 1 ? "0$sec" : $sec;
          return("$min:$sec");
        }
        
        function get_info() {
            $second = $this->synchronize();
            $third = ord(fread($this->fh, 1));
            $versionId = ($second & 16) > 0 ? ( ($second & 8) > 0 ? 1 : 2 ) : ( ($second & 8) > 0 ? 0 : 2.5 );
            $layerId = ($second & 4) > 0 ? ( ($second & 2) > 0 ? 1 : 2 ) : ( ($second & 2) > 0 ? 3 : 0 );
            $explFilePath = explode("/",$this->file);
            $this->info["bitrate"]  = $this->info_bitrates[ $versionId ][ $layerId ][ ($third & 240) ];
            $this->info["length"]   = $this->length();
            $this->info["filename"] = $explFilePath[count($explFilePath)-1];
            $this->close();
            print_r($this->info);
        }
        
        function synchronize() {
            $finished = false;
            rewind($this->fh);
            while (!$finished) {
                $skip = ord(fread($this->fh, 1));
                while ($skip != 255 && !feof($this->fh)) {
                    $skip = ord(fread($this->fh, 1));
                }
                if (feof($this->fh)) {
                    $this->error("no info header found");
                    if ($exitonerror) $this->exitonerror();
                }
                $store = ord(fread($this->fh, 1));
                if ($store >= 225) {
                    $finished = true;
                } else if (feof($this->fh)) {
                    $this->error("no info header found");
                    if ($exitonerror) $this->exitonerror();
                }
            }
            return($store);
        }
        
        function close() {
            @fclose($this->fh);
        }
    }

$mp3 = new MP3('media/vipmusic/Player$104/Avicii_-_Level_two.mp3');
$mp3->get_info();
//Vypíše:
/*
Array ( [bitrate] => 48 [length] => 21:01 [filename] => Avicii_-_Level_two.mp3 ) 
-- u této je zrovna onen problém... :-(
*/
?>
TomasJ
Profil
Tak jsem nad tím bádal, ale na nic jsem nepřišel...
Existuje tedy 100% spolehlivé řešení jak zjistit délku nebo bitrate MP3?
TomasJ
Profil
Takže ještě tedy naposled oživuji vlákno a prosím o pomoc, jak zjistit 100% pravdivě bitrate u mp3?

Moderátor Alphard: Mažeme duplicitní vlákno, sem zálohuji ne zcela funkční kód autorem duplicitně uvedný. Přesto by ale mohl někomu pomoci.

Zdravím, již jsem tu jednou asi před necelým měsícem žádal o pomoc při zjištění délky MP3 ale nikdo nic nenapsal... Nakonec jsem výpočet zjistil, ale teď už jen potřebuji 100% spolehlivou funkci na zjištění bitrate mp3 skladeb. Semtam si totiž bitrate můj skript vymýšlí... V 7 z 10 případů je to správně, ale jelikož je zde kladen důraz na pravdivost tohoto údaje, potřebuji něco co to zjistí 100% pravdivě... Moje celá třída na zjištění délky je tato:
    class MP3 {
        var $info_bitrates = array(
            1    =>    array(
                1    =>    array( 0 => 0, 16 => 32, 32 => 64, 48 => 96, 64 => 128, 80 => 160, 96 => 192, 112 => 224, 128 => 256, 144 => 288, 160 => 320, 176 => 352, 192 => 384, 208 => 416, 224 => 448, 240 => false),
                2    =>    array( 0 => 0, 16 => 32, 32 => 48, 48 => 56, 64 =>  64, 80 =>  80, 96 =>  96, 112 => 112, 128 => 128, 144 => 160, 160 => 192, 176 => 224, 192 => 256, 208 => 320, 224 => 384, 240 => false),
                3    =>    array( 0 => 0, 16 => 32, 32 => 40, 48 => 48, 64 =>  56, 80 =>  64, 96 =>  80, 112 =>  96, 128 => 112, 144 => 128, 160 => 160, 176 => 192, 192 => 224, 208 => 256, 224 => 320, 240 => false)
            ),
            2    =>    array(
                1    =>    array( 0 => 0, 16 => 32, 32 => 48, 48 => 56, 64 =>  64, 80 => 80, 96 => 96, 112 => 112, 128 => 128, 144 => 144, 160 => 160, 176 => 176, 192 => 192, 208 => 224, 224 => 256, 240 => false),
                2    =>    array( 0 => 0, 16 =>  8, 32 => 16, 48 => 24, 64 =>  32, 80 => 40, 96 => 48, 112 =>  56, 128 =>  64, 144 =>  80, 160 =>  96, 176 => 112, 192 => 128, 208 => 144, 224 => 160, 240 => false),
                3    =>    array( 0 => 0, 16 =>  8, 32 => 16, 48 => 24, 64 =>  32, 80 => 40, 96 => 48, 112 =>  56, 128 =>  64, 144 =>  80, 160 =>  96, 176 => 112, 192 => 128, 208 => 144, 224 => 160, 240 => false)
            )
        );
        var $file = "";
        var $fh = false;
        var $error = false;
        var $info = array();
        
        function mp3($file, $exitonerror=true) {
            if (file_exists($file)) {
                $this->file = $file;
                $this->fh = fopen($this->file,"r");
            } else {
                $this->error = "No such file";
                if ($exitonerror) $this->exitonerror();
            }
        }
        function exitonerror() {
            echo($this->error);
            exit;
        }
        
        function get_info() {
            $second = $this->synchronize();
            $third = ord(fread($this->fh, 1));
            $versionId = ($second & 16) > 0 ? ( ($second & 8) > 0 ? 1 : 2 ) : ( ($second & 8) > 0 ? 0 : 2.5 );
            $layerId = ($second & 4) > 0 ? ( ($second & 2) > 0 ? 1 : 2 ) : ( ($second & 2) > 0 ? 3 : 0 );
            $bitrate  = $this->info_bitrates[ $versionId ][ $layerId ][ ($third & 240) ];
            $length   = floor(filesize($this->file) / $bitrate * 0.008);
            $this->close();
            return "$filename%$length";
        }
        
        function synchronize() {
            $finished = false;
            rewind($this->fh);
            while (!$finished) {
                $skip = ord(fread($this->fh, 1));
                while ($skip != 255 && !feof($this->fh)) {
                    $skip = ord(fread($this->fh, 1));
                }
                if (feof($this->fh)) {
                    $this->error("no info header found");
                    if ($exitonerror) $this->exitonerror();
                }
                $store = ord(fread($this->fh, 1));
                if ($store >= 225) {
                    $finished = true;
                } else if (feof($this->fh)) {
                    $this->error("no info header found");
                    if ($exitonerror) $this->exitonerror();
                }
            }
            return($store);
        }
        
        function close() {
            @fclose($this->fh);
        }
    }
Funkci jsem našel na internetu a trošku ji poupravil k obrazu svému, ale "chyba" v tom byla už předtím...
Na označených řádcích 36 a 36 nejspíš vzniká "chyba".
Pomůže mi někdo se zajištěním 100% pravdivého výsledku?
Amunak
Profil
TomasJ:
Můžeš si zkusit přečíst specifikaci toho formátu a podle ní sestrojit nějaký kód, který to zjistí. Nebude to ale zrovna primitivní.
TomasJ
Profil
Zdravím vás. Konečně jsem vyřešil bitrate MP3 a její následnou délku. Tento postup:
Na začátku volání metody get_info dejte před $second (druhý bajt) rewind($this->fh);.
To pak z metody synchronize odstraňte.
Udělejte cyklus for do 100. Do cyklu dejte vše kromě $length, $this->close(); a return .... V cyklu za $bitrate si ukládejte do pole (které si před cyklem vytvoříte) bitrate, který je zjištěn. ($rate[$i] = $bitrate;). Za cyklem si vytvořte nové pole a do něj si ukládejte, kolikrát se každý bitrate opakoval. Já to mám takto:
foreach($rates as $key=>$value){
  if(!$value) continue;
  $bitRate[$value]+=1;
}
Následně vypočítejte, který bitrate se nejvíckrát opakoval a ten uložte.
Z uloženého bitrate který se nejvíckrát opakoval, vypočtěte délku $length a máte to.
Výsledek je u mě zatím 100%... Z 31 skladeb mp3 bylo 31 vypočteno správně.

Napsal jsem to proto, že to někomu může pomoct při tvorbě nějaké hlavičky o mp3 :)

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0