diff --git a/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java b/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java index 21c1b0a4ac7..16c4c89ed40 100644 --- a/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java +++ b/libraries/common/src/main/java/androidx/media3/common/MediaMetadata.java @@ -75,6 +75,7 @@ public static final class Builder { @Nullable private Integer totalDiscCount; @Nullable private CharSequence genre; @Nullable private CharSequence compilation; + @Nullable private CharSequence station; @Nullable private Bundle extras; public Builder() {} @@ -110,6 +111,7 @@ private Builder(MediaMetadata mediaMetadata) { this.totalDiscCount = mediaMetadata.totalDiscCount; this.genre = mediaMetadata.genre; this.compilation = mediaMetadata.compilation; + this.station = mediaMetadata.station; this.extras = mediaMetadata.extras; } @@ -348,6 +350,12 @@ public Builder setCompilation(@Nullable CharSequence compilation) { return this; } + /** Sets the name of the station streaming the media. */ + public Builder setStation(@Nullable CharSequence station) { + this.station = station; + return this; + } + /** Sets the extras {@link Bundle}. */ public Builder setExtras(@Nullable Bundle extras) { this.extras = extras; @@ -490,6 +498,9 @@ public Builder populate(@Nullable MediaMetadata mediaMetadata) { if (mediaMetadata.compilation != null) { setCompilation(mediaMetadata.compilation); } + if (mediaMetadata.station != null) { + setStation(mediaMetadata.station); + } if (mediaMetadata.extras != null) { setExtras(mediaMetadata.extras); } @@ -684,6 +695,8 @@ public MediaMetadata build() { @Nullable public final CharSequence genre; /** Optional compilation. */ @Nullable public final CharSequence compilation; + /** Optional name of the station streaming the media. */ + @Nullable public final CharSequence station; /** * Optional extras {@link Bundle}. @@ -725,6 +738,7 @@ private MediaMetadata(Builder builder) { this.totalDiscCount = builder.totalDiscCount; this.genre = builder.genre; this.compilation = builder.compilation; + this.station = builder.station; this.extras = builder.extras; } @@ -771,7 +785,8 @@ public boolean equals(@Nullable Object obj) { && Util.areEqual(discNumber, that.discNumber) && Util.areEqual(totalDiscCount, that.totalDiscCount) && Util.areEqual(genre, that.genre) - && Util.areEqual(compilation, that.compilation); + && Util.areEqual(compilation, that.compilation) + && Util.areEqual(station, that.station); } @Override @@ -806,7 +821,8 @@ public int hashCode() { discNumber, totalDiscCount, genre, - compilation); + compilation, + station); } // Bundleable implementation. @@ -844,6 +860,7 @@ public int hashCode() { FIELD_TOTAL_DISC_COUNT, FIELD_GENRE, FIELD_COMPILATION, + FIELD_STATION, FIELD_EXTRAS }) private @interface FieldNumber {} @@ -878,6 +895,7 @@ public int hashCode() { private static final int FIELD_GENRE = 27; private static final int FIELD_COMPILATION = 28; private static final int FIELD_ARTWORK_DATA_TYPE = 29; + private static final int FIELD_STATION = 30; private static final int FIELD_EXTRAS = 1000; @UnstableApi @@ -899,6 +917,7 @@ public Bundle toBundle() { bundle.putCharSequence(keyForField(FIELD_CONDUCTOR), conductor); bundle.putCharSequence(keyForField(FIELD_GENRE), genre); bundle.putCharSequence(keyForField(FIELD_COMPILATION), compilation); + bundle.putCharSequence(keyForField(FIELD_STATION), station); if (userRating != null) { bundle.putBundle(keyForField(FIELD_USER_RATING), userRating.toBundle()); @@ -976,6 +995,7 @@ private static MediaMetadata fromBundle(Bundle bundle) { .setConductor(bundle.getCharSequence(keyForField(FIELD_CONDUCTOR))) .setGenre(bundle.getCharSequence(keyForField(FIELD_GENRE))) .setCompilation(bundle.getCharSequence(keyForField(FIELD_COMPILATION))) + .setStation(bundle.getCharSequence(keyForField(FIELD_STATION))) .setExtras(bundle.getBundle(keyForField(FIELD_EXTRAS))); if (bundle.containsKey(keyForField(FIELD_USER_RATING))) { diff --git a/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java b/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java index 42d939e7c70..cbba8e39f5a 100644 --- a/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java +++ b/libraries/common/src/test/java/androidx/media3/common/MediaMetadataTest.java @@ -64,6 +64,7 @@ public void builder_minimal_correctDefaults() { assertThat(mediaMetadata.totalDiscCount).isNull(); assertThat(mediaMetadata.genre).isNull(); assertThat(mediaMetadata.compilation).isNull(); + assertThat(mediaMetadata.station).isNull(); assertThat(mediaMetadata.extras).isNull(); } @@ -149,6 +150,7 @@ private static MediaMetadata getFullyPopulatedMediaMetadata() { .setTotalDiscCount(3) .setGenre("Pop") .setCompilation("Amazing songs.") + .setStation("radio station") .setExtras(extras) .build(); } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/icy/IcyHeaders.java b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/icy/IcyHeaders.java index 9c9806fdae0..84dc021c3e0 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/icy/IcyHeaders.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/metadata/icy/IcyHeaders.java @@ -20,6 +20,7 @@ import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.Format; +import androidx.media3.common.MediaMetadata; import androidx.media3.common.Metadata; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Log; @@ -171,6 +172,16 @@ public IcyHeaders( metadataInterval = in.readInt(); } + @Override + public void populateMediaMetadata(MediaMetadata.Builder builder) { + if (name != null) { + builder.setStation(name); + } + if (genre != null) { + builder.setGenre(genre); + } + } + @Override public boolean equals(@Nullable Object obj) { if (this == obj) { diff --git a/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/icy/IcyHeadersTest.java b/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/icy/IcyHeadersTest.java index 4a54b14465b..69012c22b74 100644 --- a/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/icy/IcyHeadersTest.java +++ b/libraries/extractor/src/test/java/androidx/media3/extractor/metadata/icy/IcyHeadersTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import android.os.Parcel; +import androidx.media3.common.MediaMetadata; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,4 +46,23 @@ public void parcelEquals() { // Assert equals. assertThat(fromParcelIcyHeaders).isEqualTo(icyHeaders); } + + @Test + public void populateMediaMetadata() { + IcyHeaders headers = + new IcyHeaders( + /* bitrate= */ 1234, + /* genre= */ "pop", + /* name= */ "radio station", + /* url= */ "url", + /* isPublic= */ true, + /* metadataInterval= */ 5678); + MediaMetadata.Builder builder = new MediaMetadata.Builder(); + + headers.populateMediaMetadata(builder); + MediaMetadata mediaMetadata = builder.build(); + + assertThat(mediaMetadata.station.toString()).isEqualTo("radio station"); + assertThat(mediaMetadata.genre.toString()).isEqualTo("pop"); + } }