Allow to set live properties on DefaultMediaSourceFactory

Issue: #4904
PiperOrigin-RevId: 336841049
This commit is contained in:
christosts 2020-10-13 10:59:52 +01:00 committed by kim-vde
parent 0756f304d6
commit 09598580f2
2 changed files with 121 additions and 1 deletions

View File

@ -15,6 +15,8 @@
*/
package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.content.Context;
import android.net.Uri;
import android.util.SparseArray;
@ -107,6 +109,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
@Nullable private DrmSessionManager drmSessionManager;
@Nullable private List<StreamKey> streamKeys;
@Nullable private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private long liveTargetOffsetMs;
private float liveMinSpeed;
private float liveMaxSpeed;
/**
* Creates a new instance.
@ -155,6 +160,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
for (int i = 0; i < mediaSourceFactories.size(); i++) {
supportedTypes[i] = mediaSourceFactories.keyAt(i);
}
liveTargetOffsetMs = C.TIME_UNSET;
liveMinSpeed = C.RATE_UNSET;
liveMaxSpeed = C.RATE_UNSET;
}
/**
@ -181,6 +189,42 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
return this;
}
/**
* Sets the target live offset for live streams, in milliseconds.
*
* @param liveTargetOffsetMs The target live offset, in milliseconds, or {@link C#TIME_UNSET} to
* use the media-defined default.
* @return This factory, for convenience.
*/
public DefaultMediaSourceFactory setLiveTargetOffsetMs(long liveTargetOffsetMs) {
this.liveTargetOffsetMs = liveTargetOffsetMs;
return this;
}
/**
* Sets the minimum playback speed for live streams.
*
* @param minSpeed The minimum playback speed for live streams, or {@link C#RATE_UNSET} to use the
* media-defined default.
* @return This factory, for convenience.
*/
public DefaultMediaSourceFactory setLiveMinSpeed(float minSpeed) {
this.liveMinSpeed = minSpeed;
return this;
}
/**
* Sets the maximum playback speed for live streams.
*
* @param maxSpeed The maximum playback speed for live streams, or {@link C#RATE_UNSET} to use the
* media-defined default.
* @return This factory, for convenience.
*/
public DefaultMediaSourceFactory setLiveMaxSpeed(float maxSpeed) {
this.liveMaxSpeed = maxSpeed;
return this;
}
@Override
public DefaultMediaSourceFactory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
@ -244,9 +288,33 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
: streamKeys);
mediaSourceFactory.setLoadErrorHandlingPolicy(loadErrorHandlingPolicy);
// Make sure to retain the very same media item instance, if no value needs to be overridden.
if ((mediaItem.liveConfiguration.targetLiveOffsetMs == C.TIME_UNSET
&& liveTargetOffsetMs != C.TIME_UNSET)
|| (mediaItem.liveConfiguration.minPlaybackSpeed == C.RATE_UNSET
&& liveMinSpeed != C.RATE_UNSET)
|| (mediaItem.liveConfiguration.maxPlaybackSpeed == C.RATE_UNSET
&& liveMaxSpeed != C.RATE_UNSET)) {
mediaItem =
mediaItem
.buildUpon()
.setLiveTargetOffsetMs(
mediaItem.liveConfiguration.targetLiveOffsetMs == C.TIME_UNSET
? liveTargetOffsetMs
: mediaItem.liveConfiguration.targetLiveOffsetMs)
.setLiveMinPlaybackSpeed(
mediaItem.liveConfiguration.minPlaybackSpeed == C.RATE_UNSET
? liveMinSpeed
: mediaItem.liveConfiguration.minPlaybackSpeed)
.setLiveMaxPlaybackSpeed(
mediaItem.liveConfiguration.maxPlaybackSpeed == C.RATE_UNSET
? liveMaxSpeed
: mediaItem.liveConfiguration.maxPlaybackSpeed)
.build();
}
MediaSource mediaSource = mediaSourceFactory.createMediaSource(mediaItem);
List<MediaItem.Subtitle> subtitles = mediaItem.playbackProperties.subtitles;
List<MediaItem.Subtitle> subtitles = castNonNull(mediaItem.playbackProperties).subtitles;
if (!subtitles.isEmpty()) {
MediaSource[] mediaSources = new MediaSource[subtitles.size() + 1];
mediaSources[0] = mediaSource;

View File

@ -235,4 +235,56 @@ public final class DefaultMediaSourceFactoryTest {
assertThat(mediaSource).isNotInstanceOf(AdsMediaSource.class);
}
@Test
public void createMediaSource_undefinedLiveProperties_livePropertiesUnset() {
DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory((Context) ApplicationProvider.getApplicationContext());
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_MEDIA + "/file.mp4").build();
MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);
MediaItem mediaItemFromSource = mediaSource.getMediaItem();
assertThat(mediaItemFromSource.liveConfiguration.targetLiveOffsetMs).isEqualTo(C.TIME_UNSET);
assertThat(mediaItemFromSource.liveConfiguration.minPlaybackSpeed).isEqualTo(C.RATE_UNSET);
assertThat(mediaItemFromSource.liveConfiguration.maxPlaybackSpeed).isEqualTo(C.RATE_UNSET);
}
@Test
public void createMediaSource_withoutMediaItemProperties_usesFactoryLiveProperties() {
DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory((Context) ApplicationProvider.getApplicationContext())
.setLiveTargetOffsetMs(20)
.setLiveMinSpeed(.1f)
.setLiveMaxSpeed(2.0f);
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_MEDIA + "/file.mp4").build();
MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);
MediaItem mediaItemFromSource = mediaSource.getMediaItem();
assertThat(mediaItemFromSource.liveConfiguration.targetLiveOffsetMs).isEqualTo(20);
assertThat(mediaItemFromSource.liveConfiguration.minPlaybackSpeed).isEqualTo(.1f);
assertThat(mediaItemFromSource.liveConfiguration.maxPlaybackSpeed).isEqualTo(2.0f);
}
@Test
public void createMediaSource_withMediaItemLiveProperties_overridesFactoryLiveProperties() {
DefaultMediaSourceFactory defaultMediaSourceFactory =
new DefaultMediaSourceFactory((Context) ApplicationProvider.getApplicationContext())
.setLiveTargetOffsetMs(20)
.setLiveMinSpeed(.1f)
.setLiveMaxSpeed(2.0f);
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(URI_MEDIA + "/file.mp4")
.setLiveTargetOffsetMs(10)
.setLiveMinPlaybackSpeed(20.0f)
.setLiveMaxPlaybackSpeed(20.0f)
.build();
MediaSource mediaSource = defaultMediaSourceFactory.createMediaSource(mediaItem);
MediaItem mediaItemFromSource = mediaSource.getMediaItem();
assertThat(mediaItemFromSource).isEqualTo(mediaItem);
}
}