예제 #1
0
/*!
 * \brief Remove the albumart image from the file
 *
 * \param filename The music file to remove the albumart
 * \param albumart The Album Art image to remove
 * \returns True if successful
 */
bool MetaIOID3::removeAlbumArt(const QString &filename, const AlbumArtImage *albumart)
{
    if (filename.isEmpty() || !albumart)
        return false;

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    TagLib::MPEG::File *mpegfile = OpenFile(filename);

    if (!mpegfile)
        return false;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return false;
    }

    AttachedPictureFrame *apic = findAPIC(tag, type, QStringToTString(albumart->description));
    if (!apic)
    {
        delete mpegfile;
        return false;
    }

    tag->removeFrame(apic);

    mpegfile->save();
    delete mpegfile;

    return true;
}
예제 #2
0
/*!
* \brief Writes metadata common to all tag formats to the tag
*
* \param tag A pointer to the tag
* \param metadata Pointer to the metadata
*/
void MetaIOTagLib::WriteGenericMetadata(Tag *tag,  const Metadata *metadata)
{
    if (!tag || !metadata)
        return;

    if (!metadata->Artist().isEmpty())
        tag->setArtist(QStringToTString(metadata->Artist()));
    
    if (!metadata->Title().isEmpty())
        tag->setTitle(QStringToTString(metadata->Title()));
    
    if (!metadata->Album().isEmpty())
        tag->setAlbum(QStringToTString(metadata->Album()));
    
    if (metadata->Year() > 999 && metadata->Year() < 10000) // 4 digit year.
        tag->setYear(metadata->Year());
    
    if (!metadata->Genre().isEmpty())
        tag->setGenre(QStringToTString(metadata->Genre()));
    
    if (0 != metadata->Track())
        tag->setTrack(metadata->Track());
}
예제 #3
0
/*!
 * \brief Remove the albumart image from the file
 *
 * \param filename The music file to remove the albumart
 * \param albumart The Album Art image to remove
 * \returns True if successful
 */
bool MetaIOID3::removeAlbumArt(const QString &filename,
                               const AlbumArtImage *albumart)
{
    if (filename.isEmpty() || !albumart)
        return false;

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->m_imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST:
            type = AttachedPictureFrame::Artist;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    if (!OpenFile(filename, true))
        return false;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag();

    if (!tag)
        return false;

    AttachedPictureFrame *apic = findAPIC(tag, type,
                                    QStringToTString(albumart->m_description));
    if (!apic)
        return false;

    tag->removeFrame(apic);

    if (!SaveFile())
        return false;

    return true;
}
예제 #4
0
/*!
 * \copydoc MetaIO::write()
 */
