Frage
Was ist der einfachste Weg, um die Länge (in Sekunden) eine bestimmten MP3-Datei, ohne Verwendung außerhalb Bibliotheken , um zu bestimmen? (Python-Quelle sehr geschätzt)
Lösung
Sie können mit pymad . Es ist eine externe Bibliothek, fällt jedoch nicht für die Not Invented Here Falle. Ein besonderer Grund Sie wollen keine externen Bibliotheken?
import mad
mf = mad.MadFile("foo.mp3")
track_length_in_milliseconds = mf.total_time()
hier .
-
Wenn Sie wirklich nicht wollen, um eine externe Bibliothek verwenden, schauen Sie und Scheck sie heraus, wie er es getan. . Achtung: es ist kompliziert
Andere Tipps
Für Google Anhänger willen, hier sind ein paar externen Libs:
mpg321 -t
ffmpeg -i
midentify (MPlayer im Grunde) finden Sie unter Mit mplayer Länge zu bestimmen von Audio / Video-Datei
mencoder (es ungültig params übergeben, wird eine Fehlermeldung ausgespuckt, aber sie auch Informationen in Frage, ab $ mencoder inputfile.mp3 -o Fälschung auf die Datei geben)
http://mediainfo.sourceforge.net/en
exiftool
das Linux-Befehl "file"
mp3info
sox
Refs: https://superuser.com/questions/36871/linux-command- Line-Dienstprogramm ermittelnden-mp3-Bitrate
http://www.ruby-forum.com/topic/139468
(so dass dies ein Wiki für andere hinzuzufügen).
und Libs: .net: NAudio, java: JLayer, c: libmad
Cheers!
Einfache, Parse MP3 binären Blob etwas, in Python berechnen
Das klingt wie eine ziemlich große Herausforderung. Ich weiß nicht, Python, aber hier ist einige Code, den ich aus einem anderen Programm Refactoring habe ich einmal versucht, zu schreiben.
Hinweis: Es ist in C ++ (sorry, es ist, was ich habe). Auch wie er ist, wird es nur mit konstanter Bitrate MPEG 1 Audio Layer 3-Dateien verarbeiten. Die sollte deckt die meisten, aber ich kann keine Gewähr für diese Arbeiten in allen Situationen machen. Hoffentlich tut, was Sie wollen, und hoffentlich es in Python Refactoring ist einfacher, als es von Grund auf zu tun.
// determines the duration, in seconds, of an MP3;
// assumes MPEG 1 (not 2 or 2.5) Audio Layer 3 (not 1 or 2)
// constant bit rate (not variable)
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
//Bitrates, assuming MPEG 1 Audio Layer 3
const int bitrates[16] = {
0, 32000, 40000, 48000, 56000, 64000, 80000, 96000,
112000, 128000, 160000, 192000, 224000, 256000, 320000, 0
};
//Intel processors are little-endian;
//search Google or see: http://en.wikipedia.org/wiki/Endian
int reverse(int i)
{
int toReturn = 0;
toReturn |= ((i & 0x000000FF) << 24);
toReturn |= ((i & 0x0000FF00) << 8);
toReturn |= ((i & 0x00FF0000) >> 8);
toReturn |= ((i & 0xFF000000) >> 24);
return toReturn;
}
//In short, data in ID3v2 tags are stored as
//"syncsafe integers". This is so the tag info
//isn't mistaken for audio data, and attempted to
//be "played". For more info, have fun Googling it.
int syncsafe(int i)
{
int toReturn = 0;
toReturn |= ((i & 0x7F000000) >> 24);
toReturn |= ((i & 0x007F0000) >> 9);
toReturn |= ((i & 0x00007F00) << 6);
toReturn |= ((i & 0x0000007F) << 21);
return toReturn;
}
//How much room does ID3 version 1 tag info
//take up at the end of this file (if any)?
int id3v1size(ifstream& infile)
{
streampos savePos = infile.tellg();
//get to 128 bytes from file end
infile.seekg(0, ios::end);
streampos length = infile.tellg() - (streampos)128;
infile.seekg(length);
int size;
char buffer[3] = {0};
infile.read(buffer, 3);
if( buffer[0] == 'T' && buffer[1] == 'A' && buffer[2] == 'G' )
size = 128; //found tag data
else
size = 0; //nothing there
infile.seekg(savePos);
return size;
}
//how much room does ID3 version 2 tag info
//take up at the beginning of this file (if any)
int id3v2size(ifstream& infile)
{
streampos savePos = infile.tellg();
infile.seekg(0, ios::beg);
char buffer[6] = {0};
infile.read(buffer, 6);
if( buffer[0] != 'I' || buffer[1] != 'D' || buffer[2] != '3' )
{
//no tag data
infile.seekg(savePos);
return 0;
}
int size = 0;
infile.read(reinterpret_cast<char*>(&size), sizeof(size));
size = syncsafe(size);
infile.seekg(savePos);
//"size" doesn't include the 10 byte ID3v2 header
return size + 10;
}
int main(int argCount, char* argValues[])
{
//you'll have to change this
ifstream infile("C:/Music/Bush - Comedown.mp3", ios::binary);
if(!infile.is_open())
{
infile.close();
cout << "Error opening file" << endl;
system("PAUSE");
return 0;
}
//determine beginning and end of primary frame data (not ID3 tags)
infile.seekg(0, ios::end);
streampos dataEnd = infile.tellg();
infile.seekg(0, ios::beg);
streampos dataBegin = 0;
dataEnd -= id3v1size(infile);
dataBegin += id3v2size(infile);
infile.seekg(dataBegin,ios::beg);
//determine bitrate based on header for first frame of audio data
int headerBytes = 0;
infile.read(reinterpret_cast<char*>(&headerBytes),sizeof(headerBytes));
headerBytes = reverse(headerBytes);
int bitrate = bitrates[(int)((headerBytes >> 12) & 0xF)];
//calculate duration, in seconds
int duration = (dataEnd - dataBegin)/(bitrate/8);
infile.close();
//print duration in minutes : seconds
cout << duration/60 << ":" << duration%60 << endl;
system("PAUSE");
return 0;
}
verwenden Sie einfach mutagen
$pip install mutagen
verwenden Sie es in Python-Shell:
from mutagen.mp3 import MP3
audio = MP3(file_path)
print audio.info.length
auch einen Blick auf audioread nehmen (einige Linux-Distributionen, einschließlich ubuntu haben Pakete), https://github.com/ sampsyo / audioread
audio = audioread.audio_open('/path/to/mp3')
print audio.channels, audio.samplerate, audio.duration
Sie können die Anzahl der Bilder in der Datei zählen. Jeder Rahmen hat einen Startcode, obwohl ich nicht den genauen Wert des Startcodes erinnern kann und ich habe keine MPEG-Spezifikationen rumliegen. Jeder Rahmen hat eine bestimmte Länge, um 40 ms für MPEG1 Layer II.
Diese Methode funktioniert für CBR-Dateien (Constant Bit Rate), wie VBR-Dateien Arbeit eine ganz andere Geschichte ist.
Aus dem Dokument unter:
Für Layer I-Dateien uns diese Formel:
FrameLengthInBytes = (12 * BitRate / Sample + Padding) * 4
Für Layer II & III-Dateien verwenden Sie diese Formel:
FrameLengthInBytes = 144 * Bitrate / Samplerate + Padding