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

📄 cpi_playlistitem.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 3 页
字号:
        if(iFrameSize > iTagDataToRead)
            return;

        pFrameData = malloc(iFrameSize+1);
        if(!ReadFile(hFile, pFrameData, iFrameSize, &dwBytesRead, NULL)) return;
        pFrameData[iFrameSize] = '\0';

        // Decode frames
        if(memcmp(ID3v2Frame.m_cFrameID, "TIT2", 4) == 0)
            pItem->m_pcTrackName = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
        else if(memcmp(ID3v2Frame.m_cFrameID, "TPE1", 4) == 0)
            pItem->m_pcArtist = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
        else if(memcmp(ID3v2Frame.m_cFrameID, "TALB", 4) == 0)
            pItem->m_pcAlbum = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
        else if(memcmp(ID3v2Frame.m_cFrameID, "TRCK", 4) == 0)
        {
            pItem->m_pcTrackNum_AsText = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
            if(pItem->m_pcTrackNum_AsText)
                pItem->m_cTrackNum = (unsigned char)atoi(pItem->m_pcTrackNum_AsText);
        }
        else if(memcmp(ID3v2Frame.m_cFrameID, "TYER", 4) == 0)
            pItem->m_pcYear = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
        else if(memcmp(ID3v2Frame.m_cFrameID, "TENC", 4) == 0)
            pItem->m_pcComment = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
        else if(memcmp(ID3v2Frame.m_cFrameID, "TCON", 4) == 0)
        {
            char* pcGenre = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
            if(pcGenre)
            {
                // Search for this genre among the ID3v1 genres (don't read it if we cannot find it)
                int iGenreIDX;
                for(iGenreIDX = 0; iGenreIDX < CIC_NUMGENRES; iGenreIDX++)
                {
                    if(stricmp(pcGenre, glb_pcGenres[iGenreIDX]) == 0)
                    {
                        pItem->m_cGenre = (unsigned char)iGenreIDX;
                        break;
                    }
                }
                free(pcGenre);
            }
        }
        else if(memcmp(ID3v2Frame.m_cFrameID, "TLEN", 4) == 0)
        {
            char* pcLength = CPLI_ID3v2_DecodeString(pFrameData, iFrameSize);
            if(pcLength)
            {
                CPLI_DecodeLength(pItem, atoi(pcLength)/1000);
                free(pcLength);
            }
        }
#ifdef _DEBUG
        /*
        else if(ID3v2Frame.m_cFrameID[0] == 'T')
        	CP_TRACE2("Text frame %4s \"%s\"", ID3v2Frame.m_cFrameID, pFrameData+1);
        else
        	CP_TRACE1("Any old frame %4s", ID3v2Frame.m_cFrameID);
        */
#endif
        free(pFrameData);
        iTagDataToRead -= iFrameSize + sizeof(ID3v2Frame);
    }

    pItem->m_enTagType = ttID3v2;
}
//
//
//
void CPLI_ReadTag_ID3v1(CPs_PlaylistItem* pItem, HANDLE hFile)
{
    DWORD dwBytesRead;
    CIs_ID3Tag ID3;

    SetFilePointer(hFile, 0-sizeof(ID3), NULL, FILE_END);
    ReadFile(hFile, &ID3, sizeof(ID3), &dwBytesRead, NULL);

    // Not enough file data returned - or the data returned does not look like an ID3
    if(dwBytesRead != sizeof(ID3) || memcmp(ID3.m_cTAG, "TAG", 3) != 0)
        return;

    // Decode the fixed strings into our dynamic strings
    CPLII_RemoveTagInfo(pItem);
    pItem->m_pcTrackName = DecodeID3String(ID3.m_cSong, 30);
    pItem->m_pcArtist = DecodeID3String(ID3.m_cArtist, 30);
    pItem->m_pcAlbum = DecodeID3String(ID3.m_cAlbum, 30);
    pItem->m_pcYear = DecodeID3String(ID3.m_cYear, 4);

    // ID3v1.1 - If the 29th byte of the comment is 0 then the 30th byte is the track num
    // ** Some dodgy implementations of ID3v1.1 just slap a <32 char byte at position 30 and hope
    //    for the best - handle these too <hmph!>
    if(ID3.m_cComment[28] == '\0' || ID3.m_cComment[29] < 32)
    {
        char cTempString[33];

        pItem->m_pcComment = DecodeID3String(ID3.m_cComment, 28);
        pItem->m_cTrackNum = ID3.m_cComment[29];

        if(pItem->m_cTrackNum != CIC_INVALIDTRACKNUM)
        {
            itoa(pItem->m_cTrackNum, cTempString, 10);
            pItem->m_pcTrackNum_AsText = (char*)malloc(CPC_TRACKNUMASTEXTBUFFERSIZE);
            strncpy(pItem->m_pcTrackNum_AsText, cTempString, CPC_TRACKNUMASTEXTBUFFERSIZE);
        }
    }
    else
    {
        pItem->m_pcComment = DecodeID3String(ID3.m_cComment, 30);
        pItem->m_cTrackNum = CIC_INVALIDTRACKNUM;
    }

    if(ID3.m_cGenre < CIC_NUMGENRES)
        pItem->m_cGenre = ID3.m_cGenre;
    pItem->m_enTagType = ttID3v1;
}
//
//
//
BOOL CPLI_IsTagDirty(CP_HPLAYLISTITEM hItem)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;

    CP_CHECKOBJECT(pItem);
    return pItem->m_bID3Tag_SaveRequired;
}
//
//
//
void CPLI_WriteTag(CP_HPLAYLISTITEM hItem)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    HANDLE hFile;

    CP_CHECKOBJECT(pItem);
    if(pItem->m_bID3Tag_SaveRequired == FALSE)
        return;
	if(stricmp(".ogg", CPLI_GetExtension(hItem)) != 0 && 
		stricmp(".mp3", CPLI_GetExtension(hItem)) !=0)
		return;
    // Try to open the file
    hFile = CreateFile(pItem->m_pcPath, GENERIC_READ | GENERIC_WRITE,
                       FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                       OPEN_EXISTING, 0, 0);

    // Cannot open - fail silently
    if(hFile == INVALID_HANDLE_VALUE)
        return;

    pItem->m_bID3Tag_SaveRequired = FALSE;

	if (stricmp(".mp3", CPLI_GetExtension(hItem)) ==0)
    {
        CPLI_WriteTag_ID3v1(pItem, hFile);
        if(options.support_id3v2)
            CPLI_WriteTag_ID3v2(pItem, hFile);
    }

    CloseHandle(hFile);
}
//
//
//
void CPLI_WriteTag_ID3v1(CPs_PlaylistItem* pItem, HANDLE hFile)
{
    DWORD dwBytesTransferred;
    CIs_ID3Tag ID3;
    char cTagMagic[3];

    // Build the tag (of ID3v1.1 format)
    memset(&ID3, 32, sizeof(ID3));
    memcpy(ID3.m_cTAG, "TAG", 3);
    if(pItem->m_pcTrackName)
        strncpy(ID3.m_cSong, pItem->m_pcTrackName, 30);
    if(pItem->m_pcArtist)
        strncpy(ID3.m_cArtist, pItem->m_pcArtist, 30);
    if(pItem->m_pcAlbum)
        strncpy(ID3.m_cAlbum, pItem->m_pcAlbum, 30);
    if(pItem->m_pcYear)
        strncpy(ID3.m_cYear, pItem->m_pcYear, 4);
    if(pItem->m_pcComment)
	if(strlen(pItem->m_pcComment)>28)
	{
        strncpy(ID3.m_cComment, pItem->m_pcComment, 30);
	}else
	{
        strncpy(ID3.m_cComment, pItem->m_pcComment, 28);
    ID3.m_cComment[28] = '\0';
    ID3.m_cComment[29] = pItem->m_cTrackNum;
	}
    ID3.m_cGenre = pItem->m_cGenre;

    // Set the file pointer to the end of the file (or the start of the tag if there is one already)
    SetFilePointer(hFile, 0-sizeof(ID3), NULL, FILE_END);
    ReadFile(hFile, cTagMagic, sizeof(cTagMagic), &dwBytesTransferred, NULL);
    if(memcmp(cTagMagic, "TAG", 3) == 0)
        SetFilePointer(hFile, 0-sizeof(ID3), NULL, FILE_END);
    else
        SetFilePointer(hFile, 0, NULL, FILE_END);

    WriteFile(hFile, &ID3, sizeof(ID3), &dwBytesTransferred, NULL);
}
//
//
//
void CPLI_ID3v2_WriteSyncSafeInt(char cDest[4], const int iSource)
{
    cDest[0] = (iSource>>21) & 0x7F;
    cDest[1] = (iSource>>14) & 0x7F;
    cDest[2] = (iSource>>7) & 0x7F;
    cDest[3] = iSource & 0x7F;
}
//
//
//
void CPLI_ID3v2_WriteTextFrame(BYTE** ppDest, const char pcTag[4], const char* pcString)
{
    CIs_ID3v2Frame* pFrame = (CIs_ID3v2Frame*)*ppDest;
    BYTE* pFrameData;
    int iFrameDataLength;

    iFrameDataLength = strlen(pcString) + 1; // 1-byte for encoding

    memcpy(pFrame->m_cFrameID, pcTag, sizeof(pcTag));
    CPLI_ID3v2_WriteSyncSafeInt(pFrame->m_cSize_Encoded, iFrameDataLength);
    pFrame->m_cFlags = 0x0;

    // Write frame data
    pFrameData = ((*ppDest) + sizeof(CIs_ID3v2Frame));
    pFrameData[0] = 0x0;
    memcpy(pFrameData + 1, pcString, iFrameDataLength-1);

    *ppDest += iFrameDataLength + sizeof(CIs_ID3v2Frame);
}
//
//
//
void CPLI_WriteTag_ID3v2(CPs_PlaylistItem* pItem, HANDLE hFile)
{
    unsigned int iTagDataLength;
    unsigned int iExistingTagLength;
    DWORD dwBytesTransferred;
    char atiobuffer[33];
    BYTE* pTag;
    BYTE* pTag_Cursor;

    // Work out the size of the data in the tag frames
    iTagDataLength = 0;
    if(pItem->m_pcTrackName)
        iTagDataLength += strlen(pItem->m_pcTrackName) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_pcArtist)
        iTagDataLength += strlen(pItem->m_pcArtist) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_pcAlbum)
        iTagDataLength += strlen(pItem->m_pcAlbum) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_pcYear)
        iTagDataLength += strlen(pItem->m_pcYear) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_pcComment)
        iTagDataLength += strlen(pItem->m_pcComment) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_cGenre != CIC_INVALIDGENRE)
        iTagDataLength += strlen(glb_pcGenres[pItem->m_cGenre]) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_cTrackNum != CIC_INVALIDTRACKNUM)
        iTagDataLength += strlen(itoa(pItem->m_cTrackNum, atiobuffer, 10)) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header
    if(pItem->m_iTrackLength != 0)
        iTagDataLength += strlen(itoa(pItem->m_iTrackLength*1000, atiobuffer, 10)) + 1 + sizeof(CIs_ID3v2Frame); // 1-byte for encoding and a frame header

    // Add ID3v2 overhead
    iTagDataLength += sizeof(CIs_ID3v2Tag);

    // Quantise tag to the nearest 1K
    iTagDataLength = ((iTagDataLength>>10) + 1) << 10;

    // Is there a tag big enough in the file
    {
        CIs_ID3v2Tag existingtagheader;

        SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
        ReadFile(hFile, &existingtagheader, sizeof(existingtagheader), &dwBytesTransferred, NULL);

        if(memcmp(existingtagheader.m_cTAG, "ID3", 3) == 0)
        {
            iExistingTagLength = (existingtagheader.m_cSize_Encoded[0] << 21)
                                 | (existingtagheader.m_cSize_Encoded[1] << 14)
                                 | (existingtagheader.m_cSize_Encoded[2] << 7)
                                 | existingtagheader.m_cSize_Encoded[3];
            iExistingTagLength += sizeof(CIs_ID3v2Tag); // count the header
            if(iExistingTagLength > iTagDataLength)
                iTagDataLength = iExistingTagLength;
        }
        else
            iExistingTagLength = 0;
    }

    // Do we need to enlarge the file?
    if(iExistingTagLength < iTagDataLength)
    {
        if(CPLI_GrowFile(hFile, 0, iTagDataLength-iExistingTagLength) == FALSE)
            return;
    }

    // Build tag
    pTag = malloc(iTagDataLength);
    memset(pTag, 0, iTagDataLength); // ** must do this as all padding should be 0x00
    pTag_Cursor = pTag;

    // Header
    {
        CIs_ID3v2Tag* pHeader = (CIs_ID3v2Tag*)pTag_Cursor;
        int iSizeLessHeader = iTagDataLength - sizeof(CIs_ID3v2Tag);

        pHeader->m_cTAG[0] = 'I';
        pHeader->m_cTAG[1] = 'D';
        pHeader->m_cTAG[2] = '3';

        pHeader->m_cVersion[0] = 0x4;
        pHeader->m_cVersion[1] = 0x0;

        pHeader->m_cFlags = 0x0;

        CPLI_ID3v2_WriteSyncSafeInt(pHeader->m_cSize_Encoded, iSizeLessHeader);
        pTag_Cursor += sizeof(CIs_ID3v2Tag);
    }

    // Frames
    if(pItem->m_pcTrackName)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TIT2", pItem->m_pcTrackName);
    if(pItem->m_pcArtist)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TPE1", pItem->m_pcArtist);
    if(pItem->m_pcAlbum)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TALB", pItem->m_pcAlbum);
    if(pItem->m_pcYear)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TYER", pItem->m_pcYear);
    if(pItem->m_pcComment)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TENC", pItem->m_pcComment);
    if(pItem->m_cGenre != CIC_INVALIDGENRE)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TCON", glb_pcGenres[pItem->m_cGenre]);
    if(pItem->m_cTrackNum != CIC_INVALIDTRACKNUM)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TRCK", itoa(pItem->m_cTrackNum, atiobuffer, 10));
    if(pItem->m_iTrackLength != 0)
        CPLI_ID3v2_WriteTextFrame(&pTag_Cursor, "TLEN", itoa(pItem->m_iTrackLength * 1000, atiobuffer, 10));

    // Output tag
    SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
    WriteFile(hFile, pTag, iTagDataLength, &dwBytesTransferred, NULL);
    CP_ASSERT(dwBytesTransferred == iTagDataLength);
}
//
//
//
CPe_ReadWriteState CPLI_GetReadWriteState(const CP_HPLAYLISTITEM hItem)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    HANDLE hFile;
    CP_CHECKOBJECT(pItem);

    // We will check this every time (and not cache the result) because the
    // file could have been played with outside of CoolPlayer

    // Try to open the file in RW mode
    hFile = CreateFile(pItem->m_pcPath, GENERIC_READ | GENERIC_WRITE,
                       FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                       OPEN_EXISTING, 0, 0);
    if(hFile != INVALID_HANDLE_VALUE)
    {
        // Only cache
        CloseHandle(hFile);
        return rwsReadWrite;
    }

    // That didn't work - try a RO open
    hFile = CreateFile(pItem->m_pcPath, GENERIC_READ,
                       FILE_SHARE_READ | FILE_SHARE_WRITE, 0,
                       OPEN_EXISTING, 0, 0);
    if(hFile != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hFile);
        return rwsReadOnly;
    }

    return rwsBadFile;
}
//
//
//
void CPLI_SetArtist(CP_HPLAYLISTITEM hItem, const char* pcNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    STR_AllocSetString(&pItem->m_pcArtist, pcNewValue, TRUE);
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetAlbum(CP_HPLAYLISTITEM hItem, const char* pcNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    STR_AllocSetString(&pItem->m_pcAlbum, pcNewValue, TRUE);
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetTrackName(CP_HPLAYLISTITEM hItem, const char* pcNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    STR_AllocSetString(&pItem->m_pcTrackName, pcNewValue, TRUE);
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetYear(CP_HPLAYLISTITEM hItem, const char* pcNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    STR_AllocSetString(&pItem->m_pcYear, pcNewValue, TRUE);
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetGenreIDX(CP_HPLAYLISTITEM hItem, const unsigned char iNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    pItem->m_cGenre = iNewValue;
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetTrackNum(CP_HPLAYLISTITEM hItem, const unsigned char iNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    char cTempString[33];
    CP_CHECKOBJECT(pItem);

    pItem->m_cTrackNum = iNewValue;
    if(pItem->m_cTrackNum != CIC_INVALIDTRACKNUM)
    {
        if(pItem->m_pcTrackNum_AsText)
            free(pItem->m_pcTrackNum_AsText);

        pItem->m_pcTrackNum_AsText = (char*)malloc(CPC_TRACKNUMASTEXTBUFFERSIZE);
        itoa(pItem->m_cTrackNum, cTempString, 10);
        strncpy(pItem->m_pcTrackNum_AsText, cTempString, CPC_TRACKNUMASTEXTBUFFERSIZE);
    }
    else
    {
        if(pItem->m_pcTrackNum_AsText)
        {
            free(pItem->m_pcTrackNum_AsText);
            pItem->m_pcTrackNum_AsText = NULL;
        }
    }
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetTrackNum_AsText(CP_HPLAYLISTITEM hItem, const char* pcNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    if(pcNewValue[0] == '\0')
        pItem->m_cTrackNum = CIC_INVALIDTRACKNUM;
    else
        pItem->m_cTrackNum = (unsigned char)atoi(pcNewValue);

    if(pItem->m_pcTrackNum_AsText)
        free(pItem->m_pcTrackNum_AsText);

    pItem->m_pcTrackNum_AsText = (char*)malloc(CPC_TRACKNUMASTEXTBUFFERSIZE);
    strncpy(pItem->m_pcTrackNum_AsText, pcNewValue, CPC_TRACKNUMASTEXTBUFFERSIZE);
    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetComment(CP_HPLAYLISTITEM hItem, const char* pcNewValue)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    STR_AllocSetString(&pItem->m_pcComment, pcNewValue, TRUE);
    pItem->m_bID3Tag_SaveRequired = TRUE;

⌨️ 快捷键说明

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