Skip to content

Commit

Permalink
Add min/max live offset to MediaItem.LiveConfiguration.
Browse files Browse the repository at this point in the history
This allows the user and the media to define bounds in which the live offset
can vary.

Issue: #4904
PiperOrigin-RevId: 339214605
  • Loading branch information
tonihei authored and ojw28 committed Nov 2, 2020
1 parent d436a69 commit e571936
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public static final class Builder {
@Nullable private Object tag;
@Nullable private MediaMetadata mediaMetadata;
private long liveTargetOffsetMs;
private long liveMinOffsetMs;
private long liveMaxOffsetMs;
private float liveMinPlaybackSpeed;
private float liveMaxPlaybackSpeed;

Expand All @@ -88,6 +90,8 @@ public Builder() {
streamKeys = Collections.emptyList();
subtitles = Collections.emptyList();
liveTargetOffsetMs = C.TIME_UNSET;
liveMinOffsetMs = C.TIME_UNSET;
liveMaxOffsetMs = C.TIME_UNSET;
liveMinPlaybackSpeed = C.RATE_UNSET;
liveMaxPlaybackSpeed = C.RATE_UNSET;
}
Expand All @@ -102,6 +106,8 @@ private Builder(MediaItem mediaItem) {
mediaId = mediaItem.mediaId;
mediaMetadata = mediaItem.mediaMetadata;
liveTargetOffsetMs = mediaItem.liveConfiguration.targetLiveOffsetMs;
liveMinOffsetMs = mediaItem.liveConfiguration.minLiveOffsetMs;
liveMaxOffsetMs = mediaItem.liveConfiguration.maxLiveOffsetMs;
liveMinPlaybackSpeed = mediaItem.liveConfiguration.minPlaybackSpeed;
liveMaxPlaybackSpeed = mediaItem.liveConfiguration.maxPlaybackSpeed;
@Nullable PlaybackProperties playbackProperties = mediaItem.playbackProperties;
Expand Down Expand Up @@ -436,6 +442,32 @@ public Builder setLiveTargetOffsetMs(long liveTargetOffsetMs) {
return this;
}

/**
* Sets the optional minimum offset from the live edge for live streams, in milliseconds.
*
* <p>See {@code Player#getCurrentLiveOffset()}.
*
* @param liveMinOffsetMs The minimum allowed live offset, in milliseconds, or {@link
* C#TIME_UNSET} to use the media-defined default.
*/
public Builder setLiveMinOffsetMs(long liveMinOffsetMs) {
this.liveMinOffsetMs = liveMinOffsetMs;
return this;
}

/**
* Sets the optional maximum offset from the live edge for live streams, in milliseconds.
*
* <p>See {@code Player#getCurrentLiveOffset()}.
*
* @param liveMaxOffsetMs The maximum allowed live offset, in milliseconds, or {@link
* C#TIME_UNSET} to use the media-defined default.
*/
public Builder setLiveMaxOffsetMs(long liveMaxOffsetMs) {
this.liveMaxOffsetMs = liveMaxOffsetMs;
return this;
}

/**
* Sets the optional minimum playback speed for live stream speed adjustment.
*
Expand Down Expand Up @@ -519,7 +551,12 @@ public MediaItem build() {
clipRelativeToDefaultPosition,
clipStartsAtKeyFrame),
playbackProperties,
new LiveConfiguration(liveTargetOffsetMs, liveMinPlaybackSpeed, liveMaxPlaybackSpeed),
new LiveConfiguration(
liveTargetOffsetMs,
liveMinOffsetMs,
liveMaxOffsetMs,
liveMinPlaybackSpeed,
liveMaxPlaybackSpeed),
mediaMetadata != null ? mediaMetadata : new MediaMetadata.Builder().build());
}
}
Expand Down Expand Up @@ -712,14 +749,26 @@ public static final class LiveConfiguration {

/** A live playback configuration with unset values. */
public static final LiveConfiguration UNSET =
new LiveConfiguration(C.TIME_UNSET, C.RATE_UNSET, C.RATE_UNSET);
new LiveConfiguration(C.TIME_UNSET, C.TIME_UNSET, C.TIME_UNSET, C.RATE_UNSET, C.RATE_UNSET);

/**
* Target live offset, in milliseconds, or {@link C#TIME_UNSET} to use the media-defined
* default.
*/
public final long targetLiveOffsetMs;

/**
* The minimum allowed live offset, in milliseconds, or {@link C#TIME_UNSET} to use the
* media-defined default.
*/
public final long minLiveOffsetMs;

/**
* The maximum allowed live offset, in milliseconds, or {@link C#TIME_UNSET} to use the
* media-defined default.
*/
public final long maxLiveOffsetMs;

/** Minimum playback speed, or {@link C#RATE_UNSET} to use the media-defined default. */
public final float minPlaybackSpeed;

Expand All @@ -731,14 +780,24 @@ public static final class LiveConfiguration {
*
* @param targetLiveOffsetMs Target live offset, in milliseconds, or {@link C#TIME_UNSET} to use
* the media-defined default.
* @param minLiveOffsetMs The minimum allowed live offset, in milliseconds, or {@link
* C#TIME_UNSET} to use the media-defined default.
* @param maxLiveOffsetMs The maximum allowed live offset, in milliseconds, or {@link
* C#TIME_UNSET} to use the media-defined default.
* @param minPlaybackSpeed Minimum playback speed, or {@link C#RATE_UNSET} to use the
* media-defined default.
* @param maxPlaybackSpeed Maximum playback speed, or {@link C#RATE_UNSET} to use the
* media-defined default.
*/
public LiveConfiguration(
long targetLiveOffsetMs, float minPlaybackSpeed, float maxPlaybackSpeed) {
long targetLiveOffsetMs,
long minLiveOffsetMs,
long maxLiveOffsetMs,
float minPlaybackSpeed,
float maxPlaybackSpeed) {
this.targetLiveOffsetMs = targetLiveOffsetMs;
this.minLiveOffsetMs = minLiveOffsetMs;
this.maxLiveOffsetMs = maxLiveOffsetMs;
this.minPlaybackSpeed = minPlaybackSpeed;
this.maxPlaybackSpeed = maxPlaybackSpeed;
}
Expand All @@ -754,13 +813,17 @@ public boolean equals(@Nullable Object obj) {
LiveConfiguration other = (LiveConfiguration) obj;

return targetLiveOffsetMs == other.targetLiveOffsetMs
&& minLiveOffsetMs == other.minLiveOffsetMs
&& maxLiveOffsetMs == other.maxLiveOffsetMs
&& minPlaybackSpeed == other.minPlaybackSpeed
&& maxPlaybackSpeed == other.maxPlaybackSpeed;
}

@Override
public int hashCode() {
int result = (int) (targetLiveOffsetMs ^ (targetLiveOffsetMs >>> 32));
result = 31 * result + (int) (minLiveOffsetMs ^ (minLiveOffsetMs >>> 32));
result = 31 * result + (int) (maxLiveOffsetMs ^ (maxLiveOffsetMs >>> 32));
result = 31 * result + (minPlaybackSpeed != 0 ? Float.floatToIntBits(minPlaybackSpeed) : 0);
result = 31 * result + (maxPlaybackSpeed != 0 ? Float.floatToIntBits(maxPlaybackSpeed) : 0);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ public void builderSetMediaMetadata_setsMetadata() {
}

@Test
public void builderSetLiveTargetLatencyMs_setsLiveTargetLatencyMs() {
public void builderSetLiveTargetOffsetMs_setsLiveTargetOffsetMs() {
MediaItem mediaItem =
new MediaItem.Builder().setUri(URI_STRING).setLiveTargetOffsetMs(10_000).build();

Expand All @@ -318,6 +318,22 @@ public void builderSetMaxLivePlaybackSpeed_setsMaxLivePlaybackSpeed() {
assertThat(mediaItem.liveConfiguration.maxPlaybackSpeed).isEqualTo(1.1f);
}

@Test
public void builderSetMinLiveOffset_setsMinLiveOffset() {
MediaItem mediaItem =
new MediaItem.Builder().setUri(URI_STRING).setLiveMinOffsetMs(1234).build();

assertThat(mediaItem.liveConfiguration.minLiveOffsetMs).isEqualTo(1234);
}

@Test
public void builderSetMaxLiveOffset_setsMaxLiveOffset() {
MediaItem mediaItem =
new MediaItem.Builder().setUri(URI_STRING).setLiveMaxOffsetMs(1234).build();

assertThat(mediaItem.liveConfiguration.maxLiveOffsetMs).isEqualTo(1234);
}

@Test
public void buildUpon_equalsToOriginal() {
MediaItem mediaItem =
Expand Down Expand Up @@ -346,6 +362,8 @@ public void buildUpon_equalsToOriginal() {
.setLiveTargetOffsetMs(20_000)
.setLiveMinPlaybackSpeed(.9f)
.setLiveMaxPlaybackSpeed(1.1f)
.setLiveMinOffsetMs(2222)
.setLiveMaxOffsetMs(4444)
.setSubtitles(
Collections.singletonList(
new MediaItem.Subtitle(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ public interface AdsLoaderProvider {
@Nullable private List<StreamKey> streamKeys;
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private long liveTargetOffsetMs;
private long liveMinOffsetMs;
private long liveMaxOffsetMs;
private float liveMinSpeed;
private float liveMaxSpeed;

Expand Down Expand Up @@ -161,6 +163,8 @@ public DefaultMediaSourceFactory(
supportedTypes[i] = mediaSourceFactories.keyAt(i);
}
liveTargetOffsetMs = C.TIME_UNSET;
liveMinOffsetMs = C.TIME_UNSET;
liveMaxOffsetMs = C.TIME_UNSET;
liveMinSpeed = C.RATE_UNSET;
liveMaxSpeed = C.RATE_UNSET;
}
Expand Down Expand Up @@ -201,6 +205,30 @@ public DefaultMediaSourceFactory setLiveTargetOffsetMs(long liveTargetOffsetMs)
return this;
}

/**
* Sets the minimum offset from the live edge for live streams, in milliseconds.
*
* @param liveMinOffsetMs The minimum allowed live offset, in milliseconds, or {@link
* C#TIME_UNSET} to use the media-defined default.
* @return This factory, for convenience.
*/
public DefaultMediaSourceFactory setLiveMinOffsetMs(long liveMinOffsetMs) {
this.liveMinOffsetMs = liveMinOffsetMs;
return this;
}

/**
* Sets the maximum offset from the live edge for live streams, in milliseconds.
*
* @param liveMaxOffsetMs The maximum allowed live offset, in milliseconds, or {@link
* C#TIME_UNSET} to use the media-defined default.
* @return This factory, for convenience.
*/
public DefaultMediaSourceFactory setLiveMaxOffsetMs(long liveMaxOffsetMs) {
this.liveMaxOffsetMs = liveMaxOffsetMs;
return this;
}

/**
* Sets the minimum playback speed for live streams.
*
Expand Down Expand Up @@ -294,7 +322,11 @@ public MediaSource createMediaSource(MediaItem mediaItem) {
|| (mediaItem.liveConfiguration.minPlaybackSpeed == C.RATE_UNSET
&& liveMinSpeed != C.RATE_UNSET)
|| (mediaItem.liveConfiguration.maxPlaybackSpeed == C.RATE_UNSET
&& liveMaxSpeed != C.RATE_UNSET)) {
&& liveMaxSpeed != C.RATE_UNSET)
|| (mediaItem.liveConfiguration.minLiveOffsetMs == C.TIME_UNSET
&& liveMinOffsetMs != C.TIME_UNSET)
|| (mediaItem.liveConfiguration.maxLiveOffsetMs == C.TIME_UNSET
&& liveMaxOffsetMs != C.TIME_UNSET)) {
mediaItem =
mediaItem
.buildUpon()
Expand All @@ -310,6 +342,14 @@ public MediaSource createMediaSource(MediaItem mediaItem) {
mediaItem.liveConfiguration.maxPlaybackSpeed == C.RATE_UNSET
? liveMaxSpeed
: mediaItem.liveConfiguration.maxPlaybackSpeed)
.setLiveMinOffsetMs(
mediaItem.liveConfiguration.minLiveOffsetMs == C.TIME_UNSET
? liveMinOffsetMs
: mediaItem.liveConfiguration.minLiveOffsetMs)
.setLiveMaxOffsetMs(
mediaItem.liveConfiguration.maxLiveOffsetMs == C.TIME_UNSET
? liveMaxOffsetMs
: mediaItem.liveConfiguration.maxLiveOffsetMs)
.build();
}
MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
Expand Down
Loading

0 comments on commit e571936

Please sign in to comment.