Problem beim Auslesen des ID3v1 Tags einer mp3 Datei
-
Hallo,
ich will den ID3v1 Tag einer mp3 Datei auslesen. Dazu habe ich bis ejtzt folgende Struktur definiert:struct id3 { char tag[3]; char title[31]; char artist[31]; char album[31]; char year[5]; char comment[31]; int genre; int track; } play1;
Folgende Funktion soll den Tag auslesen:
id3 readid3(char *szPath) { /* szPath ist der Pfad zur mp3Datei */ FILE *datei_ptr; char ver[2]; datei_ptr = fopen(szPath, "r+b"); if ( datei_ptr != 0) { if (fseek(datei_ptr,-128,SEEK_END) == 0) { fgets(play1.tag,4,datei_ptr); fgets(play1.title,31,datei_ptr); fgets(play1.artist,31,datei_ptr); fgets(play1.album,31,datei_ptr); fgets(play1.year,5,datei_ptr); fgets(play1.comment,31,datei_ptr); fgets(ver,2,datei_ptr); play1.genre = atoi(ver); } else printf("Zeiger konnte nicht gesetzt werden!"); fclose(datei_ptr); } else printf("Fehler beim öffnen der Datei!"); return play1; }
Mit printf kann ich mir damit die Werte von Titel, Artist, Album, Jahr und Kommentar richtig anzeigen lassen. Doch bei Genre wird immer 0 ausgegeben, obwohl die Datei eine Information über das Genre enthält. Woran kann das liegen?
Ich hoffe, dass ihr mir helfen könnt.MFG, VLT02
-
Wenn ichs richtig sehe, ist das Genre als ein Byte Zahl gespeichert. Du liest einen String und versuchst dannd ie Zahl auszulesen, das klappt so nicht.
Ich denke mal
fread(&play1.genre, sizeof(unsigned char), 1, datei_ptr)
sollte besser klappen, nicht vergessen genre im struct als unsigned char zu deklarieren.
-
Herzlichen Dank, TriPhoenix, für deine Hilfe!
Jetzt klappt es so wie ich es mir vorstelleMFG, VLT02
-
Hallo,
jetzt hab ich leider wieder ein Problem.
Meine Funktion sieht jetzt so aus:id3 readid3(char *szPath) { /* Pfad zur .mp3-Datei */ FILE *datei_ptr = NULL; char ver[4]; datei_ptr = fopen(szPath, "r+b"); if ( datei_ptr != 0) { /* Nach ID3v2 Tag suchen*/ fseek(datei_ptr,0,SEEK_SET); fread(ver,3,1,datei_ptr); if (strcmp(ver, "ID3") == 0) printf("ID3v2 Tag vorhanden!"); /* Nach ID3v1 Tag suchen */ if (fseek(datei_ptr,-128,SEEK_END) == 0) { fread(play.tag,3,1,datei_ptr); if (strcmp(play.tag, "TAG") == 0) { fread(play.title,30,1,datei_ptr); fread(play.artist,30,1,datei_ptr); fread(play.album,30,1,datei_ptr); fread(play.year,4,1,datei_ptr); fread(play.comment,29,1,datei_ptr); fread(&play.genre, sizeof(unsigned char), 1, datei_ptr); fread(&play.track, sizeof(unsigned char), 1, datei_ptr); play.title[30]='\0'; play.artist[30]='\0'; play.album[30]='\0'; play.year[4]='\0'; play.comment[30]='\0'; } } else printf("Zeiger konnte nicht gesetzt werden!"); fclose(datei_ptr); } else printf("Fehler beim öffnen der Datei!"); return play; }
Wenn ich die Funktion jetzt einmal aufrufe funktioniert alles bestens.
Wenn ich aber folgendes eingebe:strcpy(pfad, "c:\\mp3s\\Faith No More - I'm Easy.mp3"); readid3(pfad); strcpy(pfad, "c:\\mp3s\\Metallica - Enter Sandman.mp3"); readid3(pfad);
steht nach dem zweiten Aufruf in play.title immer noch I'm easy und nicht Enter - Sandman.
Hab seit gestern schon alles mögliche ausprobiert, aber weis nicht woran das liegt. Hängt das irgendwie mit st_atime zusammen?MFG, VLT02
-
ist play eine globale Variable? Wenn ja: warum?
Ich nehme an, es steht einfach noch der alte Datensatz da drinnen
-
Ja in play steht noch der alte Datensatz drin.
Und play muss doch eine globale Variable sein, weil ich ansonsten in meinem Hauptprogramm nicht auf die Elemente von play zugreifen kann.
Ich hab schon probiert bei jedem Funktionsaufruf die Struktur am Anfang neu zu initialisieren mit:strcpy(play.title, "0"); strcpy(play.artist, "0"); strcpy(play.album, "0"); strcpy(play.tag, "0"); play.genre = 0; play.track = 0; strcpy(play.year, "0"); strcpy(play.comment, "0");
Dann steht aber nur noch 0 in den einzelnen Werten und fread überschreibt das nicht mehr.
Ist die Möglichkeit vom Ansatz her richtig oder macht man das besser anders?MFG, VLT02
-
returnst play doch aus deiner funktion... also leg play auch dort an...
btw: wenn eine funktion fehlschlaegt, sollte sie dies melden (und zwar nicht mit einem printf, sondern eben einen fehler zurueck geben)
einziges was mir einfaellt ist, dass
if (strcmp(play.tag, "TAG") == 0)
unwahr ist und somit die struktur nicht geaendert wird...
-
So jetzt klappt es eigentlich
if (strcmp(play.tag, "TAG") == 0)
traff tatsächlich nicht zu, da ich nicht
play.tag[3]='\0';
eingegeben habe stand beim zweiten Aufruf der Funktion in play.tag "TAG+der Name des Liedes" und war nicht mehr 3 bytes lang sonder 33.
Wie kann das sein, wenn ich in der Struktur geschrieben habe, dass play.tag nur 3 bytes lang sein darf?
-
und danke für deine Hilfe
MFG, VLT02
-
VLT02 schrieb:
So jetzt klappt es eigentlich
if (strcmp(play.tag, "TAG") == 0)
traff tatsächlich nicht zu, da ich nicht
play.tag[3]='\0';
eingegeben habe stand beim zweiten Aufruf der Funktion in play.tag "TAG+der Name des Liedes" und war nicht mehr 3 bytes lang sonder 33.
Wie kann das sein, wenn ich in der Struktur geschrieben habe, dass play.tag nur 3 bytes lang sein darf?Das 0 setzen von play.tag[3] ist eigentlich keine gute Idee. Da du ja eigentlich auf den Speicherbereich hinter play.tag[3] schreibst. Entweder du erhöhst den Speicherbereich von tag auf 4 oder du schreibst deine Überprüfung anders, und zwar nicht mit strcmp() sondern mit strncmp() da kannst du nämlich angeben wieviele Zeichen überprüft werden sollen (in deinem Fall als nur 3). strncmp() überprüft hald solange bis es das Stringendezeichen (-> \0) gefunden hat bei einem der beiden und überprüft auch dieses!