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

📄 cpi_playlistitem.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 3 页
字号:
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//
void CPLI_SetTrackStackPos(CP_HPLAYLISTITEM hItem, const int iNewPos)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    CP_CHECKOBJECT(pItem);

    pItem->m_iTrackStackPos = iNewPos;
    if(iNewPos == 0)
    {
        pItem->m_cTrackStackPos_AsText[0] = '>';
        pItem->m_cTrackStackPos_AsText[1] = '>';
        pItem->m_cTrackStackPos_AsText[2] = '>';
        pItem->m_cTrackStackPos_AsText[3] = '\0';
    }
    else if(iNewPos == CIC_TRACKSTACK_UNSTACKED)
    {
        pItem->m_cTrackStackPos_AsText[0] = '\0';
    }
    else
    {
        _snprintf(pItem->m_cTrackStackPos_AsText, sizeof(pItem->m_cTrackStackPos_AsText), "%d", iNewPos);
    }
}
//
//
//
void CPLI_CalculateLength(CP_HPLAYLISTITEM hItem)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    const char* pcExtension;

    CP_CHECKOBJECT(pItem);

    pcExtension = CPLI_GetExtension(hItem);

    if(stricmp(pcExtension, ".mp3") == 0
            || stricmp(pcExtension, ".mp2") == 0)
    {
        CPLI_CalculateLength_MP3(pItem);
    }

//    pItem->m_bID3Tag_SaveRequired = TRUE;
    CPL_cb_OnItemUpdated(hItem);
}
//
//
//

//
//
//