bool MetaIOFLACVorbis::write(Metadata* mdata)
{
    if (!mdata)
        return false;

    TagLib::FLAC::File *flacfile = OpenFile(mdata->Filename());
    
    if (!flacfile)
        return false;
    
    TagLib::Ogg::XiphComment *tag = flacfile->xiphComment();
    
    if (!tag)
    {
        delete flacfile;
        return false;
    }
    
    WriteGenericMetadata(tag, mdata);

    // Compilation
    if (mdata->Compilation())
    {
        tag->addField("MUSICBRAINZ_ALBUMARTISTID",
                          MYTH_MUSICBRAINZ_ALBUMARTIST_UUID, true);
        tag->addField("COMPILATION_ARTIST",
                        QStringToTString(mdata->CompilationArtist()), true);
    }
    else
    {
        // Don't remove the musicbrainz field unless it indicated a compilation
        if (tag->contains("MUSICBRAINZ_ALBUMARTISTID") &&
            (tag->fieldListMap()["MUSICBRAINZ_ALBUMARTISTID"].toString() ==
                MYTH_MUSICBRAINZ_ALBUMARTIST_UUID))
        {
            tag->removeField("MUSICBRAINZ_ALBUMARTISTID");
        }
        tag->removeField("COMPILATION_ARTIST");
    }

    bool result = flacfile->save();

    if (flacfile)
        delete flacfile;

    return (result);
}
예제 #5
0
bool MetaIOID3::writeLastPlay(TagLib::ID3v2::Tag *tag, QDateTime lastPlay)
{
    if (!tag)
        return false;

    // MythTV Specific Rating Tag
    UserTextIdentificationFrame *txxx = find(tag, "MythTVLastPlayed");

    if (!txxx)
    {
        txxx = new UserTextIdentificationFrame();
        tag->addFrame(txxx);
        txxx->setDescription("MythTVLastPlayed");
    }
    lastPlay.setTimeSpec(Qt::UTC);
    txxx->setText(QStringToTString(lastPlay.toString(Qt::ISODate)));

    return true;
}
예제 #6
0
bool MetaIOID3::changeImageType(const QString &filename,
                                const AlbumArtImage* albumart,
                                ImageType newType)
{
    if (!albumart)
        return false;

    if (albumart->m_imageType == newType)
        return true;

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->m_imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST:
            type = AttachedPictureFrame::Artist;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    if (!OpenFile(filename, true))
        return false;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag();

    if (!tag)
        return false;

    AttachedPictureFrame *apic = findAPIC(tag, type,
                                    QStringToTString(albumart->m_description));
    if (!apic)
        return false;

    // set the new image type
    switch (newType)
    {
        case IT_FRONTCOVER:
            apic->setType(AttachedPictureFrame::FrontCover);
            break;
        case IT_BACKCOVER:
            apic->setType(AttachedPictureFrame::BackCover);
            break;
        case IT_CD:
            apic->setType(AttachedPictureFrame::Media);
            break;
        case IT_INLAY:
            apic->setType(AttachedPictureFrame::LeafletPage);
            break;
        case IT_ARTIST:
            apic->setType(AttachedPictureFrame::Artist);
            break;
        default:
            apic->setType(AttachedPictureFrame::Other);
            break;
    }

    if (!SaveFile())
        return false;

    return true;
}
예제 #7
0
/*!
 * \brief Write the albumart image to the file
 *
 * \param filename The music file to add the albumart
 * \param albumart The Album Art image to write
 * \returns True if successful
 *
 * \note We always save the image in JPEG format
 */
bool MetaIOID3::writeAlbumArt(const QString &filename,
                              const AlbumArtImage *albumart)
{
    if (filename.isEmpty() || !albumart)
        return false;

    // load the image into a QByteArray
    QImage image(albumart->m_filename);
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "JPEG");

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->m_imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST:
            type = AttachedPictureFrame::Artist;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    if (!OpenFile(filename, true))
        return false;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag();

    if (!tag)
        return false;

    AttachedPictureFrame *apic = findAPIC(tag, type,
                                    QStringToTString(albumart->m_description));

    if (!apic)
    {
        apic = new AttachedPictureFrame();
        tag->addFrame(apic);
        apic->setType(type);
    }

    QString mimetype = "image/jpeg";

    TagLib::ByteVector bytevector;
    bytevector.setData(imageData.data(), imageData.size());

    apic->setMimeType(QStringToTString(mimetype));
    apic->setPicture(bytevector);
    apic->setDescription(QStringToTString(albumart->m_description));

    if (!SaveFile())
        return false;

    return true;
}
예제 #8
0
/*!
 * \copydoc MetaIO::write()
 */
