The mapping is taken from Picard's [1] and taglib's [2] documentation.
ID3:
The `TSST` frame is part of ID3v2.4.0:
> The 'Set subtitle' frame is intended for the subtitle of the part
> of a set this track belongs to.
asf: WM/SetSubTitle
The mapping in Microsoft's docs [3] maps `TSST` from ID3 to
`WM/SetSubTitle`.
However, some taggers [4] [5] use `WM/SubTitle` instead.
I believe this to be an error, especially since the official docs
say otherwise.
MP4: ----:com.apple.iTunes:DISCSUBTITLE
In my tests, iTunes did not respond to this attribute but it seems
to be what all the sources that I have linked use.
RIFF: PRT1
I have only found this in taglib's mapping [2]. The only other
reference that I have found is on exiftool.org [6] where it is
described as "part".
Vorbis: DISCSUBTITLE
The official list [7] of standard field names is pretty short and
does not include one for a disc/part subtitle. Some taggers use
SETSUBTITLE here instead. However, I think DISCSUBTITLE is much more
consistent with the already existing DISCNUMBER field and it matches
what Picard and taglib do.
[1]:
https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html#disc-subtitle
[2]: https://taglib.org/api/p_propertymapping.html
[3]: https://learn.microsoft.com/en-gb/windows/win32/wmformat/id3-tag-support
[4]:
https://github.com/quodlibet/quodlibet/blob/db95540de69c7f7cda662fbad6d90eeca89611ce/quodlibet/formats/wma.py#L43
[5]:
https://invent.kde.org/multimedia/kid3/-/blob/989fb5b8f98e20387c704e229f8c8b9cd00ae453/src/plugins/taglibmetadata/taglibasfsupport.cpp#L93
[6]: https://exiftool.org/TagNames/RIFF.html
[7]: https://xiph.org/vorbis/doc/v-comment.html
Signed-off-by: Tau Gärtli <[email protected]>
---
libavformat/asf.c | 3 +++
libavformat/avformat.h | 1 +
libavformat/id3v2.c | 1 +
libavformat/mov.c | 8 +++++++-
libavformat/movenc.c | 40 +++++++++++++++++++++++++++++++++++++
libavformat/riff.c | 27 +++++++++++++------------
libavformat/vorbiscomment.c | 10 ++++++----
7 files changed, 72 insertions(+), 18 deletions(-)
diff --git a/libavformat/asf.c b/libavformat/asf.c
index 5c118d2dbe..5224a5d88d 100644
--- a/libavformat/asf.c
+++ b/libavformat/asf.c
@@ -37,6 +37,9 @@ const AVMetadataConv ff_asf_metadata_conv[] = {
{ "WM/Language", "language" },
{ "WM/OriginalFilename", "filename" },
{ "WM/PartOfSet", "disc" },
+ /* SetSubTitle can be found in this mapping:
+ *
https://learn.microsoft.com/en-gb/windows/win32/wmformat/id3-tag-support */
+ { "WM/SetSubTitle", "disc_subtitle" },
{ "WM/Publisher", "publisher" },
{ "WM/Tool", "encoder" },
{ "WM/TrackNumber", "track" },
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index bd34132e00..a92f4796ba 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -386,6 +386,7 @@ struct AVFrame;
creation_time-- date when the file was created, preferably in ISO 8601.
date -- date when the work was created, preferably in ISO 8601.
disc -- number of a subset, e.g. disc in a multi-disc collection.
+ disc_subtitle-- title of a subset, e.g. disc subtitle in a multi-disc
collection.
encoder -- name/settings of the software/hardware that produced the file.
encoded_by -- person/group who created the file.
filename -- original name of the file.
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 98969c67a0..729dc6bf96 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -70,6 +70,7 @@ const AVMetadataConv ff_id3v2_4_metadata_conv[] = {
{ "TSOA", "album-sort" },
{ "TSOP", "artist-sort" },
{ "TSOT", "title-sort" },
+ { "TSST", "disc_subtitle" },
{ "TIT1", "grouping" },
{ 0 }
};
diff --git a/libavformat/mov.c b/libavformat/mov.c
index d19b213ffa..227fbf2b7b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -5451,7 +5451,13 @@ static int mov_read_custom(MOVContext *c, AVIOContext
*pb, MOVAtom atom)
sc->start_pad = priming;
}
}
- if (strcmp(key, "cdec") != 0) {
+ if (strcmp(mean, "com.apple.iTunes") == 0 &&
+ strcmp(key, "DISCSUBTITLE") == 0) {
+ av_dict_set(&c->fc->metadata, "disc_subtitle", val,
+ AV_DICT_DONT_STRDUP_VAL);
+ val = NULL;
+ }
+ else if (strcmp(key, "cdec") != 0) {
av_dict_set(&c->fc->metadata, key, val,
AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
key = val = NULL;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 802c37fc4a..e825d1fc03 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -4561,6 +4561,35 @@ static int mov_write_string_tag(AVIOContext *pb, const
char *name,
return size;
}
+static int mov_write_freeform_tag(AVIOContext *pb, const char *mean,
+ const char *name, const char *data)
+{
+ if (!data || !data[0])
+ return 0;
+
+ static const char stub_flags[4] = {0, 0, 0, 0};
+
+ int64_t entry_pos = avio_tell(pb);
+ avio_wb32(pb, 0); /* size */
+ ffio_wfourcc(pb, "----"); /* freeform */
+
+ size_t mean_len = strlen(mean);
+ avio_wb32(pb, 12 + mean_len);
+ ffio_wfourcc(pb, "mean");
+ avio_write(pb, &stub_flags[0], sizeof(stub_flags));
+ avio_write(pb, mean, mean_len);
+
+ size_t name_len = strlen(name);
+ avio_wb32(pb, 12 + name_len);
+ ffio_wfourcc(pb, "name");
+ avio_write(pb, &stub_flags[0], sizeof(stub_flags));
+ avio_write(pb, name, name_len);
+
+ mov_write_string_data_tag(pb, data, 0, 1);
+
+ return update_size(pb, entry_pos);
+}
+
static AVDictionaryEntry *get_metadata_lang(AVFormatContext *s,
const char *tag, int *lang)
{
@@ -4597,6 +4626,16 @@ static int mov_write_string_metadata(AVFormatContext *s,
AVIOContext *pb,
return mov_write_string_tag(pb, name, t->value, lang, long_style);
}
+static int mov_write_custom_metadata(AVFormatContext *s, AVIOContext *pb,
+ const char *mean, const char *name,
+ const char *tag)
+{
+ AVDictionaryEntry *t = av_dict_get(s->metadata, tag, NULL, 0);
+ if (!t)
+ return 0;
+ return mov_write_freeform_tag(pb, mean, name, t->value);
+}
+
/* iTunes bpm number */
static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
{
@@ -4785,6 +4824,7 @@ static int mov_write_ilst_tag(AVIOContext *pb,
MOVMuxContext *mov,
mov_write_trkn_tag(pb, mov, s, 0); // track number
mov_write_trkn_tag(pb, mov, s, 1); // disc number
mov_write_tmpo_tag(pb, s);
+ mov_write_custom_metadata(s, pb, "com.apple.iTunes", "DISCSUBTITLE",
"disc_subtitle");
return update_size(pb, pos);
}
diff --git a/libavformat/riff.c b/libavformat/riff.c
index fc79d0ac21..cb99f95767 100644
--- a/libavformat/riff.c
+++ b/libavformat/riff.c
@@ -635,19 +635,20 @@ const AVCodecTag *const ff_wav_codec_tags_list[] = {
ff_codec_wav_tags, NULL };
#endif
const AVMetadataConv ff_riff_info_conv[] = {
- { "IART", "artist" },
- { "ICMT", "comment" },
- { "ICOP", "copyright" },
- { "ICRD", "date" },
- { "IGNR", "genre" },
- { "ILNG", "language" },
- { "INAM", "title" },
- { "IPRD", "album" },
- { "IPRT", "track" },
- { "ITRK", "track" },
- { "ISFT", "encoder" },
- { "ISMP", "timecode" },
- { "ITCH", "encoded_by" },
+ { "IART", "artist" },
+ { "ICMT", "comment" },
+ { "ICOP", "copyright" },
+ { "ICRD", "date" },
+ { "IGNR", "genre" },
+ { "ILNG", "language" },
+ { "INAM", "title" },
+ { "IPRD", "album" },
+ { "IPRT", "track" },
+ { "ITRK", "track" },
+ { "ISFT", "encoder" },
+ { "ISMP", "timecode" },
+ { "ITCH", "encoded_by" },
+ { "PRT1", "disc_subtitle" },
{ 0 },
};
diff --git a/libavformat/vorbiscomment.c b/libavformat/vorbiscomment.c
index e57cfa5e62..8a60d6802e 100644
--- a/libavformat/vorbiscomment.c
+++ b/libavformat/vorbiscomment.c
@@ -32,10 +32,12 @@
* http://xiph.org/vorbis/doc/v-comment.html
*/
const AVMetadataConv ff_vorbiscomment_metadata_conv[] = {
- { "ALBUMARTIST", "album_artist"},
- { "TRACKNUMBER", "track" },
- { "DISCNUMBER", "disc" },
- { "DESCRIPTION", "comment" },
+ { "ALBUMARTIST", "album_artist" },
+ { "TRACKNUMBER", "track" },
+ { "DISCNUMBER", "disc" },
+ /* Adapted from
<https://picard-docs.musicbrainz.org/en/appendices/tag_mapping.html#disc-subtitle>
*/
+ { "DISCSUBTITLE", "disc_subtitle" },
+ { "DESCRIPTION", "comment" },
{ 0 }
};
--
2.52.0
_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]