• Willkommen im Linux Club - dem deutschsprachigen Supportforum für GNU/Linux. Registriere dich kostenlos, um alle Inhalte zu sehen und Fragen zu stellen.

Mp3 Tags auslesem

Olti1986

Member
Hallo!!

Ich will in C++ ein prog schreiben, das mir den Tag eines Mp3 Files ausliest, also die letzten 125 Byte.
Krieg aber irgendwie immer nur den Title, also die ersten max. 30 Byte. Wenn ich dann wieder vom Dateiende um 95 Byte nach vorne spring und den Interpreten auslesen will gibt mir fail() ne 0 zurück.

Code:
void CId3::read_tag()
{	
	file.seekg(-125, ios_base::end);
	getline(file,title);	
	
	cout << title << endl;
	
	file.seekg(-95, ios_base::end);
	getline(file,artist);
	
	if (file.fail())
		cout << "Fehler!!";
	else
		cout << artist;
}

Schreib ich statt getline(file,artist); file << artist; dann gehts, nur ist das nicht das was ich will, da im Titel auch Leerzeichen vorkommen.
Kann mir jemand sagen was ich falsch mach??

Mfg Olti[/code]
 
OP
O

Olti1986

Member
Ich hätte gern selbst was geschrieben und vor allem verstanden warums nicht geht!!!

Mfg Olti
 

TeXpert

Guru
ich lese mp3tags (Version 1) auch unter C++ immer noch auf die klassische C-Variante ein, d.h. ein POD (plain old Datastructure) und alles rein da :)

ich hab gerade mal etwas zusammen gecopy-pastet (Hinweis: das muss nicht 1:1 kompilieren....)


Code:
#include <iostream>
#include <fstream>
#include "mp3v1_genres.h"
/**
  * the ID3-Tag structure,
  * compare with: http://www.id3.org/id3v1.html
  */
typedef struct {
  char tag[3];
  char title[30];
  char artist[30];
  char album[30];
  char year[4];
  char comment[30];
  char genre;
} ID3TAGV1;

/**
  * look for this characters to find the Version1 Tagstruct
  */
const char TAGIDENTIFIER[3] = { 'T', 'A', 'G' };



class ID3Reader {
private:
  ID3TAGV1 tag;
  std::string filename;

public:
  ID3Reader(const std::string file);
  
  bool readTag();
  
  void printTag();
};


ID3Reader::ID3Reader(const std::string file)
: filename(file) {  
}


bool ID3Reader::readTag() {
  std::ifstream file;
  int count;
  
  file.open(filename.c_str(), std::ios::in); 
  if (!file)
    return false;

  file.seekg(-sizeof(tag), std::ios_base::end); 
  file.read(reinterpret_cast<char*>(&tag), sizeof(tag));
  file.close();
  
  // tag-check
  for (count = 0; count < 3; count++){
    if (tag.tag[count] != TAGIDENTIFIER[count])
      return false;  
  }
  
  return true;
}
  
  
void ID3Reader::printTag() {

  std::cout << "The ID3-Tags of \"" << filename << "\"" << std::endl;
  std::cout << "Title  : " << tag.title << std::endl;
  std::cout << "Artist : " << tag.artist << std::endl;
  std::cout << "Album  : " << tag.album << std::endl;
  std::cout << "Comment: " << tag.comment << std::endl;
  
  int genre = (int)tag.genre;
  if (genre > MAX_GENRE) {
    std::cout << "Genre not found in list! (" << genre << ")" << std::endl;
  }
  else if (genre > MAX_STD_GENRE) {
    std::cout << "Genre  : " << GENRES[genre] << " (WinAmp-Extension!)" << std::endl;
  }
  else {
    std::cout << "Genre  : " << GENRES[genre] << std::endl;
  }

}   


int main(int argc, char* argv[]) {

  if (argc != 2) {
    std::cout << "parameterfehler" << std::endl;
    std::exit(1);
  }
  
  ID3Reader *id3reader = new ID3Reader(argv[1]);  
  if (id3reader->readTag()) {
    id3reader->printTag();
  } else {
    std::cout << "error reading tag" << std::endl;
  }
  delete id3reader;
}
kompilieren und mit dem File als Argument aufrufen.
 

TeXpert

Guru
und Du brauchst noch meine Genre-Liste: (als mp3v1_genres.h im gleichen Verzeichnis speichern)

Code:
#ifndef __MP3V1GENRES_H__
#define __MP3V1GENRES_H__


