Add ClippingConfiguration.allowUnseekableMedia

PiperOrigin-RevId: 731240278
This commit is contained in:
tonihei 2025-02-26 03:09:32 -08:00 committed by Copybara-Service
parent 676fe86028
commit 4f039eaafa
5 changed files with 43 additions and 6 deletions

View File

@ -1853,6 +1853,7 @@ public final class MediaItem {
private boolean relativeToLiveWindow;
private boolean relativeToDefaultPosition;
private boolean startsAtKeyFrame;
private boolean allowUnseekableMedia;
/** Creates a new instance with default values. */
public Builder() {
@ -1865,6 +1866,7 @@ public final class MediaItem {
relativeToLiveWindow = clippingConfiguration.relativeToLiveWindow;
relativeToDefaultPosition = clippingConfiguration.relativeToDefaultPosition;
startsAtKeyFrame = clippingConfiguration.startsAtKeyFrame;
allowUnseekableMedia = clippingConfiguration.allowUnseekableMedia;
}
/**
@ -1942,6 +1944,21 @@ public final class MediaItem {
return this;
}
/**
* Sets whether clipping to a non-zero start position in unseekable media is allowed (Default:
* {@code false}).
*
* <p>Note that this could be inefficient because a player needs to read and decode all
* samples from the beginning of the file and it should only be used if the clip start
* position is small and the entire data before the start position fits into memory.
*/
@UnstableApi
@CanIgnoreReturnValue
public Builder setAllowUnseekableMedia(boolean allowUnseekableMedia) {
this.allowUnseekableMedia = allowUnseekableMedia;
return this;
}
/**
* Returns a {@link ClippingConfiguration} instance initialized with the values of this
* builder.
@ -1994,9 +2011,12 @@ public final class MediaItem {
*/
public final boolean relativeToDefaultPosition;
/** Sets whether the start point is guaranteed to be a key frame. */
/** Whether the start point is guaranteed to be a key frame. */
public final boolean startsAtKeyFrame;
/** Whether clipping to a non-zero start position in unseekable media is allowed. */
@UnstableApi public final boolean allowUnseekableMedia;
private ClippingConfiguration(Builder builder) {
this.startPositionMs = usToMs(builder.startPositionUs);
this.endPositionMs = usToMs(builder.endPositionUs);
@ -2005,6 +2025,7 @@ public final class MediaItem {
this.relativeToLiveWindow = builder.relativeToLiveWindow;
this.relativeToDefaultPosition = builder.relativeToDefaultPosition;
this.startsAtKeyFrame = builder.startsAtKeyFrame;
this.allowUnseekableMedia = builder.allowUnseekableMedia;
}
/** Returns a {@link Builder} initialized with the values of this instance. */
@ -2027,7 +2048,8 @@ public final class MediaItem {
&& endPositionUs == other.endPositionUs
&& relativeToLiveWindow == other.relativeToLiveWindow
&& relativeToDefaultPosition == other.relativeToDefaultPosition
&& startsAtKeyFrame == other.startsAtKeyFrame;
&& startsAtKeyFrame == other.startsAtKeyFrame
&& allowUnseekableMedia == other.allowUnseekableMedia;
}
@Override
@ -2037,6 +2059,7 @@ public final class MediaItem {
result = 31 * result + (relativeToLiveWindow ? 1 : 0);
result = 31 * result + (relativeToDefaultPosition ? 1 : 0);
result = 31 * result + (startsAtKeyFrame ? 1 : 0);
result = 31 * result + (allowUnseekableMedia ? 1 : 0);
return result;
}
@ -2045,8 +2068,9 @@ public final class MediaItem {
private static final String FIELD_RELATIVE_TO_LIVE_WINDOW = Util.intToStringMaxRadix(2);
private static final String FIELD_RELATIVE_TO_DEFAULT_POSITION = Util.intToStringMaxRadix(3);
private static final String FIELD_STARTS_AT_KEY_FRAME = Util.intToStringMaxRadix(4);
static final String FIELD_START_POSITION_US = Util.intToStringMaxRadix(5);
static final String FIELD_END_POSITION_US = Util.intToStringMaxRadix(6);
@VisibleForTesting static final String FIELD_START_POSITION_US = Util.intToStringMaxRadix(5);
@VisibleForTesting static final String FIELD_END_POSITION_US = Util.intToStringMaxRadix(6);
private static final String FIELD_ALLOW_UNSEEKABLE_MEDIA = Util.intToStringMaxRadix(7);
@UnstableApi
public Bundle toBundle() {
@ -2072,6 +2096,9 @@ public final class MediaItem {
if (startsAtKeyFrame != UNSET.startsAtKeyFrame) {
bundle.putBoolean(FIELD_STARTS_AT_KEY_FRAME, startsAtKeyFrame);
}
if (allowUnseekableMedia != UNSET.allowUnseekableMedia) {
bundle.putBoolean(FIELD_ALLOW_UNSEEKABLE_MEDIA, allowUnseekableMedia);
}
return bundle;
}
@ -2096,7 +2123,11 @@ public final class MediaItem {
/* defaultValue= */ UNSET.relativeToDefaultPosition))
.setStartsAtKeyFrame(
bundle.getBoolean(
FIELD_STARTS_AT_KEY_FRAME, /* defaultValue= */ UNSET.startsAtKeyFrame));
FIELD_STARTS_AT_KEY_FRAME, /* defaultValue= */ UNSET.startsAtKeyFrame))
.setAllowUnseekableMedia(
bundle.getBoolean(
FIELD_ALLOW_UNSEEKABLE_MEDIA,
/* defaultValue= */ UNSET.allowUnseekableMedia));
long startPositionUs =
bundle.getLong(FIELD_START_POSITION_US, /* defaultValue= */ UNSET.startPositionUs);
if (startPositionUs != UNSET.startPositionUs) {

View File

@ -450,6 +450,7 @@ public class MediaItemTest {
.setRelativeToLiveWindow(true)
.setRelativeToDefaultPosition(true)
.setStartsAtKeyFrame(true)
.setAllowUnseekableMedia(true)
.build())
.build();
@ -458,6 +459,7 @@ public class MediaItemTest {
assertThat(mediaItem.clippingConfiguration.relativeToLiveWindow).isTrue();
assertThat(mediaItem.clippingConfiguration.relativeToDefaultPosition).isTrue();
assertThat(mediaItem.clippingConfiguration.startsAtKeyFrame).isTrue();
assertThat(mediaItem.clippingConfiguration.allowUnseekableMedia).isTrue();
assertThat(mediaItem.clippingConfiguration).isEqualTo(mediaItem.clippingProperties);
}
@ -475,6 +477,7 @@ public class MediaItemTest {
assertThat(clippingConfiguration.relativeToLiveWindow).isFalse();
assertThat(clippingConfiguration.relativeToDefaultPosition).isFalse();
assertThat(clippingConfiguration.startsAtKeyFrame).isFalse();
assertThat(clippingConfiguration.allowUnseekableMedia).isFalse();
assertThat(clippingConfiguration).isEqualTo(MediaItem.ClippingConfiguration.UNSET);
}
@ -503,6 +506,7 @@ public class MediaItemTest {
.setStartPositionMs(1000L)
.setEndPositionUs(2000_031L)
.setStartsAtKeyFrame(true)
.setAllowUnseekableMedia(true)
.build();
MediaItem.ClippingConfiguration clippingConfigurationFromBundle =

View File

@ -200,7 +200,7 @@ public final class ClippingMediaSource extends WrappingMediaSource {
* Sets whether clipping to a non-zero start position in unseekable media is allowed.
*
* <p>Note that this is inefficient because the player needs to read and decode all samples from
* the beginning of the file and it should only be used if the seek start position is small and
* the beginning of the file and it should only be used if the clip start position is small and
* the entire data before the start position fits into memory.
*
* <p>The default value is {@code false}.

View File

@ -589,6 +589,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
.setEnableInitialDiscontinuity(!mediaItem.clippingConfiguration.startsAtKeyFrame)
.setAllowDynamicClippingUpdates(mediaItem.clippingConfiguration.relativeToLiveWindow)
.setRelativeToDefaultPosition(mediaItem.clippingConfiguration.relativeToDefaultPosition)
.setAllowUnseekableMedia(mediaItem.clippingConfiguration.allowUnseekableMedia)
.build();
}

View File

@ -611,6 +611,7 @@ public final class ClippingMediaSourceTest {
.setEnableInitialDiscontinuity(!mediaItem.clippingConfiguration.startsAtKeyFrame)
.setAllowDynamicClippingUpdates(mediaItem.clippingConfiguration.relativeToLiveWindow)
.setRelativeToDefaultPosition(mediaItem.clippingConfiguration.relativeToDefaultPosition)
.setAllowUnseekableMedia(mediaItem.clippingConfiguration.allowUnseekableMedia)
.build();
}