⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 id3v2.cpp

📁 FreeAMP(MP3播放)程序源代码-用来研究MP3解码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    return true;
}

bool ID3v2::WriteMetaData(const char* url, const MetaData& metadata)
{
    ID3Tag   *pTag;
    ID3Frame *pFrame;
    ID3Field *pField;
    ID3_Err   err;
    char      dummy[20];
    bool      bWriteID3v1, bWriteID3v2;
    luint     whichTags;
    char     *ptr;

    ptr = strrchr(url, '.');
    if (ptr == NULL)
        return false;

    if (strcasecmp(ptr, ".mp3"))
        return false;  

    m_context->prefs->GetPrefBoolean(kWriteID3v1Pref, &bWriteID3v1);
    m_context->prefs->GetPrefBoolean(kWriteID3v2Pref, &bWriteID3v2);

    whichTags = (bWriteID3v1) ? ID3TT_ID3V1 : 0;
    whichTags |= (bWriteID3v2) ? ID3TT_ID3V2 : 0;

    if (!whichTags)
        return true;

    assert(url);

    char path[_MAX_PATH];
    uint32 length = sizeof(path);

    URLToFilePath(url, path, &length);

    pTag = ID3Tag_New();
    ID3Tag_Link(pTag, path);

    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_TITLE);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_TITLE);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Title().c_str());
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Title().c_str());
    }
   
    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_ALBUM);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_ALBUM);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Album().c_str());
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Album().c_str());
    }

    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_LEADARTIST);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_LEADARTIST);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Artist().c_str());
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Artist().c_str());
    }

    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_COMMENT);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_COMMENT);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Comment().c_str());
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, (char *)metadata.Comment().c_str());
    }

    sprintf(dummy, "%d", metadata.Time() * 1000);
    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_SONGLEN);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_SONGLEN);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
    }

    sprintf(dummy, "%d", metadata.Year());
    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_YEAR);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_YEAR);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
    }

    sprintf(dummy, "%d", metadata.Size());
    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_SIZE);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_SIZE);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
    }

    sprintf(dummy, "%d", metadata.Track());
    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_TRACKNUM);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_TRACKNUM);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
    }

    sprintf(dummy, "(12)%s", metadata.Genre().c_str());
    pFrame = ID3Tag_FindFrameWithID(pTag, ID3FID_CONTENTTYPE);
    if (!pFrame)
    {
        pFrame = ID3Frame_NewID(ID3FID_CONTENTTYPE);
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
        ID3Tag_AttachFrame(pTag, pFrame);
    }
    else
    {
        pField = ID3Frame_GetField(pFrame, ID3FN_TEXT);
        ID3Field_SetASCII(pField, dummy);
    }

    err = ID3Tag_UpdateByTagType(pTag, whichTags);

    ID3Tag_Delete(pTag);

    return err == ID3E_NoError;
}

#else

const int supportedVersion = 3;

struct ID3Header
{
   char          tag[3];
   unsigned char versionMajor;
   unsigned char versionRevision;
   unsigned char flags;
   unsigned char size[4];
};
struct FrameHeader
{
   char           tag[4];
   unsigned int   size;
   unsigned short flags;
};
const unsigned frameHeaderSize = 10;

void ID3v2::HandleFrame(char *tag, char *frameData, MetaData *metadata)
{
    char tagName[5];

    strncpy(tagName, tag, 4);
    tagName[4] = 0;

    if (strcmp(tagName, "TIT2") == 0)
        metadata->SetTitle(frameData);

    if (strcmp(tagName, "TALB") == 0)
        metadata->SetAlbum(frameData);

    if (strcmp(tagName, "TPE1") == 0)
        metadata->SetArtist(frameData);

    if (strcmp(tagName, "TCOM") == 0)
        metadata->SetComment(frameData);

    if (strcmp(tagName, "TLEN") == 0)
        metadata->SetTime(atoi(frameData) / 1000);

    if (strcmp(tagName, "TYER") == 0)
        metadata->SetYear(atoi(frameData));

    if (strcmp(tagName, "TRCK") == 0)
        metadata->SetTrack(atoi(frameData));

    if (strcmp(tagName, "TSIZ") == 0)
        metadata->SetSize(atoi(frameData));

    if (strcmp(tagName, "TCON") == 0)
    {
        char genre[255];
        int  genreId, ret;

        genre[0] = 0;
        ret = sscanf(frameData, "(%d)%[^\n]", &genreId, genre);
        if (ret > 0)
        {
            if (ret == 2)
                metadata->SetGenre(genre);
            else
            if (genreId != genreOther)
            {
                LookupGenre(genreId, genre);
                metadata->SetGenre(genre);
            }
        }
        else
        {
            metadata->SetGenre(frameData);
        }
    }
}

bool ID3v2::ReadMetaData(const char* url, MetaData* metadata)
{
    bool        result = false;
    FILE       *inFile;
    char        buffer[1024], *frameData;
    ID3Header   sHead;
    FrameHeader sFrame;
    int         ret;
    int         size;
    Error       error;
    char       *ptr;

    assert(url);
    assert(metadata);

    ptr = strrchr(url, '.');
    if (ptr == NULL)
        return false;

    if (strcasecmp(ptr, ".mp3"))
        return false;  

    char path[_MAX_PATH];
    uint32 length = sizeof(path);

    error = URLToFilePath(url, path, &length);

    if(IsntError(error))
    {
        inFile = fopen(path, "rb");
        if (inFile == NULL)
            return result;

        ret = fread(&sHead, 1, sizeof(ID3Header), inFile);
        if (ret != sizeof(ID3Header))
        {
            fclose(inFile);
            return result;
        }

        if (strncmp(sHead.tag, "ID3", 3))
        {
            fclose(inFile);
            return result;
        }

        if (sHead.versionMajor != supportedVersion)
        {
            fclose(inFile);
            return result;
        }
        size = ( sHead.size[3] & 0x7F       ) |
               ((sHead.size[2] & 0x7F) << 7 ) |
               ((sHead.size[1] & 0x7F) << 14) |
               ((sHead.size[0] & 0x7F) << 21);
        if (sHead.flags & (1 << 6))
        {
            unsigned extHeaderSize;

            if (fread(&extHeaderSize, 1, sizeof(int), inFile) != sizeof(int))
            {
                fclose(inFile);
                return result;
            }
            if (fread(buffer, 1, extHeaderSize, inFile) != extHeaderSize)
            {
                fclose(inFile);
                return result;
            }
        }
        for(; size > 0;)
        {
            if (fread(&sFrame, 1, frameHeaderSize, inFile) != frameHeaderSize)
            {
                fclose(inFile);
                return result;
            }
            sFrame.size = ntohl(sFrame.size);
            frameData = new char[sFrame.size + 1];
            if (fread(frameData, 1, sFrame.size, inFile) != sFrame.size)
            {
                delete frameData;
                fclose(inFile);
                return result;
            }
            frameData[sFrame.size] = 0;
            HandleFrame(sFrame.tag, &frameData[1], metadata);

            delete frameData;
            size -= sizeof(FrameHeader) + sFrame.size;
        }

        fclose(inFile);
    }
    return true;
}

bool ID3v2::WriteMetaData(const char* url, const MetaData& metadata)
{
    bool result = false;
    return result;
}

#endif

void ID3v2::LookupGenre(int genreId, char* genre)
{
    if (genreId < 0 || genreId > genreMax)
    {
        genre[0] = 0;
        return;
    }

    strcpy(genre, genreList[genreId]);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -