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

📄 qcdmp4tag.cpp

📁 BHE的解码程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include <mp4.h>
#include <faad.h>
#include "QCDTagsDLL.h"


//..............................................................................
// Global Variables

typedef struct tag
{
    char *item;
    char *value;
} tag;

typedef struct medialib_tags
{
    struct tag *tags;
    unsigned int count;
} medialib_tags;

int tag_add_field(medialib_tags *tags, const char *item, const char *value)
{
    void *backup = (void *)tags->tags;

    if (!item || (item && !*item) || !value) return 0;

    tags->tags = (struct tag *)realloc(tags->tags, (tags->count+1) * sizeof(tag));
    if (!tags->tags) {
        if (backup) free(backup);
        return 0;
    }
    else
    {
        int i_len = strlen(item);
        int v_len = strlen(value);

        tags->tags[tags->count].item = (char *)malloc(i_len+1);
        tags->tags[tags->count].value = (char *)malloc(v_len+1);

        if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
        {
            if (!tags->tags[tags->count].item) free (tags->tags[tags->count].item);
            if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
            tags->tags[tags->count].item = NULL;
            tags->tags[tags->count].value = NULL;
            return 0;
        }

        memcpy(tags->tags[tags->count].item, item, i_len);
        memcpy(tags->tags[tags->count].value, value, v_len);
        tags->tags[tags->count].item[i_len] = '\0';
        tags->tags[tags->count].value[v_len] = '\0';

        tags->count++;
        return 1;
    }
}

int tag_set_field(medialib_tags *tags, const char *item, const char *value)
{
    unsigned int i;

    if (!item || (item && !*item) || !value) return 0;

    for (i = 0; i < tags->count; i++)
    {
        if (!stricmp(tags->tags[i].item, item))
        {
            void *backup = (void *)tags->tags[i].value;
            int v_len = strlen(value);

            tags->tags[i].value = (char *)realloc(tags->tags[i].value, v_len+1);
            if (!tags->tags[i].value)
            {
                if (backup) free(backup);
                return 0;
            }

            memcpy(tags->tags[i].value, value, v_len);
            tags->tags[i].value[v_len] = '\0';

            return 1;
        }
    }

    return tag_add_field(tags, item, value);
}

void tag_delete(medialib_tags *tags)
{
    unsigned int i;

    for (i = 0; i < tags->count; i++)
    {
        if (tags->tags[i].item) free(tags->tags[i].item);
        if (tags->tags[i].value) free(tags->tags[i].value);
    }

    if (tags->tags) free(tags->tags);

    tags->tags = NULL;
    tags->count = 0;
}

int ReadMP4Tag(MP4FileHandle file, medialib_tags *tags)
{
    unsigned __int32 valueSize;
    unsigned __int8 *pValue;
    char *pName;
    unsigned int i = 0;

    do {
        pName = 0;
        pValue = 0;
        valueSize = 0;

        MP4GetMetadataByIndex(file, i, (const char **)&pName, &pValue, &valueSize);

        if (valueSize > 0)
        {
            char *val = (char *)malloc(valueSize+1);
            if (!val) return 0;
            memcpy(val, pValue, valueSize);
            val[valueSize] = '\0';

            if (pName[0] == '\xa9')
            {
                if (memcmp(pName, "﹏am", 4) == 0)
                {
                    tag_add_field(tags, "title", val);
                } else if (memcmp(pName, "〢RT", 4) == 0) {
                    tag_add_field(tags, "artist", val);
                } else if (memcmp(pName, "﹚rt", 4) == 0) {
                    tag_add_field(tags, "writer", val);
                } else if (memcmp(pName, "゛lb", 4) == 0) {
                    tag_add_field(tags, "album", val);
                } else if (memcmp(pName, "ヾay", 4) == 0) {
                    tag_add_field(tags, "date", val);
                } else if (memcmp(pName, "﹖oo", 4) == 0) {
                    tag_add_field(tags, "tool", val);
                } else if (memcmp(pName, "ヽmt", 4) == 0) {
                    tag_add_field(tags, "comment", val);
                } else if (memcmp(pName, "ゞen", 4) == 0) {
                    tag_add_field(tags, "genre", val);
                } else {
                    tag_add_field(tags, pName, val);
                }
            } else if (memcmp(pName, "gnre", 4) == 0) {
                char *t=0;
                if (MP4GetMetadataGenre(file, &t))
                {
                    tag_add_field(tags, "genre", t);
                }
            } else if (memcmp(pName, "trkn", 4) == 0) {
                unsigned __int16 trkn = 0, tot = 0;
                char t[200];
                if (MP4GetMetadataTrack(file, &trkn, &tot))
                {
                    if (tot > 0)
                        wsprintf(t, "%d/%d", trkn, tot);
                    else
                        wsprintf(t, "%d", trkn);
                    tag_add_field(tags, "tracknumber", t);
                }
            } else if (memcmp(pName, "disk", 4) == 0) {
                unsigned __int16 disk = 0, tot = 0;
                char t[200];
                if (MP4GetMetadataDisk(file, &disk, &tot))
                {
                    if (tot > 0)
                        wsprintf(t, "%d/%d", disk, tot);
                    else
                        wsprintf(t, "%d", disk);
                    tag_add_field(tags, "disc", t);
                }
            } else if (memcmp(pName, "cpil", 4) == 0) {
                unsigned __int8 cpil = 0;
                char t[200];
                if (MP4GetMetadataCompilation(file, &cpil))
                {
                    wsprintf(t, "%d", cpil);
                    tag_add_field(tags, "compilation", t);
                }
            } else if (memcmp(pName, "tmpo", 4) == 0) {
                unsigned __int16 tempo = 0;
                char t[200];
                if (MP4GetMetadataTempo(file, &tempo))
                {
                    wsprintf(t, "%d BPM", tempo);
                    tag_add_field(tags, "tempo", t);
                }
            } else if (memcmp(pName, "NDFL", 4) == 0) {
                /* Removed */
            } else {
                tag_add_field(tags, pName, val);
            }

            free(val);
        }

        i++;
    } while (valueSize > 0);

    return 1;
}

int mp4_set_metadata(MP4FileHandle file, const char *item, const char *val)
{
    if (!item || (item && !*item) || !val || (val && !*val)) return 0;

    if (!stricmp(item, "track") || !stricmp(item, "tracknumber"))
    {
        unsigned __int16 trkn, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        trkn = t1, tot = t2;
        if (!trkn) return 1;
        if (MP4SetMetadataTrack(file, trkn, tot)) return 1;
    }
    else if (!stricmp(item, "disc") || !stricmp(item, "disknumber"))
    {
        unsigned __int16 disk, tot;
        int t1 = 0, t2 = 0;
        sscanf(val, "%d/%d", &t1, &t2);
        disk = t1, tot = t2;
        if (!disk) return 1;
        if (MP4SetMetadataDisk(file, disk, tot)) return 1;
    }
    else if (!stricmp(item, "compilation"))
    {
        unsigned __int8 cpil = atoi(val);
        if (!cpil) return 1;
        if (MP4SetMetadataCompilation(file, cpil)) return 1;
    }
    else if (!stricmp(item, "tempo"))
    {
        unsigned __int16 tempo = atoi(val);
        if (!tempo) return 1;
        if (MP4SetMetadataTempo(file, tempo)) return 1;
    }
    else if (!stricmp(item, "artist"))
    {
        if (MP4SetMetadataArtist(file, val)) return 1;
    }
    else if (!stricmp(item, "writer"))
    {
        if (MP4SetMetadataWriter(file, val)) return 1;
    }
    else if (!stricmp(item, "title"))
    {
        if (MP4SetMetadataName(file, val)) return 1;
    }
    else if (!stricmp(item, "album"))
    {
        if (MP4SetMetadataAlbum(file, val)) return 1;
    }
    else if (!stricmp(item, "date") || !stricmp(item, "year"))
    {
        if (MP4SetMetadataYear(file, val)) return 1;
    }
    else if (!stricmp(item, "comment"))
    {
        if (MP4SetMetadataComment(file, val)) return 1;
    }
    else if (!stricmp(item, "genre"))
    {
        if (MP4SetMetadataGenre(file, val)) return 1;
    }
    else if (!stricmp(item, "tool"))
    {
        if (MP4SetMetadataTool(file, val)) return 1;
    }
    else
    {
        if (MP4SetMetadataFreeForm(file, (char *)item, (u_int8_t *)val, (u_int32_t)strlen(val) + 1)) return 1;
    }

    return 0;
}