bool MetaIOID3::write(const QString &filename, MusicMetadata* mdata)
{
    if (filename.isEmpty())
        return false;

    if (!OpenFile(filename, true))
        return false;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag();

    if (!tag)
        return false;

    WriteGenericMetadata(tag, mdata);

    // MythTV rating and playcount, stored in POPM frame
    writeRating(tag, mdata->Rating());
    writePlayCount(tag, mdata->PlayCount());
    writeLastPlay(tag, mdata->LastPlay());

    // MusicBrainz ID
    UserTextIdentificationFrame *musicbrainz = nullptr;
    musicbrainz = find(tag, "MusicBrainz Album Artist Id");

    if (mdata->Compilation())
    {

        if (!musicbrainz)
        {
            musicbrainz = new UserTextIdentificationFrame(TagLib::String::UTF8);
            tag->addFrame(musicbrainz);
            musicbrainz->setDescription("MusicBrainz Album Artist Id");
        }

        musicbrainz->setText(MYTH_MUSICBRAINZ_ALBUMARTIST_UUID);
    }
    else if (musicbrainz)
        tag->removeFrame(musicbrainz);

    // Compilation Artist Frame (TPE4/2)
    if (!mdata->CompilationArtist().isEmpty())
    {
        TextIdentificationFrame *tpe4frame = nullptr;
        TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
        if (!tpelist.isEmpty())
            tpe4frame = (TextIdentificationFrame *)tpelist.front();

        if (!tpe4frame)
        {
            tpe4frame = new TextIdentificationFrame(TagLib::ByteVector("TPE4"),
                                                    TagLib::String::UTF8);
            tag->addFrame(tpe4frame);
        }
        tpe4frame->setText(QStringToTString(mdata->CompilationArtist()));


        TextIdentificationFrame *tpe2frame = nullptr;
        tpelist = tag->frameListMap()["TPE2"];
        if (!tpelist.isEmpty())
            tpe2frame = (TextIdentificationFrame *)tpelist.front();

        if (!tpe2frame)
        {
            tpe2frame = new TextIdentificationFrame(TagLib::ByteVector("TPE2"),
                                                    TagLib::String::UTF8);
            tag->addFrame(tpe2frame);
        }
        tpe2frame->setText(QStringToTString(mdata->CompilationArtist()));
    }

    if (!SaveFile())
        return false;

    return true;
}
예제 #9
0
/*!
 * \copydoc MetaIO::write()
 */
bool MetaIOID3::write(Metadata* mdata)
{
    TagLib::MPEG::File *mpegfile = OpenFile(mdata->Filename());

    if (!mpegfile)
        return false;

    TagLib::ID3v2::Tag *tag = mpegfile->ID3v2Tag();

    if (!tag)
    {
        delete mpegfile;
        return false;
    }

    WriteGenericMetadata(tag, mdata);

    // MythTV rating and playcount, stored in POPM frame
    writeRating(tag, mdata->Rating());
    writePlayCount(tag, mdata->PlayCount());

    // MusicBrainz ID
    UserTextIdentificationFrame *musicbrainz = NULL;
    musicbrainz = find(tag, "MusicBrainz Album Artist Id");

    if (mdata->Compilation())
    {

        if (!musicbrainz)
        {
            musicbrainz = new UserTextIdentificationFrame(TagLib::String::UTF8);
            tag->addFrame(musicbrainz);
            musicbrainz->setDescription("MusicBrainz Album Artist Id");
        }

        musicbrainz->setText(MYTH_MUSICBRAINZ_ALBUMARTIST_UUID);
    }
    else if (musicbrainz)
        tag->removeFrame(musicbrainz);

    // Compilation Artist Frame (TPE4/2)
    if (!mdata->CompilationArtist().isEmpty())
    {
        TextIdentificationFrame *tpe4frame = NULL;
        TagLib::ID3v2::FrameList tpelist = tag->frameListMap()["TPE4"];
        if (!tpelist.isEmpty())
            tpe4frame = (TextIdentificationFrame *)tpelist.front();

        if (!tpe4frame)
        {
            tpe4frame = new TextIdentificationFrame(TagLib::ByteVector("TPE4"),
                                                    TagLib::String::UTF8);
                                                    tag->addFrame(tpe4frame);
        }
        tpe4frame->setText(QStringToTString(mdata->CompilationArtist()));


        TextIdentificationFrame *tpe2frame = NULL;
        tpelist = tag->frameListMap()["TPE2"];
        if (!tpelist.isEmpty())
            tpe2frame = (TextIdentificationFrame *)tpelist.front();

        if (!tpe2frame)
        {
            tpe2frame = new TextIdentificationFrame(TagLib::ByteVector("TPE2"),
                                                    TagLib::String::UTF8);
                                                    tag->addFrame(tpe2frame);
        }
        tpe2frame->setText(QStringToTString(mdata->CompilationArtist()));
    }

    bool result = mpegfile->save();

    delete mpegfile;

    return result;
}
예제 #10
0
 TagLib::String operator[](const char *key) const
 {
     return QStringToTString(m_info["Comment"][key].value().toString());
 }
