Odczytywanie struktury ID3_TAG

0

Witam

Szukałem trochę po necie informacji o plikach mp3, konkretnie o tagach ID3. Napisałem taki kod pozwalający odczytywać informacje z pliku mp3. Z tym że nie zawsze te informacje wyświetlane są poprawie. Moje pytanie brzmi : czy przyczyna tkwi w złym odczycie czy może tak jest faktycznie zapisana informacja w tagach ?? Będę bardzo wdzięczny za każda pomoc.

struct ID3_TAG
{
char  Header[3];
char  SongTitle[30];
char  Artist[30];
char  Album[30];
char  Year[4];
char  Comment[30];
BYTE  Genre;
};
void GetID3_TAG(char FileName[], ID3_TAG &id3_tag)
{
  FILE *fp;
  if((fp = fopen(FileName,"r")) != NULL)
  {
    fseek(fp,-128,SEEK_END);
    fread(&id3_tag,sizeof(id3_tag),1,fp);
    fclose(fp);
  }
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(OpenDialog1->Execute())
  {
    GetID3_TAG(OpenDialog1->FileName.c_str(),id3_tag);
    Label1->Caption = id3_tag.Header;
    Label2->Caption = id3_tag.SongTitle;
    Label3->Caption = id3_tag.Artist;
    Label4->Caption = id3_tag.Album;
    Label5->Caption = id3_tag.Year;
    Label6->Caption = id3_tag.Comment;
    Label7->Caption = id3_tag.Genre;
  }
}

Screen z przykladowym odczytem
http://www.i-imagehost.com/uploads/423b9d5c11.jpg

Pozdrawiam

0

Po prostu tagi nie mają null terminatora /'\0'/, musisz go dodać we własnym zakresie albo ciąć po n znaków /gdzie n to długość tagu/.

0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dirent.h>


//================================================================================

typedef struct  {
	
	char TagID[3];
	char Title[30];
	char Artist[30];
	char Album[30];
	char Year[4];
	char Comment[30];
	unsigned char Genre;
	
} MP3TAG;

//================================================================================

typedef struct {
	
	MP3TAG	MP3tag;
	char	MP3FileName[300];
	
} MP3FILE;

//================================================================================

void AddToM3U(const char* FullName, const char* FileName, FILE* play, const char* tag) {
	
	MP3FILE mp3;
	// otwarcie pliku mp3 do odczytu
	FILE *MP3File = fopen( FullName, "r");	
	
	// gdy otwarcie się nie uda
	if( !MP3File ) {
		printf("Can't open file \"%s\"\n", FileName);
		fclose(MP3File);
		return;
	}
	
	// jesli nie można ustawić się na pozycji 128 bajtów od końca pliku
	else if ( fseek( MP3File, -128, SEEK_END) ) {
		fclose(MP3File);
		return;
	}
	
	else {
		// wczytanie tagu z pliku
		fread( &(mp3.MP3tag), sizeof(MP3TAG), 1, MP3File);
		
		// warunek na to czy plik jest poprwaną mp3,
		// jeśli nie będzie spełniony to albo tag nie jest 
		// zapisany, albo podany plik to nie mp3
		if ( ! memcmp( mp3.MP3tag.TagID, "TAG", 3) )
			strcpy(mp3.MP3FileName, FileName);
		
		// zmknięcie pliku
		fclose(MP3File);
	}
	
	// porównanie wartość pola Artist - jesli identyczne to dodajemy do playlisty
	if( ! strcmp(mp3.MP3tag.Artist, tag) ) {
		fprintf(play, "%s\n", FullName);
		printf("Added: \t%s\n", FileName);
	}
}


//================================================================================

