예제 #1
0
bool KFlacPlugin::readInfo( KFileMetaInfo& info, uint what )
{
    if ( info.path().isEmpty() ) // remote file
        return false;

    bool readComment = false;
    bool readTech = false;
    if (what & (KFileMetaInfo::Fastest |
                KFileMetaInfo::DontCare |
                KFileMetaInfo::ContentInfo)) readComment = true;

    if (what & (KFileMetaInfo::Fastest |
                KFileMetaInfo::DontCare |
                KFileMetaInfo::TechnicalInfo)) readTech = true;

    TagLib::File *file = 0;

    if (info.mimeType() == "audio/x-flac")
        file = new TagLib::FLAC::File(QFile::encodeName(info.path()).data(), readTech);
#ifdef TAGLIB_1_2
    else
        file = new TagLib::Ogg::FLAC::File(QFile::encodeName(info.path()).data(), readTech);
#endif

    if (!file || !file->isValid())
    {
        kdDebug(7034) << "Couldn't open " << file->name() << endl;
        delete file;
        return false;
    }

    if(readComment && file->tag())
    {
        KFileMetaInfoGroup commentgroup = appendGroup(info, "Comment");

        QString date  = file->tag()->year() > 0 ? QString::number(file->tag()->year()) : QString::null;
        QString track = file->tag()->track() > 0 ? QString::number(file->tag()->track()) : QString::null;

        appendItem(commentgroup, "Title",       TStringToQString(file->tag()->title()).stripWhiteSpace());
        appendItem(commentgroup, "Artist",      TStringToQString(file->tag()->artist()).stripWhiteSpace());
        appendItem(commentgroup, "Album",       TStringToQString(file->tag()->album()).stripWhiteSpace());
        appendItem(commentgroup, "Date",        date);
        appendItem(commentgroup, "Comment",     TStringToQString(file->tag()->comment()).stripWhiteSpace());
        appendItem(commentgroup, "Tracknumber", track);
        appendItem(commentgroup, "Genre",       TStringToQString(file->tag()->genre()).stripWhiteSpace());
    }

    if (readTech && file->audioProperties())
    {
        KFileMetaInfoGroup techgroup = appendGroup(info, "Technical");
        TagLib::FLAC::Properties *properties =
                   (TagLib::FLAC::Properties*)(file->audioProperties());

        appendItem(techgroup, "Bitrate",      properties->bitrate());
        appendItem(techgroup, "Sample Rate",  properties->sampleRate());
        appendItem(techgroup, "Sample Width", properties->sampleWidth());
        appendItem(techgroup, "Channels",     properties->channels());
        appendItem(techgroup, "Length",       properties->length());
    }

    delete file;
    return true;

}
예제 #2
-1
void import_flac_file(const std::string& filename)
{
  //std::cerr << "import_flac_file " << filename << std::endl;

  TagLib::FLAC::File file(filename.c_str());

  auto tag = file.tag();

  auto artist_name = tag->artist().to8Bit(true);
  auto album_title = tag->album().to8Bit(true);
  auto track_title = tag->title().to8Bit(true);

  auto artist = dm::artist::find_by_name(artist_name);

  if ( artist.is_null() )
  {
    // Create artist.
    artist.name(artist_name);
    artist.save();
  }

  auto album = artist.find_album_by_title(album_title);

  if ( album.is_null() )
  {
    // Create album.
    album.title(album_title);
    album.member("artist", json::object{ { "id", artist.id() }, { "name", artist.name() } });
    album.save();

    // Add album to artist albums.
    artist.add_album(album);
    artist.save();
  }

  auto track = album.find_track_by_title_and_number(track_title, tag->track());

  // Set/update track attributes.

  track.title(track_title);
  track.track_number(tag->track());
  track.disc_number(1);

  // Create track source object.
  json::object source{ { "name", "local" }, { "uri", filename } };

  TagLib::FLAC::Properties* properties = file.audioProperties();
  if ( properties )
  {
    track.duration(properties->length());
  }

  TagLib::Ogg::XiphComment* xiph_comment = file.xiphComment();
  if ( xiph_comment )
  {
    auto field_map = xiph_comment->fieldListMap();

    json::object replaygain;

    for ( auto& field : field_map )
    {
      if ( field.first == "TRACK NUMBER" || field.first == "TRACKNUMBER" )
      {
        if ( field.second.size() > 0 ) {
          track.track_number(std::stoi(field.second[0].to8Bit()));
        }
        else {
          std::cerr << "field='" << field.first << "' string list size=" << field.second.size() << std::endl;
        }
      }
      else if ( field.first == "DISC NUMBER" || field.first == "DISCNUMBER" )
      {
        if ( field.second.size() > 0 ) {
          track.disc_number(std::stoi(field.second[0].to8Bit()));
        }
        else {
          std::cerr << "field='" << field.first << "' string list size=" << field.second.size() << std::endl;
        }
      }
      else if ( field.first == "REPLAYGAIN_REFERENCE_LOUDNESS" )
      {
        auto ref_loudness = std::stod(field.second[0].to8Bit());
        replaygain["reference_loudness"] = ref_loudness;
      }
      else if ( field.first == "REPLAYGAIN_TRACK_GAIN" )
      {
        auto gain = std::stod(field.second[0].to8Bit());
        replaygain["track_gain"] = gain;
      }
    }

    if ( !replaygain.empty() ) {
      source["replaygain"] = replaygain;
    }
  }

  const TagLib::List<TagLib::FLAC::Picture*>& images = file.pictureList();

  if ( images.size() > 0 )
  {
    TagLib::FLAC::Picture* image = images[0];

    if ( image->mimeType() == "image/jpeg" )
    {
      auto cover = dm::album_cover::find_by_album_id(album.id());

      if ( cover.is_null() )
      {
        cover.format("jpg");
        cover.data(reinterpret_cast<const char*>(image->data().data()), image->data().size());
        cover.save();
      }
    }
    else
    {
      std::cerr << "unhandled image mime type - " << filename << " images=" << images.size() << ", mime type " << image->mimeType() << std::endl;
    }
  }

  track.artist(artist);
  track.album(album);
  track.source(std::move(source));

  if ( track.id_is_null() )
  {
    // Create track id.
    track.save();
    // Add new track to album.
    album.add_track(track);
    album.save();
  }
  else
  {
    track.save();
  }
}