예제 #11
0
void MetaDetector::updateMediaFileTagCodec(MediaMeta *meta, const QByteArray &codecName, bool forceEncode)
{
    Q_ASSERT(meta != nullptr);

    if (meta->localPath.isEmpty()) {
        qCritical() << "meta localPath is empty:" << meta->title << meta->hash;
        return ;
    }

    QByteArray detectByte;
    QByteArray detectCodec = codecName;
    auto mediaPath = QStringToTString(meta->localPath);
#ifdef _WIN32
    TagLib::FileRef f(meta->localPath.toStdWString().c_str());
#else
    TagLib::FileRef f(meta->localPath.toStdString().c_str());
#endif
    TagLib::Tag *tag = f.tag();

    if (!f.file()) {
        qCritical() << "TagLib: open file failed:" << meta->localPath << f.file();
    }

    if (!tag) {
        qWarning() << "TagLib: no tag for media file" << meta->localPath;
        return;
    }

    bool encode = true;
    encode &= tag->title().isNull() ? true : tag->title().isLatin1();
    encode &= tag->artist().isNull() ? true : tag->artist().isLatin1();
    encode &= tag->album().isNull() ? true : tag->album().isLatin1();

    if (forceEncode) {
        encode = true;
    }

    if (encode) {
        if (detectCodec.isEmpty()) {
            detectByte += tag->title().toCString();
            detectByte += tag->artist().toCString();
            detectByte += tag->album().toCString();
            detectCodec = detectEncodings(detectByte).value(0);
//            qDebug() << "detect codec" << detectEncodings(detectByte);
        }

//        qDebug() << "convert to" << detectCodec;
//        QTextCodec *codec = QTextCodec::codecForName(detectCodec);
//        meta->album = codec->toUnicode(tag->album().to8Bit().c_str());
//        meta->artist = codec->toUnicode(tag->artist().to8Bit().c_str());
//        meta->title = codec->toUnicode(tag->title().to8Bit().c_str());

//#ifndef true
//        qDebug() << "convert to" << detectCodec << QTextCodec::availableCodecs();
        const size_t buflen = 1024 * 10;
        char buf[buflen];
        UErrorCode err = U_ZERO_ERROR;
        int32_t len = ucnv_convert("utf-8", detectCodec, buf, buflen, tag->title().toCString(), -1, &err);
        meta->title = QString::fromUtf8(buf);
//        qDebug() << len <<  QString::fromUtf8(buf) << buf << u_errorName(err);

        err = U_ZERO_ERROR;
        len = ucnv_convert("utf-8", detectCodec, buf, buflen, tag->artist().toCString(), -1, &err);
        meta->artist = QString::fromUtf8(buf);
//        qDebug() << len <<  QString::fromUtf8(buf) << buf << u_errorName(err);

        err = U_ZERO_ERROR;
        len = ucnv_convert("utf-8", detectCodec, buf, buflen, tag->album().toCString(), -1, &err);
        meta->album = QString::fromUtf8(buf);
//        qDebug() << len <<  QString::fromUtf8(buf) << buf << u_errorName(err);
        Q_UNUSED(len);
//#endif
    } else {
        meta->album = TStringToQString(tag->album());
        meta->artist = TStringToQString(tag->artist());
        meta->title = TStringToQString(tag->title());
    }

    if (meta->title.isEmpty()) {
        QFileInfo localFi(meta->localPath);
        meta->title = localFi.completeBaseName();
    }
}