Moin Moin
Ich bin aktuell dabei ein Programm zu schreiben was mir die MP3 Tags auslesen kann. Aktuell scheiter ich bei ID3V2(aber noch nicht gro´ßartig nachgeguckt) und bei der Bitrate. Bei der Bitrate habe ich schon die ganze Zeit rumgegooglet womit ich jetzt weiß das ich jedes einzelne Frame auslesen muss. Könnt ihr mir vielleicht helfen wie ich das hinbekomme? Dies ist mein Übungsprojekt, dass heißt ich bin noch nicht so ein Profi und kenne noch nicht alle Begriffe.
Gruß
Metaller
Hi,
Bitraten kannst du einfach vom header auslesen:
Hier mal die Methode dazu:
public bool ReadMP3Information(string FileName)
{
FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read);
// Setze Dateinamen ohne Pfad
strFileName = @fs.Name;
char[] chrSeparators = new char[] { '\\', '/' };
string[] strSeparator = strFileName.Split(chrSeparators);
int intUpper = strSeparator.GetUpperBound(0);
strFileName = strSeparator[intUpper];
strFileName = strFileName.Replace("'", "''");
// Setze Dateilänge
lngFileSize = fs.Length;
byte[] bytHeader = new byte[4];
byte[] bytVBitRate = new byte[12];
int intPos = 0;
// Lese die ersten 4 Bits um zu prüfen ob es eine MP3 ist
do
{
fs.Position = intPos;
fs.Read(bytHeader, 0, 4);
intPos++;
LoadMP3Header(bytHeader);
}
while (!IsValidHeader() && (fs.Position != fs.Length));
//Wenn die Streamposition = der Länge ist ist es KEINE Gültige MP3
if (fs.Position != fs.Length)
{
intPos += 3;
if (getVersionIndex() == 3) // MPEG Version 1
{
if (getModeIndex() == 3) // Single Channel
{
intPos += 17;
}
else
{
intPos += 32;
}
}
else // MPEG Version 2.0 or 2.5
{
if (getModeIndex() == 3) // Single Channel
{
intPos += 9;
}
else
{
intPos += 17;
}
}
// Pürfe ob die Datei eine Variable Bitrate hat
fs.Position = intPos;
fs.Read(bytVBitRate, 0, 12);
boolVBitRate = LoadVBRHeader(bytVBitRate);
// Wenn die Datei gelesen wurde übergib die daten an die Public Variablen
intBitRate = getBitrate();
intFrequency = getFrequency();
strMode = getMode();
intLength = getLengthInSeconds();
strLengthFormatted = getFormattedLength();
fs.Close();
return true;
}
return false;
}
private void LoadMP3Header(byte[] c)
{
// c[0] = 00000011
// c[1] = 00001100
// c[2] = 00110000
// c[3] = 11000000
// Dieser Operator << bedeutet Das wir die Bits in diese Richtung schieben
// 00000011 << 24 = 00000011000000000000000000000000
// 00001100 << 16 = 000011000000000000000000
// 00110000 << 24 = 0011000000000000
// 11000000 = 11000000
// +_________________________________
// 00000011000011000011000011000000
bithdr = (ulong)(((c[0] & 255) << 24) | ((c[1] & 255) << 16) | ((c[2] & 255) << 8) | ((c[3] & 255)));
}
private bool LoadVBRHeader(byte[] inputheader)
{
//Bei einer Variablen Bitrate wird XING ausgegeben
if (inputheader[0] == 88 && inputheader[1] == 105 &&
inputheader[2] == 110 && inputheader[3] == 103)
{
int flags = (int)(((inputheader[4] & 255) << 24) | ((inputheader[5] & 255) << 16) | ((inputheader[6] & 255) << 8) | ((inputheader[7] & 255)));
if ((flags & 0x0001) == 1)
{
intVFrames = (int)(((inputheader[8] & 255) << 24) | ((inputheader[9] & 255) << 16) | ((inputheader[10] & 255) << 8) | ((inputheader[11] & 255)));
return true;
}
else
{
intVFrames = -1;
return true;
}
}
return false;
}
private bool IsValidHeader()
{
return (((getFrameSync() & 2047) == 2047) &&
((getVersionIndex() & 3) != 1) &&
((getLayerIndex() & 3) != 0) &&
((getBitrateIndex() & 15) != 0) &&
((getBitrateIndex() & 15) != 15) &&
((getFrequencyIndex() & 3) != 3) &&
((getEmphasisIndex() & 3) != 2));
}
private int getFrameSync()
{
return (int)((bithdr >> 21) & 2047);
}
private int getVersionIndex()
{
return (int)((bithdr >> 19) & 3);
}
private int getLayerIndex()
{
return (int)((bithdr >> 17) & 3);
}
private int getProtectionBit()
{
return (int)((bithdr >> 16) & 1);
}
private int getBitrateIndex()
{
return (int)((bithdr >> 12) & 15);
}
private int getFrequencyIndex()
{
return (int)((bithdr >> 10) & 3);
}
private int getPaddingBit()
{
return (int)((bithdr >> 9) & 1);
}
private int getPrivateBit()
{
return (int)((bithdr >> 8) & 1);
}
private int getModeIndex()
{
return (int)((bithdr >> 6) & 3);
}
private int getModeExtIndex()
{
return (int)((bithdr >> 4) & 3);
}
private int getCoprightBit()
{
return (int)((bithdr >> 3) & 1);
}
private int getOrginalBit()
{
return (int)((bithdr >> 2) & 1);
}
private int getEmphasisIndex()
{
return (int)(bithdr & 3);
}
private double getVersion()
{
double[] table = { 2.5, 0.0, 2.0, 1.0 };
return table[getVersionIndex()];
}
private int getLayer()
{
return (int)(4 - getLayerIndex());
}
private int getBitrate()
{
// Bei Variabler Bitrate wird ein Mittelwert gebildet
if (boolVBitRate)
{
double medFrameSize = (double)lngFileSize / (double)getNumberOfFrames();
return (int)((medFrameSize * (double)getFrequency()) / (1000.0 * ((getLayerIndex() == 3) ? 12.0 : 144.0)));
}
else
{
int[, ,] table = {
{ // MPEG 2 & 2.5
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, // Layer III
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, // Layer II
{0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0} // Layer I
},
{ // MPEG 1
{0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}, // Layer III
{0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, // Layer II
{0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,0} // Layer I
}
};
return table[getVersionIndex() & 1, getLayerIndex() - 1, getBitrateIndex()];
}
}
private int getFrequency()
{
int[,] table = {
{32000, 16000, 8000}, // MPEG 2.5
{ 0, 0, 0}, // reserved
{22050, 24000, 16000}, // MPEG 2
{44100, 48000, 32000} // MPEG 1
};
return table[getVersionIndex(), getFrequencyIndex()];
}
private string getMode()
{
switch (getModeIndex())
{
default:
return "Stereo";
case 1:
return "Joint Stereo";
case 2:
return "Dual Channel";
case 3:
return "Single Channel";
}
}
private int getLengthInSeconds()
{
// "intKilBitFileSize" geteilt durch 1000 damit die Formel stimmt "Kilobits/second"
int intKiloBitFileSize = (int)((8 * lngFileSize) / 1000);
return (int)(intKiloBitFileSize / getBitrate());
}
private string getFormattedLength()
{
// Komplette Sekunden
int s = getLengthInSeconds();
// Sekunden formatiert
int ss = s % 60;
// Komplette Minuten
int m = (s - ss) / 60;
// Formatierte Minuten
int mm = m % 60;
// Komplette Stunden
int h = (m - mm) / 60;
// mach "hh:mm:ss"
return h.ToString("D2") + ":" + mm.ToString("D2") + ":" + ss.ToString("D2");
}
private int getNumberOfFrames()
{
// Die Anzahl der MPGFrames ist abhängig obs eine Variable Bitrate oder eine feste ist
if (!boolVBitRate)
{
double medFrameSize = (double)(((getLayerIndex() == 3) ? 12 : 144) * ((1000.0 * (float)getBitrate()) / (float)getFrequency()));
return (int)(lngFileSize / medFrameSize);
}
else
return intVFrames;
}
}
Schnelle Antwort. Vielen Dank. Guck mir das nachher mal an.