int IndexMP3(const char* path, const char* tag, FILE* Play) {

	DIR*				directory;	// struktora DIR z bieżącym katalogiem
	dirent*				DirEntry;	// aktualnie przetwarzany wpis w katalogu "katalog"
	
	directory = opendir( path );
	
	// jeśli nie uda się otworzyć katalogu zwracamy błąd
	if(!directory) {
		printf("Directory doesn't exist!\n");
		return 1;
	}
	
	// czytamy po kolei wszystkie wpisy
	while( DirEntry = readdir(directory) ) {
		
		char plik[150];
		int l = strlen(DirEntry->d_name);
		int i;
		
		// zamiana nazwy pliku na duże litery...
		strcpy(plik, DirEntry->d_name);
		for(i=0; i < l; ++i)
			plik[i] = toupper(plik[i]);
		// ... żeby porównać rozszerzenie
		if( plik[l-4] == '.' && plik[l-3] == 'M' && plik[l-2] == 'P' &&	plik[l-1] == '3') {
			// nazwa plik + ścieżka do niego
			char FullName[400];
			
			// scalenie ścieżki i nazwy pliku
			strcpy(FullName, path);
			strcat(FullName, "\\");
			strcat(FullName, DirEntry->d_name);
			
			// wywołanie funckji, która doda do playlisty plik
			// jeśli wszystkie warunki będa spełnione
			AddToM3U(FullName, DirEntry->d_name, Play, tag);
			
		}
		// wyczyszczenie nazwy pliku, żeby stare wpisay nie mieszały się z nowymi
		memset( plik, '\0', l);
	}
		
	
	return 0;
}

//================================================================================

// tablica w której przechowywane są wszystkie katalogi
char*	AllDirs[10000];
// index nast. wolnego miejsca w tablicy
int		Index=0;

//================================================================================

int FindDirsDownto(const char* path) {
	
	DIR*			directory;	// katalog bieżący
	dirent*			DirEntry;	// wpis, na którym aktualnie pracuje funkcja
	int				pos = 0;	// index ostatniego elementu w tablicy
	char*			Dirs[200];	// tablica lokalnych katalogów
	int				i;
	
	
	// jeśli nie można otwarzyć katalogu zwracamy 1
	if( !(directory = opendir( path ) ) )
		return 1;
	
	// czytamy wszystkie wpisy
	while( DirEntry = readdir(directory) )
		// jeśli wpis jest katalogiem
		if( (directory->dd_dta.attrib & _A_SUBDIR) && (DirEntry->d_name[0] != '.') ) {
			
			// sklejamy ścieżke z nazwą, usuwając wcześniej znak '*' na końcu ścieżki
			char *kat = (char*)calloc( strlen(directory->dd_name)+strlen(DirEntry->d_name), sizeof(char) );
				
			strncpy(kat, directory->dd_name, strlen( directory->dd_name )-1 );
			strcat(kat, DirEntry->d_name);
			
			Dirs[pos++] = kat;		// dodajemy do listy lokalnych katalogów
			AllDirs[Index++] = kat;	// dodajemy do listy wszystkich katalogów
		}
	
	
	closedir(directory);	// zamykamy katalog
	
	
	// wywołujemy rekurencyjnie dla wszystkich katalogów lokalnych
	for(i = 0; i < pos; ++i)
		FindDirsDownto(Dirs[i]);
	
	return 0;
}


//================================================================================

int main() {
	// nazwa katalogu głównego
	char kat[200];
	// nazwa pliku z palylistą
	char play[50];
	char tag[50];	
	int i;
	FILE *Play;
	
	// pobranie danych
	printf("Enter directory name: ");
	gets(kat);
	printf("Enter playlist file name: ");
	gets(play);
	
	strcat(play, ".m3u");
	
	printf("Enter artist name: ");
	gets(tag);	
	printf("I'm scanning \"%s\"\n", kat);
	
	// zindeksowanie katalogów
	FindDirsDownto(kat);
	
	// otwarcie pliku do dopisywania
	Play = fopen(play, "a+");
	
	// Indeksowanie plików mp3 oraz dodanie ich do playlisty
	for(i=0; i < Index; ++i)
		IndexMP3(AllDirs[i], tag, Play);
	
	// zamknięcie pliku playlisty
	fclose(Play);
	
	// zwolanienie pamięci
	for(i=0; i < Index; ++i)
		free(AllDirs[i]);

}

Pisałem kiedyś. Program jest w C. ID3v2 już nie jest tak łatwo odczytać. Zainteresuj się id3lib.

1 użytkowników online, w tym zalogowanych: 0, gości: 1