Add imageDurationMs to MediaItem

PiperOrigin-RevId: 551776350
This commit is contained in:
tofunmi 2023-07-28 09:29:37 +01:00 committed by Rohit Singh
parent ccdde8806e
commit ebbcec9a20
2 changed files with 54 additions and 5 deletions

View File

@ -15,6 +15,7 @@
*/
package androidx.media3.common;
import static androidx.media3.common.util.Assertions.checkArgument;
import static androidx.media3.common.util.Assertions.checkNotNull;
import static androidx.media3.common.util.Assertions.checkState;
@ -77,6 +78,7 @@ public final class MediaItem implements Bundleable {
private ImmutableList<SubtitleConfiguration> subtitleConfigurations;
@Nullable private AdsConfiguration adsConfiguration;
@Nullable private Object tag;
private long imageDurationMs;
@Nullable private MediaMetadata mediaMetadata;
// TODO: Change this to LiveConfiguration once all the deprecated individual setters
// are removed.
@ -92,6 +94,7 @@ public final class MediaItem implements Bundleable {
subtitleConfigurations = ImmutableList.of();
liveConfiguration = new LiveConfiguration.Builder();
requestMetadata = RequestMetadata.EMPTY;
imageDurationMs = C.TIME_UNSET;
}
private Builder(MediaItem mediaItem) {
@ -114,6 +117,7 @@ public final class MediaItem implements Bundleable {
? localConfiguration.drmConfiguration.buildUpon()
: new DrmConfiguration.Builder();
adsConfiguration = localConfiguration.adsConfiguration;
imageDurationMs = localConfiguration.imageDurationMs;
}
}
@ -555,6 +559,22 @@ public final class MediaItem implements Bundleable {
return this;
}
/**
* Sets the image duration in video output, in milliseconds.
*
* <p>Must be set if {@linkplain #setUri the uri} is set and resolves to an image. Ignored
* otherwise.
*
* <p>Default value is {@link C#TIME_UNSET}.
*/
@CanIgnoreReturnValue
@UnstableApi
public Builder setImageDurationMs(long imageDurationMs) {
checkArgument(imageDurationMs > 0 || imageDurationMs == C.TIME_UNSET);
this.imageDurationMs = imageDurationMs;
return this;
}
/** Sets the media metadata. */
@CanIgnoreReturnValue
public Builder setMediaMetadata(MediaMetadata mediaMetadata) {
@ -585,7 +605,8 @@ public final class MediaItem implements Bundleable {
streamKeys,
customCacheKey,
subtitleConfigurations,
tag);
tag,
imageDurationMs);
}
return new MediaItem(
mediaId != null ? mediaId : DEFAULT_MEDIA_ID,
@ -599,7 +620,6 @@ public final class MediaItem implements Bundleable {
/** DRM configuration for a media item. */
public static final class DrmConfiguration implements Bundleable {
/** Builder for {@link DrmConfiguration}. */
public static final class Builder {
@ -1128,6 +1148,9 @@ public final class MediaItem implements Bundleable {
*/
@Nullable public final Object tag;
/** Duration for image assets in milliseconds. */
@UnstableApi public final long imageDurationMs;
@SuppressWarnings("deprecation") // Setting deprecated subtitles field.
private LocalConfiguration(
Uri uri,
@ -1137,7 +1160,8 @@ public final class MediaItem implements Bundleable {
List<StreamKey> streamKeys,
@Nullable String customCacheKey,
ImmutableList<SubtitleConfiguration> subtitleConfigurations,
@Nullable Object tag) {
@Nullable Object tag,
long imageDurationMs) {
this.uri = uri;
this.mimeType = mimeType;
this.drmConfiguration = drmConfiguration;
@ -1151,6 +1175,7 @@ public final class MediaItem implements Bundleable {
}
this.subtitles = subtitles.build();
this.tag = tag;
this.imageDurationMs = imageDurationMs;
}
@Override
@ -1170,7 +1195,8 @@ public final class MediaItem implements Bundleable {
&& streamKeys.equals(other.streamKeys)
&& Util.areEqual(customCacheKey, other.customCacheKey)
&& subtitleConfigurations.equals(other.subtitleConfigurations)
&& Util.areEqual(tag, other.tag);
&& Util.areEqual(tag, other.tag)
&& Util.areEqual(imageDurationMs, other.imageDurationMs);
}
@Override
@ -1183,6 +1209,7 @@ public final class MediaItem implements Bundleable {
result = 31 * result + (customCacheKey == null ? 0 : customCacheKey.hashCode());
result = 31 * result + subtitleConfigurations.hashCode();
result = 31 * result + (tag == null ? 0 : tag.hashCode());
result = (int) (31L * result + imageDurationMs);
return result;
}
@ -1195,6 +1222,7 @@ public final class MediaItem implements Bundleable {
private static final String FIELD_STREAM_KEYS = Util.intToStringMaxRadix(4);
private static final String FIELD_CUSTOM_CACHE_KEY = Util.intToStringMaxRadix(5);
private static final String FIELD_SUBTITLE_CONFIGURATION = Util.intToStringMaxRadix(6);
private static final String FIELD_IMAGE_DURATION_MS = Util.intToStringMaxRadix(7);
/**
* {@inheritDoc}
@ -1227,6 +1255,9 @@ public final class MediaItem implements Bundleable {
bundle.putParcelableArrayList(
FIELD_SUBTITLE_CONFIGURATION, BundleableUtil.toBundleArrayList(subtitleConfigurations));
}
if (imageDurationMs != C.TIME_UNSET) {
bundle.putLong(FIELD_IMAGE_DURATION_MS, imageDurationMs);
}
return bundle;
}
@ -1253,6 +1284,7 @@ public final class MediaItem implements Bundleable {
subtitleBundles == null
? ImmutableList.of()
: BundleableUtil.fromBundleList(SubtitleConfiguration.CREATOR, subtitleBundles);
long imageDurationMs = bundle.getLong(FIELD_IMAGE_DURATION_MS, C.TIME_UNSET);
return new LocalConfiguration(
checkNotNull(bundle.getParcelable(FIELD_URI)),
@ -1262,7 +1294,8 @@ public final class MediaItem implements Bundleable {
streamKeys,
bundle.getString(FIELD_CUSTOM_CACHE_KEY),
subtitleConfiguration,
/* tag= */ null);
/* tag= */ null,
imageDurationMs);
}
}

View File

@ -390,6 +390,22 @@ public class MediaItemTest {
assertThat(mediaItem.localConfiguration.tag).isEqualTo(tag);
}
@Test
public void builderSetImageDurationMs_isTimeUnsetTByDefault() {
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build();
assertThat(mediaItem.localConfiguration.imageDurationMs).isEqualTo(C.TIME_UNSET);
}
@Test
public void builderSetImageDurationMs_setsImageDurationMs() {
long duration = 1;
MediaItem mediaItem =
new MediaItem.Builder().setUri(URI_STRING).setImageDurationMs(duration).build();
assertThat(mediaItem.localConfiguration.imageDurationMs).isEqualTo(duration);
}
@Test
@SuppressWarnings("deprecation") // Testing deprecated field
public void builderSetClippingConfiguration() {