void WriteMP4Tag(MP4FileHandle file, const medialib_tags *tags)
{
    unsigned int i;

    for (i = 0; i < tags->count; i++)
    {
        const char *item = tags->tags[i].item;
        const char *value = tags->tags[i].value;

        if (value && *value)
        {
            mp4_set_metadata(file, item, value);
        }
    }
}

QCDModInitTag	ModInitTag;

medialib_tags tags;

BOOL uSetDlgItemText(void *tagHandle, int fieldId, const char *str);
UINT uGetDlgItemText(void *tagHandle, int fieldId, char *str, int max);

//------------------------------------------------------------------------------

PLUGIN_API QCDModInitTag* TAGEDITORDLL_ENTRY_POINT()
{	
	ModInitTag.size			= sizeof(QCDModInitTag);
	ModInitTag.version		= PLUGIN_API_VERSION;
	ModInitTag.ShutDown		= ShutDown_Tag;

	ModInitTag.Read			= Read_Tag;
	ModInitTag.Write		= Write_Tag;	// Leave null for operations that plugin does not support
	ModInitTag.Strip		= Strip_Tag;	// ie: if plugin only reads tags, leave Write and Strip null

	ModInitTag.description	= "MP4 Tags";
	ModInitTag.defaultexts	= "MP4:M4A";

	return &ModInitTag;
}

//-----------------------------------------------------------------------------

void ShutDown_Tag(int flags)
{
	// TODO:
	// prepare plugin to be unloaded. All allocations should be freed.
	// flags param is unused
	tag_delete(&tags);
}

//-----------------------------------------------------------------------------

bool Read_Tag(LPCSTR filename, void* tagHandle)
{
	// TODO:
	// read metadata from tag and set each field to tagHandle
	// only TAGFIELD_* are supported (see QCDModTagEditor.h)

	// example of how to set value to tagHandle
	// use SetFieldA for ASCII or MultiBytes strings.
	// use SetFieldW for UNICODE strings
	//
	//	ModInitTag.SetFieldW(tagHandle, TAGFIELD_COMPOSER, szwValue);

	// return true for successfull read, false for failure

	MP4FileHandle file = MP4_INVALID_FILE_HANDLE;
	char *pVal, dummy1[1024];
	short dummy, dummy2;
	u_int32_t valueSize = 0;

#ifdef DEBUG_OUTPUT
	in_mp4_DebugOutput("mp4_tag_read");
#endif

	file = MP4Read(filename, 0);

	if (file == MP4_INVALID_FILE_HANDLE)
		return false;

	/* get Metadata */

	pVal = NULL;
	MP4GetMetadataName(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_TITLE, pVal);

	pVal = NULL;
	MP4GetMetadataArtist(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_ARTIST, pVal);

	pVal = NULL;
	MP4GetMetadataWriter(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_COMPOSER, pVal);

	pVal = NULL;
	MP4GetMetadataComment(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_COMMENT, pVal);

	pVal = NULL;
	MP4GetMetadataAlbum(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_ALBUM, pVal);

	pVal = NULL;
	MP4GetMetadataGenre(file, &pVal);
	uSetDlgItemText(tagHandle, TAGFIELD_GENRE, pVal);

	//dummy = 0;
	//MP4GetMetadataTempo(file, &dummy);
	//if (dummy)
	//{
	//	wsprintf(dummy1, "%d", dummy);
	//	SetDlgItemText(hwndDlg,IDC_METATEMPO, dummy1);
	//}

	dummy = 0; dummy2 = 0;
	MP4GetMetadataTrack(file, (unsigned __int16*)&dummy, (unsigned __int16*)&dummy2);
	if (dummy)
	{
		wsprintf(dummy1, "%d", dummy);
		ModInitTag.SetFieldA(tagHandle, TAGFIELD_TRACK, dummy1);
	}
	//if (dumm2)
	//{
	//	wsprintf(dummy1, "%d", dummy2);
	//	SetDlgItemText(hwndDlg,IDC_METATRACK2, dummy1);
	//}

	//dummy = 0; dummy2 = 0;
	//MP4GetMetadataDisk(file, &dummy, &dummy2);
	//if (dummy)
	//{
	//	wsprintf(dummy1, "%d", dummy);
	//	SetDlgItemText(hwndDlg,IDC_METADISK1, dummy1);
	//}
	//if (dummy)
	//{
	//	wsprintf(dummy1, "%d", dummy2);
	//	SetDlgItemText(hwndDlg,IDC_METADISK2, dummy1);
	//}

⌨️ 快捷键说明

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