예제 #1
0
bool CTagLoaderTagLib::Load(const CStdString& strFileName, CMusicInfoTag& tag, const CStdString& fallbackFileExtension, MUSIC_INFO::EmbeddedArt *art /* = NULL */)
{  
  CStdString strExtension = URIUtils::GetExtension(strFileName);
  StringUtils::ToLower(strExtension);
  StringUtils::TrimLeft(strExtension, ".");

  if (strExtension.empty())
  {
    strExtension = fallbackFileExtension;
    if (strExtension.empty())
      return false;
    StringUtils::ToLower(strExtension);
  }

  TagLibVFSStream*           stream = new TagLibVFSStream(strFileName, true);
  if (!stream)
  {
    CLog::Log(LOGERROR, "could not create TagLib VFS stream for: %s", strFileName.c_str());
    return false;
  }
  
  ID3v1::Tag::setStringHandler(&ID3v1StringHandler);
  ID3v2::Tag::setLatin1StringHandler(&ID3v2StringHandler);
  TagLib::File*              file = NULL;
  TagLib::APE::File*         apeFile = NULL;
  TagLib::ASF::File*         asfFile = NULL;
  TagLib::FLAC::File*        flacFile = NULL;
  TagLib::IT::File*          itFile = NULL;
  TagLib::Mod::File*         modFile = NULL;
  TagLib::MP4::File*         mp4File = NULL;
  TagLib::MPC::File*         mpcFile = NULL;
  TagLib::MPEG::File*        mpegFile = NULL;
  TagLib::Ogg::Vorbis::File* oggVorbisFile = NULL;
  TagLib::Ogg::FLAC::File*   oggFlacFile = NULL;
  TagLib::S3M::File*         s3mFile = NULL;
  TagLib::TrueAudio::File*   ttaFile = NULL;
  TagLib::WavPack::File*     wvFile = NULL;
  TagLib::XM::File*          xmFile = NULL;

  if (strExtension == "ape")
    file = apeFile = new APE::File(stream);
  else if (strExtension == "asf" || strExtension == "wmv" || strExtension == "wma")
    file = asfFile = new ASF::File(stream);
  else if (strExtension == "flac")
    file = flacFile = new FLAC::File(stream, ID3v2::FrameFactory::instance());
  else if (strExtension == "it")
    file = itFile = new IT::File(stream);
  else if (strExtension == "mod" || strExtension == "module" || strExtension == "nst" || strExtension == "wow")
    file = modFile = new Mod::File(stream);
  else if (strExtension == "mp4" || strExtension == "m4a" || 
           strExtension == "m4r" || strExtension == "m4b" || 
           strExtension == "m4p" || strExtension == "3g2")
    file = mp4File = new MP4::File(stream);
  else if (strExtension == "mpc")
    file = mpcFile = new MPC::File(stream);
  else if (strExtension == "mp3" || strExtension == "aac")
    file = mpegFile = new MPEG::File(stream, ID3v2::FrameFactory::instance());
  else if (strExtension == "s3m")
    file = s3mFile = new S3M::File(stream);
  else if (strExtension == "tta")
    file = ttaFile = new TrueAudio::File(stream, ID3v2::FrameFactory::instance());
  else if (strExtension == "wv")
    file = wvFile = new WavPack::File(stream);
  else if (strExtension == "xm")
    file = xmFile = new XM::File(stream);
  else if (strExtension == "ogg")
    file = oggVorbisFile = new Ogg::Vorbis::File(stream);
  else if (strExtension == "oga") // Leave this madness until last - oga container can have Vorbis or FLAC
  {
    file = oggFlacFile = new Ogg::FLAC::File(stream);
    if (!file || !file->isValid())
    {
      delete file;
      oggFlacFile = NULL;
      file = oggVorbisFile = new Ogg::Vorbis::File(stream);
    }
  }

  if (!file || !file->isOpen())
  {
    delete file;
    delete stream;
    CLog::Log(LOGDEBUG, "file could not be opened for tag reading");
    return false;
  }

  APE::Tag *ape = NULL;
  ASF::Tag *asf = NULL;
  MP4::Tag *mp4 = NULL;
  ID3v1::Tag *id3v1 = NULL;
  ID3v2::Tag *id3v2 = NULL;
  Ogg::XiphComment *xiph = NULL;
  Tag *generic = NULL;

  if (apeFile)
    ape = apeFile->APETag(false);
  else if (asfFile)
    asf = asfFile->tag();
  else if (flacFile)
  {
    xiph = flacFile->xiphComment(false);
    id3v2 = flacFile->ID3v2Tag(false);
  }
  else if (mp4File)
    mp4 = mp4File->tag();
  else if (mpegFile)
  {
    id3v1 = mpegFile->ID3v1Tag(false);
    id3v2 = mpegFile->ID3v2Tag(false);
    ape = mpegFile->APETag(false);
  }
  else if (oggFlacFile)
    xiph = dynamic_cast<Ogg::XiphComment *>(oggFlacFile->tag());
  else if (oggVorbisFile)
    xiph = dynamic_cast<Ogg::XiphComment *>(oggVorbisFile->tag());
  else if (ttaFile)
    id3v2 = ttaFile->ID3v2Tag(false);
  else if (wvFile)
    ape = wvFile->APETag(false);
  else if (mpcFile)
    ape = mpcFile->APETag(false);
  else    // This is a catch all to get generic information for other files types (s3m, xm, it, mod, etc)
    generic = file->tag();

  if (file->audioProperties())
    tag.SetDuration(file->audioProperties()->length());

  if (asf)
    ParseASF(asf, art, tag);
  if (id3v1)
    ParseID3v1Tag(id3v1, art, tag);
  if (id3v2)
    ParseID3v2Tag(id3v2, art, tag);
  if (generic)
    ParseGenericTag(generic, art, tag);
  if (mp4)
    ParseMP4Tag(mp4, art, tag);
  if (xiph) // xiph tags override id3v2 tags in badly tagged FLACs
    ParseXiphComment(xiph, art, tag);
  if (ape && (!id3v2 || g_advancedSettings.m_prioritiseAPEv2tags)) // ape tags override id3v2 if we're prioritising them
    ParseAPETag(ape, art, tag);

  // art for flac files is outside the tag
  if (flacFile)
    SetFlacArt(flacFile, art, tag);

  if (!tag.GetTitle().empty() || !tag.GetArtist().empty() || !tag.GetAlbum().empty())
    tag.SetLoaded();
  tag.SetURL(strFileName);

  delete file;
  delete stream;
  
  return true;
}
예제 #2
0
/* LOAD UP THE FILE'S TAG
 * Search each file type individually so we can get individual tags for
 * custom tagging.
 */
