Add vorbis comment support for track/disc numbering fields, and genre

Only `TRACKNUMBER` and `GENRE` are listed here:
https://xiph.org/vorbis/doc/v-comment.html

The rest are derived from the example in Issue: androidx/media#1958.

It's possible that other formats exist in the wild:
https://hydrogenaud.io/index.php/topic,69292.msg613808.html#msg613808

Issue: androidx/media#1958
PiperOrigin-RevId: 704308788
This commit is contained in:
ibaker 2024-12-09 09:09:53 -08:00 committed by Copybara-Service
parent aa0e7298ca
commit 12546070ee
3 changed files with 49 additions and 0 deletions

View File

@ -49,6 +49,9 @@
active at `timeUs` (started before but not yet ended) was incorrectly
discarded ([#1939](https://github.com/androidx/media/issues/1939)).
* Metadata:
* Extract disc/track numbering and genre from Vorbis comments into
`MediaMetadata`
([#1958](https://github.com/androidx/media/issues/1958)).
* Image:
* DRM:
* Effect:

View File

@ -24,6 +24,7 @@ import androidx.media3.common.MediaMetadata;
import androidx.media3.common.Metadata;
import androidx.media3.common.util.UnstableApi;
import com.google.common.base.Ascii;
import com.google.common.primitives.Ints;
/**
* @deprecated Use {@link androidx.media3.extractor.metadata.vorbis.VorbisComment} instead.
@ -58,6 +59,9 @@ public class VorbisComment implements Metadata.Entry {
@Override
public void populateMediaMetadata(MediaMetadata.Builder builder) {
// Vorbis comments can have duplicate keys, but all these fields are singular on MediaMetadata,
// so we naively overwrite whatever any previously set value (which results in 'keep last'
// semantics).
switch (key) {
case "TITLE":
builder.setTitle(value);
@ -71,6 +75,33 @@ public class VorbisComment implements Metadata.Entry {
case "ALBUMARTIST":
builder.setAlbumArtist(value);
break;
case "TRACKNUMBER":
@Nullable Integer trackNumber = Ints.tryParse(value);
if (trackNumber != null) {
builder.setTrackNumber(trackNumber);
}
break;
case "TOTALTRACKS":
@Nullable Integer totalTracks = Ints.tryParse(value);
if (totalTracks != null) {
builder.setTotalTrackCount(totalTracks);
}
break;
case "DISCNUMBER":
@Nullable Integer discNumber = Ints.tryParse(value);
if (discNumber != null) {
builder.setDiscNumber(discNumber);
}
break;
case "TOTALDISCS":
@Nullable Integer totalDiscs = Ints.tryParse(value);
if (totalDiscs != null) {
builder.setTotalDiscCount(totalDiscs);
}
break;
case "GENRE":
builder.setGenre(value);
break;
case "DESCRIPTION":
builder.setDescription(value);
break;

View File

@ -50,6 +50,11 @@ public final class VorbisCommentTest {
String artist = "artist";
String albumTitle = "album title";
String albumArtist = "album Artist";
int trackNumber = 3;
int totalTracks = 12;
int discNumber = 1;
int totalDiscs = 3;
String genre = "Metal";
String description = "a description about the audio.";
List<Metadata.Entry> entries =
ImmutableList.of(
@ -57,6 +62,11 @@ public final class VorbisCommentTest {
new VorbisComment("ArTisT", artist),
new VorbisComment("ALBUM", albumTitle),
new VorbisComment("albumartist", albumArtist),
new VorbisComment("TRACKNUMBER", String.valueOf(trackNumber)),
new VorbisComment("TOTALTRACKS", String.valueOf(totalTracks)),
new VorbisComment("DISCNUMBER", String.valueOf(discNumber)),
new VorbisComment("TOTALDISCS", String.valueOf(totalDiscs)),
new VorbisComment("GENRE", genre),
new VorbisComment("DESCRIPTION", description));
MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
@ -69,6 +79,11 @@ public final class VorbisCommentTest {
assertThat(mediaMetadata.artist.toString()).isEqualTo(artist);
assertThat(mediaMetadata.albumTitle.toString()).isEqualTo(albumTitle);
assertThat(mediaMetadata.albumArtist.toString()).isEqualTo(albumArtist);
assertThat(mediaMetadata.trackNumber).isEqualTo(trackNumber);
assertThat(mediaMetadata.totalTrackCount).isEqualTo(totalTracks);
assertThat(mediaMetadata.discNumber).isEqualTo(discNumber);
assertThat(mediaMetadata.totalDiscCount).isEqualTo(totalDiscs);
assertThat(mediaMetadata.genre.toString()).isEqualTo(genre);
assertThat(mediaMetadata.description.toString()).isEqualTo(description);
}
}