mp4meta.cpp
来自「faac-1.25.rar音频编解码器demo」· C++ 代码 · 共 988 行 · 第 1/2 页
CPP
988 行
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is MPEG4IP.
*
* The Initial Developer of the Original Code is Cisco Systems Inc.
* Portions created by Cisco Systems Inc. are
* Copyright (C) Cisco Systems Inc. 2001. All Rights Reserved.
*
* Contributor(s):
* M. Bakker mbakker at nero.com
*
* Apple iTunes Metadata handling
*/
/**
The iTunes tagging seems to support any tag field name
but there are some predefined fields, also known from the QuickTime format
predefined fields (the ones I know of until now):
- ﹏am : Name of the song/movie (string)
- 〢RT : Name of the artist/performer (string)
- ﹚rt : Name of the writer (string)
- ゛lb : Name of the album (string)
- ヾay : Year (4 bytes, e.g. "2003") (string)
- ﹖oo : Tool(s) used to create the file (string)
- ヽmt : Comment (string)
- ゞen : Custom genre (string)
- trkn : Tracknumber (8 byte string)
16 bit: empty
16 bit: tracknumber
16 bit: total tracks on album
16 bit: empty
- disk : Disknumber (8 byte string)
16 bit: empty
16 bit: disknumber
16 bit: total number of disks
16 bit: empty
- gnre : Genre (16 bit genre) (ID3v1 index + 1)
- cpil : Part of a compilation (1 byte, 1 or 0)
- tmpo : Tempo in BPM (16 bit)
- covr : Cover art (xx bytes binary data)
- ---- : Free form metadata, can have any name and any data
**/
#include "mp4common.h"
bool MP4File::GetMetadataByIndex(u_int32_t index,
const char** ppName,
u_int8_t** ppValue, u_int32_t* pValueSize)
{
char s[256];
sprintf(s, "moov.udta.meta.ilst.*[%u].data.metadata", index);
GetBytesProperty(s, ppValue, pValueSize);
sprintf(s, "moov.udta.meta.ilst.*[%u]", index);
MP4Atom* pParent = m_pRootAtom->FindAtom(s);
*ppName = pParent->GetType();
/* check for free form tagfield */
if (memcmp(*ppName, "----", 4) == 0)
{
u_int8_t* pV;
u_int32_t VSize = 0;
char *pN;
sprintf(s, "moov.udta.meta.ilst.*[%u].name.metadata", index);
GetBytesProperty(s, &pV, &VSize);
pN = (char*)malloc((VSize+1)*sizeof(char));
memset(pN, 0, (VSize+1)*sizeof(char));
memcpy(pN, pV, VSize*sizeof(char));
*ppName = pN;
}
return true;
}
bool MP4File::CreateMetadataAtom(const char* name)
{
char s[256];
char t[256];
sprintf(t, "udta.meta.ilst.%s.data", name);
sprintf(s, "moov.udta.meta.ilst.%s.data", name);
AddDescendantAtoms("moov", t);
MP4Atom *pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
return false;
/* some fields need special flags set */
if ((uint8_t)name[0] == 0251)
{
pMetaAtom->SetFlags(0x1);
} else if ((memcmp(name, "cpil", 4) == 0) || (memcmp(name, "tmpo", 4) == 0)) {
pMetaAtom->SetFlags(0x15);
}
MP4Atom *pHdlrAtom = m_pRootAtom->FindAtom("moov.udta.meta.hdlr");
MP4StringProperty *pStringProperty = NULL;
MP4BytesProperty *pBytesProperty = NULL;
ASSERT(pHdlrAtom);
pHdlrAtom->FindProperty(
"hdlr.handlerType", (MP4Property**)&pStringProperty);
ASSERT(pStringProperty);
pStringProperty->SetValue("mdir");
u_int8_t val[12];
memset(val, 0, 12*sizeof(u_int8_t));
val[0] = 0x61;
val[1] = 0x70;
val[2] = 0x70;
val[3] = 0x6c;
pHdlrAtom->FindProperty(
"hdlr.reserved2", (MP4Property**)&pBytesProperty);
ASSERT(pBytesProperty);
pBytesProperty->SetReadOnly(false);
pBytesProperty->SetValue(val, 12);
pBytesProperty->SetReadOnly(true);
return true;
}
bool MP4File::SetMetadataName(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251nam.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251nam"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
return true;
}
bool MP4File::GetMetadataName(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251nam.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataWriter(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251wrt.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251wrt"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
return true;
}
bool MP4File::GetMetadataWriter(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251wrt.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataAlbum(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251alb.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251alb"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
return true;
}
bool MP4File::GetMetadataAlbum(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251alb.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataArtist(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251ART.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251ART"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
return true;
}
bool MP4File::GetMetadataArtist(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251ART.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataTool(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251too.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251too"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
return true;
}
bool MP4File::GetMetadataTool(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251too.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataComment(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251cmt.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251cmt"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)value, strlen(value));
return true;
}
bool MP4File::GetMetadataComment(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251cmt.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataYear(const char* value)
{
const char *s = "moov.udta.meta.ilst.\251day.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("\251day"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
if (strlen(value) < 4)
return false;
pMetadataProperty->SetValue((u_int8_t*)value, 4);
return true;
}
bool MP4File::GetMetadataYear(char** value)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.\251day.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
if (valSize > 0)
{
*value = (char*)malloc((valSize+1)*sizeof(unsigned char));
memset(*value, 0, (valSize+1)*sizeof(unsigned char));
memcpy(*value, val, valSize*sizeof(unsigned char));
return true;
} else {
*value = NULL;
return false;
}
}
bool MP4File::SetMetadataTrack(u_int16_t track, u_int16_t totalTracks)
{
unsigned char t[9];
const char *s = "moov.udta.meta.ilst.trkn.data";
MP4BytesProperty *pMetadataProperty = NULL;
MP4Atom *pMetaAtom = NULL;
pMetaAtom = m_pRootAtom->FindAtom(s);
if (!pMetaAtom)
{
if (!CreateMetadataAtom("trkn"))
return false;
pMetaAtom = m_pRootAtom->FindAtom(s);
}
memset(t, 0, 9*sizeof(unsigned char));
t[2] = (unsigned char)(track>>8)&0xFF;
t[3] = (unsigned char)(track)&0xFF;
t[4] = (unsigned char)(totalTracks>>8)&0xFF;
t[5] = (unsigned char)(totalTracks)&0xFF;
pMetaAtom->FindProperty("data.metadata", (MP4Property**)&pMetadataProperty);
ASSERT(pMetadataProperty);
pMetadataProperty->SetValue((u_int8_t*)t, 8);
return true;
}
bool MP4File::GetMetadataTrack(u_int16_t* track, u_int16_t* totalTracks)
{
unsigned char *val = NULL;
u_int32_t valSize = 0;
const char *s = "moov.udta.meta.ilst.trkn.data.metadata";
GetBytesProperty(s, (u_int8_t**)&val, &valSize);
*track = 0;
*totalTracks = 0;
if (valSize != 8)
return false;
*track = (u_int16_t)(val[3]);
*track += (u_int16_t)(val[2]<<8);
*totalTracks = (u_int16_t)(val[5]);
*totalTracks += (u_int16_t)(val[4]<<8);
return true;
}
bool MP4File::SetMetadataDisk(u_int16_t disk, u_int16_t totalDisks)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?