#define MAX_GENRE 147
#define MAX_STD_GENRE 80

const char *GENRES[148]={
"Blues",
"Classic Rock",
"Country",
"Dance",
"Disco",
"Funk",
"Grunge",
"Hip-Hop",
"Jazz",
"Metal",
"New Age",
"Oldies",
"Other",
"Pop",
"R&B",
"Rap",
"Reggae",
"Rock",
"Techno",
"Industrial",
"Alternative",
"Ska",
"Death Metal",
"Pranks",
"Soundtrack",
"Euro-Techno",
"Ambient",
"Trip-Hop",
"Vocal",
"Jazz&Funk",
"Fusion",
"Trance",
"Classical",
"Instrumental",
"Acid",
"House",
"Game",
"Sound Clip",
"Gospel",
"Noise",
"Alternative",
"Bass",
"Soul",
"Punk",
"Space",
"Meditative",
"Instrumental Pop",
"Instrumental Rock",
"Ethnic",
"Gothic",
"Darkwave",
"Techno-Industrial",
"Electronic",
"Pop-Folk",
"Eurodance",
"Dream",
"Southern Rock",
"Comedy",
"Cult",
"Gangsta",
"Top 40",
"Christian Rap",
"Pop/Funk",
"Jungle",
"Native US",
"Cabaret",
"New Wave",
"Psychedelic",
"Rave",
"Showtunes",
"Trailer",
"Lo-Fi",
"Tribal",
"Acid Punk",
"Acid Jazz",
"Polka",
"Retro",
"Musical",
"Rock & Roll",
"Hard Rock",
"Folk",
// winamp-extensions:
"Folk-Rock",
"National Folk",
"Swing",
"Fast Fusion",
"Bebop",
"Latin",
"Revival",
"Celtic",
"Bluegrass",
"Avantgarde",
"Gothic Rock",
"Progressive Rock",
"Psychedelic Rock",
"Symphonic Rock",
"Slow Rock",
"Big Band",
"Chorus",
"Easy Listening",
"Acoustic",
"Humour",
"Speech",
"Chanson",
"Opera",
"Chamber Music",
"Sonata",
"Symphony",
"Booty Bass",
"Primus",
"Porn Groove",
"Satire",
"Slow Jam",
"Club",
"Tango",
"Samba",
"Folklore",
"Ballad",
"Power Ballad",
"Rhytmic Soul",
"Freestyle",
"Duet",
"Punk Rock",
"Drum Solo",
"Acapella",
"Euro-House",
"Dance Hall",
"Goa",
"Drum & Bass",
"Club-House",
"Hardcore",
"Terror",
"Indie",
"BritPop",
"Negerpunk",
"Polsk Punk",
"Beat",
"Christian Gangsta",
"Heavy Metal",
"Black Metal",
"Crossover",
"Contemporary C",
"Christian Rock",
"Merengue",
"Salsa",
"Thrash Metal",
"Anime",
"JPop",
"SynthPop"};

#endif
 
OP
O

Olti1986

Member
Hallo!!

Danke für die schnelle Hilfe! Werds mal probieren!
Kannst du mir folgende Zeile mal kurz erklären, da ich noch ziemlicher Neuling in C++ bin??

Code:
file.read(reinterpret_cast<char*>(&tag), sizeof(tag));

MFG Olti
 

TeXpert

Guru
das ist im Prinzip ein kleiner Hack ;)

was ein cast ist sollte klar sein, file.read liefert einen char* auf die gewünschte Zeichenmenge die Anzahl der Zeichen die glesen werden sollen hole ich mir über die Größe des structs -> sizeof(tag)

d.h. ich hab jetzt ein char* mit 128Bytes, das will ich aber nicht als char* sondern in meiner Struct haben. ein reinterpret_cast ist wie gesagt IMHO ein Hack, da ich mutwillig :) die Bedeutung umändere und den Mist einfach in den Specherbereich des Structs schreiben lasse
 
OP
O

Olti1986

Member
Hallo Texpert!

Danke für die super Hilfe!
Funktioniert super nur wenn ich mir tag.tag ausgeben lasse steht da zuerst TAG und dann aber noch der Titel des Liedes obwohl mein tag ja wirklich nur 3 Byte groß sein dürfte! Ist im Prinzip nicht weiter wild aber weiß jemand warum das so ist?

MFG Olti
 

TeXpert

Guru
Argh...

sach mal Basiswissen in C hast Du schon? insbesondere was Strings und die Terminatoren angeht?
 
Oben