//
//
//
void CPLI_CalculateLength_MP3(CPs_PlaylistItem* pItem)
{
    BYTE pbBuffer[0x8000];
    unsigned int iBufferCursor;
    DWORD dwBufferSize;
    HANDLE hFile;
    BOOL bFoundFrameHeader;
    int iBitRate;
    DWORD dwFileSize;
    int iMPEG_version;
    int iLayer;
    BOOL bMono;
    unsigned int iVBRHeader;

    // - Try to open the file
    hFile = CreateFile(pItem->m_pcPath, GENERIC_READ,
                       FILE_SHARE_READ, 0,
                       OPEN_EXISTING, 0, 0);
    dwFileSize = GetFileSize(hFile, NULL);

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

    // Read the first 64K of the file (that should contain the first frame header!)
    ReadFile(hFile, pbBuffer, sizeof(pbBuffer), &dwBufferSize, NULL);
    CloseHandle(hFile);

    iBufferCursor = 0;

    // Skip over a any ID3v2 tag
    {
        CIs_ID3v2Tag* pHeader = (CIs_ID3v2Tag*)(pbBuffer + iBufferCursor);

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

    // Seek to the start of the first frame
    bFoundFrameHeader = FALSE;
    while(iBufferCursor < (dwBufferSize-4))
    {
        if(pbBuffer[iBufferCursor] == 0xFF
                && (pbBuffer[iBufferCursor+1] & 0xE0) == 0xE0)
        {
            bFoundFrameHeader = TRUE;
            break;
        }
        iBufferCursor++;
    }
    if(bFoundFrameHeader == FALSE)
        return;

    // Work out MPEG version
    if( ((pbBuffer[iBufferCursor+1] >> 3) & 0x3) == 0x3)
        iMPEG_version = 1;
    else
        iMPEG_version = 2;

    // Work out layer
    iLayer = 0x4 - ( (pbBuffer[iBufferCursor+1] >> 1) & 0x3);
    if(iLayer == 0)
        return;

    // Work out stereo
    if( (pbBuffer[iBufferCursor+3]>>6) == 0x3)
        bMono = TRUE;
    else
        bMono = FALSE;

    // Work out the VBR header should be
    if(iMPEG_version == 1)
        iVBRHeader = (iBufferCursor+4) + (bMono ? 17 : 32);
    else
        iVBRHeader = (iBufferCursor+4) + (bMono ? 9 : 17);


    // Is this a VBR file
    if( (iBufferCursor+iVBRHeader+12) < dwBufferSize
            && pbBuffer[iVBRHeader]=='X'
            && pbBuffer[iVBRHeader+1]=='i'
            && pbBuffer[iVBRHeader+2]=='n'
            && pbBuffer[iVBRHeader+3]=='g')
    {
        int iNumberOfFrames;
        int iFreq;
        int iDetailedVersion;
        const int aryFrequencies[3][3] = {
                                             {44100, 48000, 32000}, //MPEG 1
                                             {22050, 24000, 16000}, //MPEG 2
                                             {32000, 16000,  8000}  //MPEG 2.5
                                         };

        if( ((pbBuffer[iBufferCursor+1] >> 3) & 0x3) == 0x3)
            iDetailedVersion = 1;
        else if( ((pbBuffer[iBufferCursor+1] >> 3) & 0x3) == 0x2)
            iDetailedVersion = 2;
        else
            iDetailedVersion = 3;

        // Get the number of frames from the Xing header
        iNumberOfFrames = (pbBuffer[iVBRHeader+8] << 24)
                          | (pbBuffer[iVBRHeader+9] << 16)
                          | (pbBuffer[iVBRHeader+10] << 8)
                          | pbBuffer[iVBRHeader+11];

        if( ((pbBuffer[iBufferCursor+2]>>2) & 0x3) == 0x3)
            return;
        iFreq = aryFrequencies[iDetailedVersion-1][(pbBuffer[iBufferCursor+2]>>2) & 0x3];

        CPLI_DecodeLength(pItem, (8 * iNumberOfFrames * 144)/iFreq);
    }
    // Work out the bit rate for a CBR file
    else
    {
        const int aryBitRates[2][3][16] = {
                                              {         //MPEG 2 & 2.5
                                                  {0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0}, //Layer I
                                                  {0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}, //Layer II
                                                  {0,  8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0}  //Layer III
                                              },{       //MPEG 1
                                                  {0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,0}, //Layer I
                                                  {0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,0}, //Layer II
                                                  {0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,0}  //Layer III
                                              }
                                          };

        iBitRate = aryBitRates[2-iMPEG_version][iLayer-1][pbBuffer[iBufferCursor+2]>>4];
        if(iBitRate)
            CPLI_DecodeLength(pItem, (dwFileSize*8)/(iBitRate*1000) );
    }
}
//
//
//
BOOL CPLI_RenameTrack(CP_HPLAYLISTITEM hItem, const CPe_FilenameFormat enFormat)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    char cPath[MAX_PATH];
    char cNewPath[MAX_PATH];
    BOOL bMoved;
    const char* pcExtension;

    CP_CHECKOBJECT(pItem);

    strncpy(cPath, pItem->m_pcPath, MAX_PATH);

    // Remove the filename from the path
    {
        int iLastSlashIDX, iCharIDX;
        iLastSlashIDX = CPC_INVALIDCHAR;

        for(iCharIDX = 0; cPath[iCharIDX]; iCharIDX++)
        {
            if(cPath[iCharIDX] == '\\')
                iLastSlashIDX = iCharIDX;
        }

        if(iLastSlashIDX != CPC_INVALIDCHAR)
            cPath[iLastSlashIDX] = '\0';
    }

    pcExtension = CPLI_GetExtension(hItem);

    // Apply the name format
    {
        char cNewFilename[MAX_PATH];
        const char* pcTitle;
        const char* pcArtist;
        const char* pcAlbum;

        if(pItem->m_pcTrackName)
            pcTitle = pItem->m_pcTrackName;
        else
            pcTitle = "<title>";
        if(pItem->m_pcArtist)
            pcArtist = pItem->m_pcArtist;
        else
            pcArtist = "<title>";
        if(pItem->m_pcAlbum)
            pcAlbum = pItem->m_pcAlbum;
        else
            pcAlbum = "<album>";


        switch(enFormat)
        {
        case rwsArtistAlbumNumberTitle:
            sprintf(cNewFilename, "%s - %s - %02d - %s%s", pcArtist, pcAlbum, (int)pItem->m_cTrackNum, pcTitle, pcExtension);
            break;
        case rwsArtistNumberTitle:
            sprintf(cNewFilename, "%s - %02d - %s%s", pcArtist, (int)pItem->m_cTrackNum, pcTitle, pcExtension);
            break;
        case rwsAlbumNumberTitle:
            sprintf(cNewFilename, "%s - %02d - %s%s", pcAlbum, (int)pItem->m_cTrackNum, pcTitle, pcExtension);
            break;
        case rwsAlbumNumber:
            sprintf(cNewFilename, "%s - %02d%s", pcAlbum, (int)pItem->m_cTrackNum, pcExtension);
            break;
        case rwsNumberTitle:
            sprintf(cNewFilename, "%02d - %s%s", (int)pItem->m_cTrackNum, pcTitle, pcExtension);
            break;
        case rwsTitle:
            sprintf(cNewFilename, "%s%s", pcTitle, pcExtension);
            break;
        default:
            CP_FAIL("Unknown rename format");
        }

        // Replace illegal chars with _
        {
            int iCharIDX;

            for(iCharIDX = 0; cNewFilename[iCharIDX]; iCharIDX++)
            {
                if(cNewFilename[iCharIDX] == '\\'
                        || cNewFilename[iCharIDX] == '/'
                        || cNewFilename[iCharIDX] == ':'
                        || cNewFilename[iCharIDX] == '"')
                {
                    cNewFilename[iCharIDX] = '_';
                }
            }
        }

        sprintf(cNewPath, "%s\\%s", cPath, cNewFilename);
    }

    CP_TRACE2("Rename \"%s\" to \"%s\"", pItem->m_pcPath, cNewPath);
    bMoved = MoveFile(pItem->m_pcPath, cNewPath);
    if(bMoved)
    {
        CPLI_SetPath(pItem, cNewPath);

        // Update interface
        CPL_cb_OnItemUpdated(hItem);
    }

    return bMoved;
}
//
//
//
void CPLI_SetPath(CPs_PlaylistItem* pItem, const char* pcPath)
{
    int iCharIDX, iLastSlashIDX;
    char cFullPath[MAX_PATH];

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

    // Store the full path to the file if this isn't a stream
    if(strnicmp(CIC_HTTPHEADER, pcPath, 5) != 0
            && strnicmp("https:", pcPath, 6) != 0
            && strnicmp("ftp:", pcPath, 4) != 0)
    {
        _fullpath(cFullPath, pcPath, MAX_PATH);
        STR_AllocSetString(&pItem->m_pcPath, cFullPath, FALSE);
    }
    else
        STR_AllocSetString(&pItem->m_pcPath, pcPath, FALSE);

    // Get the filename (the string following the last slash)
    iLastSlashIDX = 0;
    for(iCharIDX = 0; pItem->m_pcPath[iCharIDX]; iCharIDX++)
    {
        if(pItem->m_pcPath[iCharIDX] == '\\')
            iLastSlashIDX = iCharIDX;
    }
    pItem->m_pcFilename = pItem->m_pcPath + iLastSlashIDX + 1;
}
//
//
//
const char* CPLI_GetExtension(const CP_HPLAYLISTITEM hItem)
{
    CPs_PlaylistItem* pItem = (CPs_PlaylistItem*)hItem;
    int iCharIDX;
    const char* pcLastDot;

    CP_CHECKOBJECT(pItem);

    pcLastDot = NULL;
    for(iCharIDX = 0; pItem->m_pcPath[iCharIDX]; iCharIDX++)
    {
        if(pItem->m_pcPath[iCharIDX] == '.')
            pcLastDot = pItem->m_pcPath + iCharIDX;
        // If there is a directory name with a dot in it we don't want that!
        else if(pItem->m_pcPath[iCharIDX] == '\\')
            pcLastDot = NULL;
    }

    // Ensure the string is valid
    if(!pcLastDot)
        pcLastDot = "";

    return pcLastDot;
}
//
//
//
/*
void CPLI_OGG_SkipOverTab(FILE* pFile)
{
    CIs_ID3v2Tag tag;
    int iStreamStart = 0;

    memset(&tag, 0, sizeof(tag));
    fread(&tag, sizeof(tag), 1, pFile);

    if(memcmp(tag.m_cTAG, "ID3", 3) == 0)
    {
        iStreamStart = sizeof(CIs_ID3v2Tag);
        iStreamStart += (tag.m_cSize_Encoded[0] << 21)
                        | (tag.m_cSize_Encoded[1] << 14)
                        | (tag.m_cSize_Encoded[2] << 7)
                        | tag.m_cSize_Encoded[3];
    }

    fseek(pFile, iStreamStart, SEEK_SET);
}*/
//
//
//
/*void CPLI_OGG_DecodeString(char** ppcString, const char* pcNewValue)
{
    int iStringLength;

    if(*ppcString)
        free(*ppcString);

    iStringLength = strlen(pcNewValue);
    *ppcString = malloc(iStringLength + 1);
    memcpy(*ppcString, pcNewValue, iStringLength+1);
}*/

