mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
avformat/id3v2: support USLT tags
I think this turned out pretty terrible. There's no good way to add new custom tags that write to AVFormatContext->metadata. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
369b4cd412
commit
ea7af58fc6
@ -55,6 +55,7 @@ const AVMetadataConv ff_id3v2_34_metadata_conv[] = {
|
|||||||
{ "TPUB", "publisher" },
|
{ "TPUB", "publisher" },
|
||||||
{ "TRCK", "track" },
|
{ "TRCK", "track" },
|
||||||
{ "TSSE", "encoder" },
|
{ "TSSE", "encoder" },
|
||||||
|
{ "USLT", "lyrics" },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -353,6 +354,52 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
|
|||||||
av_dict_set(metadata, key, dst, dict_flags);
|
av_dict_set(metadata, key, dst, dict_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen,
|
||||||
|
AVDictionary **metadata)
|
||||||
|
{
|
||||||
|
uint8_t lang[4];
|
||||||
|
uint8_t *descriptor = NULL; // 'Content descriptor'
|
||||||
|
uint8_t *text = NULL;
|
||||||
|
char *key = NULL;
|
||||||
|
int encoding;
|
||||||
|
unsigned genre;
|
||||||
|
int ok = 0;
|
||||||
|
|
||||||
|
if (taglen < 1)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
encoding = avio_r8(pb);
|
||||||
|
taglen--;
|
||||||
|
|
||||||
|
if (avio_read(pb, lang, 3) < 3)
|
||||||
|
goto error;
|
||||||
|
lang[3] = '\0';
|
||||||
|
taglen -= 3;
|
||||||
|
|
||||||
|
if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (decode_str(s, pb, encoding, &text, &taglen) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// FFmpeg does not support hierarchical metadata, so concatenate the keys.
|
||||||
|
key = av_asprintf("lyrics-%s%s%s", descriptor[0] ? (char *)descriptor : "",
|
||||||
|
descriptor[0] ? "-" : "",
|
||||||
|
lang);
|
||||||
|
if (!key)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
av_dict_set(metadata, key, text, 0);
|
||||||
|
|
||||||
|
ok = 1;
|
||||||
|
error:
|
||||||
|
if (!ok)
|
||||||
|
av_log(s, AV_LOG_ERROR, "Error reading lyrics, skipped\n");
|
||||||
|
av_free(descriptor);
|
||||||
|
av_free(text);
|
||||||
|
av_free(key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
|
* Parse GEOB tag into a ID3v2ExtraMetaGEOB struct.
|
||||||
*/
|
*/
|
||||||
@ -845,6 +892,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
|
|||||||
avio_skip(pb, tlen);
|
avio_skip(pb, tlen);
|
||||||
/* check for text tag or supported special meta tag */
|
/* check for text tag or supported special meta tag */
|
||||||
} else if (tag[0] == 'T' ||
|
} else if (tag[0] == 'T' ||
|
||||||
|
!memcmp(tag, "USLT", 4) ||
|
||||||
(extra_meta &&
|
(extra_meta &&
|
||||||
(extra_func = get_extra_meta_func(tag, isv34)))) {
|
(extra_func = get_extra_meta_func(tag, isv34)))) {
|
||||||
pbx = pb;
|
pbx = pb;
|
||||||
@ -910,6 +958,8 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
|
|||||||
if (tag[0] == 'T')
|
if (tag[0] == 'T')
|
||||||
/* parse text tag */
|
/* parse text tag */
|
||||||
read_ttag(s, pbx, tlen, metadata, tag);
|
read_ttag(s, pbx, tlen, metadata, tag);
|
||||||
|
else if (!memcmp(tag, "USLT", 4))
|
||||||
|
read_uslt(s, pbx, tlen, metadata);
|
||||||
else
|
else
|
||||||
/* parse special meta tag */
|
/* parse special meta tag */
|
||||||
extra_func->read(s, pbx, tlen, tag, extra_meta, isv34);
|
extra_func->read(s, pbx, tlen, tag, extra_meta, isv34);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user