📄 qcdmp4tag.cpp
字号:
#include <mp4.h>#include <faad.h>#include "QCDTagsDLL.h"//..............................................................................// Global Variablestypedef 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 + -