//
//
//
void CPLI_ShrinkFile(HANDLE hFile, const DWORD dwStartOffset, const unsigned int iNumBytes)
{
    BYTE pBuffer[0x10000];
    DWORD dwLength;
    DWORD dwBytesTransferred;
    DWORD dwCursor;

    CP_TRACE1("Shrunking file by %d bytes", iNumBytes);

    dwLength = GetFileSize(hFile, NULL);
    CP_ASSERT( (dwStartOffset+iNumBytes) < dwLength);
    dwCursor = dwStartOffset;
    while((dwCursor+iNumBytes) < dwLength)
    {
        unsigned int iChunkSize;

        iChunkSize = 0x10000;
        if(iChunkSize > dwLength-(dwCursor+iNumBytes) )
            iChunkSize = dwLength-(dwCursor+iNumBytes);

        SetFilePointer(hFile, dwCursor + iNumBytes, NULL, FILE_BEGIN);
        ReadFile(hFile, pBuffer, iChunkSize, &dwBytesTransferred, NULL);
        CP_ASSERT(dwBytesTransferred == iChunkSize);

        SetFilePointer(hFile, dwCursor, NULL, FILE_BEGIN);
        WriteFile(hFile, pBuffer, iChunkSize, &dwBytesTransferred, NULL);

        dwCursor += iChunkSize;
    }

    SetFilePointer(hFile, dwLength - iNumBytes, NULL, FILE_BEGIN);
    SetEndOfFile(hFile);
}
//
//
//
BOOL CPLI_GrowFile(HANDLE hFile, const DWORD dwStartOffset, const unsigned int iNumBytes)
{
    DWORD dwFileSize;
    unsigned int iFileCursor;
    DWORD dwBytesTransferred;
    BYTE* pbReadBlock[0x10000];

    dwFileSize = GetFileSize(hFile, NULL);
    CP_TRACE1("Enlarging file by %d bytes", iNumBytes);

    // Try to write extra data to end of file - if we fail then clip the file and return
    // (so that we don't corrupt the file in short of space situations)
    {
        BYTE* pbExtra;

        pbExtra = (BYTE*)malloc(iNumBytes);
        memset(pbExtra, 0, iNumBytes);
        SetFilePointer(hFile, dwFileSize + iNumBytes, NULL, FILE_BEGIN);
        WriteFile(hFile, pbExtra, iNumBytes, &dwBytesTransferred, NULL);
        if(dwBytesTransferred != iNumBytes)
        {
            // Failed - clip file again and abort tag write
            SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN);
            SetEndOfFile(hFile);
            return FALSE;
        }
    }

    // Enlarge tag
    iFileCursor = dwFileSize;
    while(iFileCursor > dwStartOffset)
    {
        unsigned int iBlockSize;

        iBlockSize = 0x10000;
        if( (iFileCursor - dwStartOffset) < iBlockSize)
            iBlockSize = iFileCursor - dwStartOffset;

        // Read a chunk
        SetFilePointer(hFile, iFileCursor - iBlockSize, NULL, FILE_BEGIN);
        ReadFile(hFile, pbReadBlock, iBlockSize, &dwBytesTransferred, NULL);
        CP_ASSERT(dwBytesTransferred == iBlockSize);

        // Write chunk at offsetted position
        SetFilePointer(hFile, iFileCursor - iBlockSize + iNumBytes, NULL, FILE_BEGIN);
        WriteFile(hFile, pbReadBlock, iBlockSize, &dwBytesTransferred, NULL);
        CP_ASSERT(dwBytesTransferred == iBlockSize);

        iFileCursor -= iBlockSize;
    }

    return TRUE;
}
//
//
//

⌨️ 快捷键说明

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