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" },
|
||||
{ "TRCK", "track" },
|
||||
{ "TSSE", "encoder" },
|
||||
{ "USLT", "lyrics" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -353,6 +354,52 @@ static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen,
|
||||
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.
|
||||
*/
|
||||
@ -845,6 +892,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
|
||||
avio_skip(pb, tlen);
|
||||
/* check for text tag or supported special meta tag */
|
||||
} else if (tag[0] == 'T' ||
|
||||
!memcmp(tag, "USLT", 4) ||
|
||||
(extra_meta &&
|
||||
(extra_func = get_extra_meta_func(tag, isv34)))) {
|
||||
pbx = pb;
|
||||
@ -910,6 +958,8 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
|
||||
if (tag[0] == 'T')
|
||||
/* parse text tag */
|
||||
read_ttag(s, pbx, tlen, metadata, tag);
|
||||
else if (!memcmp(tag, "USLT", 4))
|
||||
read_uslt(s, pbx, tlen, metadata);
|
||||
else
|
||||
/* parse special meta tag */
|
||||
extra_func->read(s, pbx, tlen, tag, extra_meta, isv34);
|
||||
|
Loading…
x
Reference in New Issue
Block a user