mirror of
https://github.com/samsonjs/media.git
synced 2026-04-02 10:45:51 +00:00
Add an artworkDataType to MediaMetadata.
This field is to be associated with the artworkData. PiperOrigin-RevId: 385757480
This commit is contained in:
parent
0fe504d4b1
commit
fde3075af1
4 changed files with 176 additions and 9 deletions
|
|
@ -49,6 +49,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
@Nullable private Rating userRating;
|
||||
@Nullable private Rating overallRating;
|
||||
@Nullable private byte[] artworkData;
|
||||
@Nullable @PictureType private Integer artworkDataType;
|
||||
@Nullable private Uri artworkUri;
|
||||
@Nullable private Integer trackNumber;
|
||||
@Nullable private Integer totalTrackCount;
|
||||
|
|
@ -83,6 +84,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
this.userRating = mediaMetadata.userRating;
|
||||
this.overallRating = mediaMetadata.overallRating;
|
||||
this.artworkData = mediaMetadata.artworkData;
|
||||
this.artworkDataType = mediaMetadata.artworkDataType;
|
||||
this.artworkUri = mediaMetadata.artworkUri;
|
||||
this.trackNumber = mediaMetadata.trackNumber;
|
||||
this.totalTrackCount = mediaMetadata.totalTrackCount;
|
||||
|
|
@ -168,9 +170,41 @@ public final class MediaMetadata implements Bundleable {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Sets the artwork data as a compressed byte array. */
|
||||
/**
|
||||
* @deprecated Use {@link #setArtworkData(byte[] data, Integer pictureType)} or {@link
|
||||
* #maybeSetArtworkData(byte[] data, int pictureType)}, providing a {@link PictureType}.
|
||||
*/
|
||||
@Deprecated
|
||||
public Builder setArtworkData(@Nullable byte[] artworkData) {
|
||||
return setArtworkData(artworkData, /* artworkDataType= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the artwork data as a compressed byte array with an associated {@link PictureType
|
||||
* artworkDataType}.
|
||||
*/
|
||||
public Builder setArtworkData(
|
||||
@Nullable byte[] artworkData, @Nullable @PictureType Integer artworkDataType) {
|
||||
this.artworkData = artworkData == null ? null : artworkData.clone();
|
||||
this.artworkDataType = artworkDataType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the artwork data as a compressed byte array in the event that the associated {@link
|
||||
* PictureType} is {@link #PICTURE_TYPE_FRONT_COVER}, the existing {@link PictureType} is not
|
||||
* {@link #PICTURE_TYPE_FRONT_COVER}, or the current artworkData is not set.
|
||||
*
|
||||
* <p>Use {@link #setArtworkData(byte[], Integer)} to set the artwork data without checking the
|
||||
* {@link PictureType}.
|
||||
*/
|
||||
public Builder maybeSetArtworkData(byte[] artworkData, @PictureType int artworkDataType) {
|
||||
if (this.artworkData == null
|
||||
|| Util.areEqual(artworkDataType, PICTURE_TYPE_FRONT_COVER)
|
||||
|| !Util.areEqual(this.artworkDataType, PICTURE_TYPE_FRONT_COVER)) {
|
||||
this.artworkData = artworkData.clone();
|
||||
this.artworkDataType = artworkDataType;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +427,61 @@ public final class MediaMetadata implements Bundleable {
|
|||
/** Type for a folder containing media categorized by year. */
|
||||
public static final int FOLDER_TYPE_YEARS = 6;
|
||||
|
||||
/**
|
||||
* The picture type of the artwork.
|
||||
*
|
||||
* <p>Values sourced from the ID3 v2.4 specification (See section 4.14 of
|
||||
* https://id3.org/id3v2.4.0-frames).
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@IntDef({
|
||||
PICTURE_TYPE_OTHER,
|
||||
PICTURE_TYPE_FILE_ICON,
|
||||
PICTURE_TYPE_FILE_ICON_OTHER,
|
||||
PICTURE_TYPE_FRONT_COVER,
|
||||
PICTURE_TYPE_BACK_COVER,
|
||||
PICTURE_TYPE_LEAFLET_PAGE,
|
||||
PICTURE_TYPE_MEDIA,
|
||||
PICTURE_TYPE_LEAD_ARTIST_PERFORMER,
|
||||
PICTURE_TYPE_ARTIST_PERFORMER,
|
||||
PICTURE_TYPE_CONDUCTOR,
|
||||
PICTURE_TYPE_BAND_ORCHESTRA,
|
||||
PICTURE_TYPE_COMPOSER,
|
||||
PICTURE_TYPE_LYRICIST,
|
||||
PICTURE_TYPE_RECORDING_LOCATION,
|
||||
PICTURE_TYPE_DURING_RECORDING,
|
||||
PICTURE_TYPE_DURING_PERFORMANCE,
|
||||
PICTURE_TYPE_MOVIE_VIDEO_SCREEN_CAPTURE,
|
||||
PICTURE_TYPE_A_BRIGHT_COLORED_FISH,
|
||||
PICTURE_TYPE_ILLUSTRATION,
|
||||
PICTURE_TYPE_BAND_ARTIST_LOGO,
|
||||
PICTURE_TYPE_PUBLISHER_STUDIO_LOGO
|
||||
})
|
||||
public @interface PictureType {}
|
||||
|
||||
public static final int PICTURE_TYPE_OTHER = 0x00;
|
||||
public static final int PICTURE_TYPE_FILE_ICON = 0x01;
|
||||
public static final int PICTURE_TYPE_FILE_ICON_OTHER = 0x02;
|
||||
public static final int PICTURE_TYPE_FRONT_COVER = 0x03;
|
||||
public static final int PICTURE_TYPE_BACK_COVER = 0x04;
|
||||
public static final int PICTURE_TYPE_LEAFLET_PAGE = 0x05;
|
||||
public static final int PICTURE_TYPE_MEDIA = 0x06;
|
||||
public static final int PICTURE_TYPE_LEAD_ARTIST_PERFORMER = 0x07;
|
||||
public static final int PICTURE_TYPE_ARTIST_PERFORMER = 0x08;
|
||||
public static final int PICTURE_TYPE_CONDUCTOR = 0x09;
|
||||
public static final int PICTURE_TYPE_BAND_ORCHESTRA = 0x0A;
|
||||
public static final int PICTURE_TYPE_COMPOSER = 0x0B;
|
||||
public static final int PICTURE_TYPE_LYRICIST = 0x0C;
|
||||
public static final int PICTURE_TYPE_RECORDING_LOCATION = 0x0D;
|
||||
public static final int PICTURE_TYPE_DURING_RECORDING = 0x0E;
|
||||
public static final int PICTURE_TYPE_DURING_PERFORMANCE = 0x0F;
|
||||
public static final int PICTURE_TYPE_MOVIE_VIDEO_SCREEN_CAPTURE = 0x10;
|
||||
public static final int PICTURE_TYPE_A_BRIGHT_COLORED_FISH = 0x11;
|
||||
public static final int PICTURE_TYPE_ILLUSTRATION = 0x12;
|
||||
public static final int PICTURE_TYPE_BAND_ARTIST_LOGO = 0x13;
|
||||
public static final int PICTURE_TYPE_PUBLISHER_STUDIO_LOGO = 0x14;
|
||||
|
||||
/** Empty {@link MediaMetadata}. */
|
||||
public static final MediaMetadata EMPTY = new MediaMetadata.Builder().build();
|
||||
|
||||
|
|
@ -422,6 +511,8 @@ public final class MediaMetadata implements Bundleable {
|
|||
@Nullable public final Rating overallRating;
|
||||
/** Optional artwork data as a compressed byte array. */
|
||||
@Nullable public final byte[] artworkData;
|
||||
/** Optional {@link PictureType} of the artwork data. */
|
||||
@Nullable @PictureType public final Integer artworkDataType;
|
||||
/** Optional artwork {@link Uri}. */
|
||||
@Nullable public final Uri artworkUri;
|
||||
/** Optional track number. */
|
||||
|
|
@ -498,6 +589,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
this.userRating = builder.userRating;
|
||||
this.overallRating = builder.overallRating;
|
||||
this.artworkData = builder.artworkData;
|
||||
this.artworkDataType = builder.artworkDataType;
|
||||
this.artworkUri = builder.artworkUri;
|
||||
this.trackNumber = builder.trackNumber;
|
||||
this.totalTrackCount = builder.totalTrackCount;
|
||||
|
|
@ -545,6 +637,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
&& Util.areEqual(userRating, that.userRating)
|
||||
&& Util.areEqual(overallRating, that.overallRating)
|
||||
&& Arrays.equals(artworkData, that.artworkData)
|
||||
&& Util.areEqual(artworkDataType, that.artworkDataType)
|
||||
&& Util.areEqual(artworkUri, that.artworkUri)
|
||||
&& Util.areEqual(trackNumber, that.trackNumber)
|
||||
&& Util.areEqual(totalTrackCount, that.totalTrackCount)
|
||||
|
|
@ -579,6 +672,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
userRating,
|
||||
overallRating,
|
||||
Arrays.hashCode(artworkData),
|
||||
artworkDataType,
|
||||
artworkUri,
|
||||
trackNumber,
|
||||
totalTrackCount,
|
||||
|
|
@ -615,6 +709,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
FIELD_USER_RATING,
|
||||
FIELD_OVERALL_RATING,
|
||||
FIELD_ARTWORK_DATA,
|
||||
FIELD_ARTWORK_DATA_TYPE,
|
||||
FIELD_ARTWORK_URI,
|
||||
FIELD_TRACK_NUMBER,
|
||||
FIELD_TOTAL_TRACK_COUNT,
|
||||
|
|
@ -666,6 +761,7 @@ public final class MediaMetadata implements Bundleable {
|
|||
private static final int FIELD_TOTAL_DISC_COUNT = 26;
|
||||
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_EXTRAS = 1000;
|
||||
|
||||
@Override
|
||||
|
|
@ -729,6 +825,9 @@ public final class MediaMetadata implements Bundleable {
|
|||
if (totalDiscCount != null) {
|
||||
bundle.putInt(keyForField(FIELD_TOTAL_DISC_COUNT), totalDiscCount);
|
||||
}
|
||||
if (artworkDataType != null) {
|
||||
bundle.putInt(keyForField(FIELD_ARTWORK_DATA_TYPE), artworkDataType);
|
||||
}
|
||||
if (extras != null) {
|
||||
bundle.putBundle(keyForField(FIELD_EXTRAS), extras);
|
||||
}
|
||||
|
|
@ -749,7 +848,11 @@ public final class MediaMetadata implements Bundleable {
|
|||
.setSubtitle(bundle.getCharSequence(keyForField(FIELD_SUBTITLE)))
|
||||
.setDescription(bundle.getCharSequence(keyForField(FIELD_DESCRIPTION)))
|
||||
.setMediaUri(bundle.getParcelable(keyForField(FIELD_MEDIA_URI)))
|
||||
.setArtworkData(bundle.getByteArray(keyForField(FIELD_ARTWORK_DATA)))
|
||||
.setArtworkData(
|
||||
bundle.getByteArray(keyForField(FIELD_ARTWORK_DATA)),
|
||||
bundle.containsKey(keyForField(FIELD_ARTWORK_DATA_TYPE))
|
||||
? bundle.getInt(keyForField(FIELD_ARTWORK_DATA_TYPE))
|
||||
: null)
|
||||
.setArtworkUri(bundle.getParcelable(keyForField(FIELD_ARTWORK_URI)))
|
||||
.setWriter(bundle.getCharSequence(keyForField(FIELD_WRITER)))
|
||||
.setComposer(bundle.getCharSequence(keyForField(FIELD_COMPOSER)))
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public final class PictureFrame implements Metadata.Entry {
|
|||
|
||||
@Override
|
||||
public void populateMediaMetadata(MediaMetadata.Builder builder) {
|
||||
builder.setArtworkData(pictureData);
|
||||
builder.maybeSetArtworkData(pictureData, pictureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public final class ApicFrame extends Id3Frame {
|
|||
|
||||
@Override
|
||||
public void populateMediaMetadata(MediaMetadata.Builder builder) {
|
||||
builder.setArtworkData(pictureData);
|
||||
builder.maybeSetArtworkData(pictureData, pictureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@ import static com.google.common.truth.Truth.assertThat;
|
|||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.MediaMetadata.PictureType;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.id3.ApicFrame;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
import java.util.Arrays;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
|
|
@ -46,6 +46,7 @@ public class MediaMetadataTest {
|
|||
assertThat(mediaMetadata.userRating).isNull();
|
||||
assertThat(mediaMetadata.overallRating).isNull();
|
||||
assertThat(mediaMetadata.artworkData).isNull();
|
||||
assertThat(mediaMetadata.artworkDataType).isNull();
|
||||
assertThat(mediaMetadata.artworkUri).isNull();
|
||||
assertThat(mediaMetadata.trackNumber).isNull();
|
||||
assertThat(mediaMetadata.totalTrackCount).isNull();
|
||||
|
|
@ -79,9 +80,10 @@ public class MediaMetadataTest {
|
|||
@Test
|
||||
public void builderSetArtworkData_setsArtworkData() {
|
||||
byte[] bytes = new byte[] {35, 12, 6, 77};
|
||||
MediaMetadata mediaMetadata = new MediaMetadata.Builder().setArtworkData(bytes).build();
|
||||
MediaMetadata mediaMetadata =
|
||||
new MediaMetadata.Builder().setArtworkData(new byte[] {35, 12, 6, 77}, null).build();
|
||||
|
||||
assertThat(Arrays.equals(mediaMetadata.artworkData, bytes)).isTrue();
|
||||
assertThat(mediaMetadata.artworkData).isEqualTo(bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -104,7 +106,8 @@ public class MediaMetadataTest {
|
|||
.setMediaUri(Uri.parse("https://www.google.com"))
|
||||
.setUserRating(new HeartRating(false))
|
||||
.setOverallRating(new PercentageRating(87.4f))
|
||||
.setArtworkData(new byte[] {-88, 12, 3, 2, 124, -54, -33, 69})
|
||||
.setArtworkData(
|
||||
new byte[] {-88, 12, 3, 2, 124, -54, -33, 69}, MediaMetadata.PICTURE_TYPE_MEDIA)
|
||||
.setTrackNumber(4)
|
||||
.setTotalTrackCount(12)
|
||||
.setFolderType(MediaMetadata.FOLDER_TYPE_PLAYLISTS)
|
||||
|
|
@ -133,11 +136,12 @@ public class MediaMetadataTest {
|
|||
@Test
|
||||
public void builderPopulatedFromApicFrameEntry_setsArtwork() {
|
||||
byte[] pictureData = new byte[] {-12, 52, 33, 85, 34, 22, 1, -55};
|
||||
@PictureType int pictureType = MediaMetadata.PICTURE_TYPE_LEAFLET_PAGE;
|
||||
Metadata.Entry entry =
|
||||
new ApicFrame(
|
||||
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
|
||||
/* description= */ "an image",
|
||||
/* pictureType= */ 0x03,
|
||||
pictureType,
|
||||
pictureData);
|
||||
|
||||
MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
|
||||
|
|
@ -145,5 +149,65 @@ public class MediaMetadataTest {
|
|||
|
||||
MediaMetadata mediaMetadata = builder.build();
|
||||
assertThat(mediaMetadata.artworkData).isEqualTo(pictureData);
|
||||
assertThat(mediaMetadata.artworkDataType).isEqualTo(pictureType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderPopulatedFromApicFrameEntry_considersTypePriority() {
|
||||
byte[] data1 = new byte[] {1, 1, 1, 1};
|
||||
Metadata.Entry entry1 =
|
||||
new ApicFrame(
|
||||
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
|
||||
/* description= */ "an image",
|
||||
MediaMetadata.PICTURE_TYPE_BAND_ARTIST_LOGO,
|
||||
data1);
|
||||
byte[] data2 = new byte[] {2, 2, 2, 2};
|
||||
Metadata.Entry entry2 =
|
||||
new ApicFrame(
|
||||
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
|
||||
/* description= */ "an image",
|
||||
MediaMetadata.PICTURE_TYPE_ARTIST_PERFORMER,
|
||||
data2);
|
||||
byte[] data3 = new byte[] {3, 3, 3, 3};
|
||||
Metadata.Entry entry3 =
|
||||
new ApicFrame(
|
||||
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
|
||||
/* description= */ "an image",
|
||||
MediaMetadata.PICTURE_TYPE_FRONT_COVER,
|
||||
data3);
|
||||
byte[] data4 = new byte[] {4, 4, 4, 4};
|
||||
Metadata.Entry entry4 =
|
||||
new ApicFrame(
|
||||
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
|
||||
/* description= */ "an image",
|
||||
MediaMetadata.PICTURE_TYPE_ILLUSTRATION,
|
||||
data4);
|
||||
byte[] data5 = new byte[] {5, 5, 5, 5};
|
||||
Metadata.Entry entry5 =
|
||||
new ApicFrame(
|
||||
/* mimeType= */ MimeTypes.BASE_TYPE_IMAGE,
|
||||
/* description= */ "an image",
|
||||
MediaMetadata.PICTURE_TYPE_FRONT_COVER,
|
||||
data5);
|
||||
MediaMetadata.Builder builder = MediaMetadata.EMPTY.buildUpon();
|
||||
|
||||
entry1.populateMediaMetadata(builder);
|
||||
assertThat(builder.build().artworkData).isEqualTo(data1);
|
||||
|
||||
// Data updates when any type is given, if the current type is not front cover.
|
||||
entry2.populateMediaMetadata(builder);
|
||||
assertThat(builder.build().artworkData).isEqualTo(data2);
|
||||
|
||||
// Data updates because this entry picture type is front cover.
|
||||
entry3.populateMediaMetadata(builder);
|
||||
assertThat(builder.build().artworkData).isEqualTo(data3);
|
||||
|
||||
// Data does not update because the current type is front cover, and this entry type is not.
|
||||
entry4.populateMediaMetadata(builder);
|
||||
assertThat(builder.build().artworkData).isEqualTo(data3);
|
||||
|
||||
// Data updates because this entry picture type is front cover.
|
||||
entry5.populateMediaMetadata(builder);
|
||||
assertThat(builder.build().artworkData).isEqualTo(data5);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue