#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.