ref: 995ab26bd50a2ff96fb537f55b691cf012676b9a
parent: d4fbb806622ca833b19c9a9b97207bdbc05823b2
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Wed Aug 9 12:21:24 EDT 2017
new --tag option to add named tags
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -108,6 +108,7 @@
"\n"
"MP4 specific options:\n"
" -w\t\tWrap AAC data in MP4 container. (default for *.mp4 and *.m4a)\n"
+ " --tag <tagname,tagvalue> Add named tag (iTunes '----')\n"
" --artist X\tSet artist to X\n"
" --composer X\tSet composer to X\n"
" --title X\tSet title to X\n"
@@ -309,6 +310,7 @@
COVER_ART_FLAG,
COMMENT_FLAG,
WRITER_FLAG,
+ TAG_FLAG,
};
#ifndef _WIN32
@@ -427,7 +429,7 @@
unsigned int ndiscs = 0, discno = 0;
uint8_t compilation = 0;
const char *artist = NULL, *title = NULL, *album = NULL, *year = NULL,
- *comment = NULL, *composer = NULL;
+ *comment = NULL, *composer = NULL, *tagname = 0, *tagval = 0;
int genre = 0;
uint8_t *artData = NULL;
uint64_t artSize = 0;
@@ -481,6 +483,7 @@
{"compilation", 0, 0, COMPILATION_FLAG},
{"pcmswapbytes", 0, 0, 'X'},
{"ignorelength", 0, 0, IGNORELEN_FLAG},
+ {"tag", 1, 0, TAG_FLAG},
{0, 0, 0, 0}
};
int c = -1;
@@ -621,6 +624,14 @@
break;
case COMMENT_FLAG:
comment = optarg;
+ break;
+ case TAG_FLAG:
+ tagname = optarg;
+ if (!(tagval = strchr(optarg, ',')))
+ dieMessage = "Missing tag value.\n";
+ else
+ *(char *)tagval++ = 0;
+ mp4tag_add(tagname, tagval);
break;
case COVER_ART_FLAG:
{
--- a/frontend/mp4write.c
+++ b/frontend/mp4write.c
@@ -608,6 +608,7 @@
static int ilstout(void)
{
int size = 0;
+ int cnt;
size += tagtxt("\xa9" "too", mp4config.tag.encoder);
if (mp4config.tag.artist)
@@ -654,6 +655,33 @@
if (mp4config.tag.comment)
size += tagtxt("\xa9" "cmt", mp4config.tag.comment);
+ // ----(mean(com.apple.iTunes),name(name),data(data))
+ for (cnt = 0; cnt < mp4config.tag.extnum; cnt++)
+ {
+ static const char *mean = "faac";//"com.apple.iTunes";
+ const char *name = mp4config.tag.ext[cnt].name;
+ const char *data = mp4config.tag.ext[cnt].data;
+ uint32_t len1 = 8 + strlen(mean) + 4;
+ uint32_t len2 = 8 + strlen(name) + 4;
+ uint32_t len3 = 8 + strlen(data) + 4 + 4;
+ u32out(8 + len1 + len2 + len3);
+ size += 8 + len1 + len2 + len3;
+ stringout("----");
+ u32out(len1);
+ stringout("mean");
+ u32out(0);
+ stringout(mean);
+ u32out(len2);
+ stringout("name");
+ u32out(0);
+ stringout(name);
+ u32out(len3);
+ stringout("data");
+ u32out(1);
+ u32out(0);
+ stringout(data);
+ }
+
return size;
};
@@ -845,6 +873,23 @@
g_atom = g_tail;
while (g_atom->opcode != ATOM_STOP)
create();
+
+ return 0;
+}
+
+int mp4tag_add(const char *name, const char *data)
+{
+ int idx = mp4config.tag.extnum;
+
+ if (idx >= TAGMAX)
+ {
+ fprintf(stderr, "To many tags\n");
+ return -1;
+ }
+
+ mp4config.tag.ext[idx].name = name;
+ mp4config.tag.ext[idx].data = data;
+ mp4config.tag.extnum++;
return 0;
}
--- a/frontend/mp4write.h
+++ b/frontend/mp4write.h
@@ -19,6 +19,8 @@
#include <stdint.h>
+enum {TAGMAX = 100};
+
typedef struct
{
uint32_t samplerate;
@@ -67,6 +69,11 @@
int size;
} cover;
const char *comment;
+ struct {
+ const char *name;
+ const char *data;
+ } ext[TAGMAX];
+ int extnum;
} tag;
} mp4config_t;
@@ -77,3 +84,4 @@
int mp4atom_tail(void);
int mp4atom_frame(uint8_t * bitbuf, int bytesWritten, int frame_samples);
int mp4atom_close(void);
+int mp4tag_add(const char *name, const char *data);