TagDatac * tag_data_load (char *url, int *pvalid)
{
    TagData * data;
    TagLib::String s = url;
    int mtime;
    struct stat buf;
    if (!stat (url, &buf))
        mtime = (int) buf.st_mtime;


   /* FIXME: Using filename to find media type. GStreamer probe instead?
   */
    if(s.size() > 4) {
        if(s.substr(s.size() - 4, 4).upper() == ".OGG")
        {
            TagLib::Vorbis::File * f = new TagLib::Vorbis::File(url);
            if (! f->isValid ())
                return NULL;
            data = (TagData*) malloc (sizeof (TagData));
            data->file = new TagLib::FileRef (f);
            data->id3v2 = NULL;
            data->id3v1 = NULL;
            data->ape   = NULL;
            data->xiph  = f->tag ();
            data->mime  = "application/ogg";
            data->mtime = mtime;
            return reinterpret_cast<TagDatac *> (data);
        }
        if(s.substr(s.size() - 4, 4).upper() == ".MP3")
        {
            TagLib::MPEG::File * f = new TagLib::MPEG::File(url);
            if (! f->isValid ())
                return NULL;
            data = (TagData*) malloc (sizeof (TagData));
            data->file = new TagLib::FileRef (f);
            data->id3v2 = f->ID3v2Tag ();
            data->id3v1 = f->ID3v1Tag ();
            data->ape   = f->APETag ();
            data->xiph  = NULL;
            data->mime  = "audio/mpeg";
            data->mtime = mtime;
            return reinterpret_cast<TagDatac *>(data);
        }
        if(s.substr(s.size() - 5, 5).upper() == ".FLAC")
        {
            TagLib::FLAC::File * f = new TagLib::FLAC::File(url);
            if ((! f->isValid ())&& (pvalid != NULL)){
				*pvalid = -1;//paul add on 080827 merge from Olive
                return NULL;
			}
            data = (TagData*) malloc (sizeof (TagData));
            data->file = new TagLib::FileRef (f);
            data->id3v2 = f->ID3v2Tag ();
            data->id3v1 = f->ID3v1Tag ();
            data->ape   = NULL;
            data->xiph  = f->xiphComment ();
            data->mime  = "audio/x-flac";
            data->mtime = mtime;
            return reinterpret_cast<TagDatac *>(data);
        }
        if(s.substr(s.size() - 4, 4).upper() == ".MPC" || s.substr(s.size() - 4, 4).upper() == ".AAC")
        {
            TagLib::MPC::File * f = new TagLib::MPC::File(url);
            if (! f->isValid ())
                return NULL;
            data = (TagData*) malloc (sizeof (TagData));
            data->file = new TagLib::FileRef (f);
            data->id3v2 = NULL;
            data->id3v1 = f->ID3v1Tag ();
            data->ape   = f->APETag ();
            data->xiph  = NULL;
            data->mime  = "audio/x-musepack";
            data->mtime = mtime;
            return reinterpret_cast<TagDatac *>(data);
        }
    }
    return NULL;
}