diff --git a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java index 8ef7bd13f1..143c70ebb3 100644 --- a/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java +++ b/library/dash/src/main/java/com/google/android/exoplayer2/source/dash/DashMediaSource.java @@ -79,6 +79,7 @@ public final class DashMediaSource extends BaseMediaSource { private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private int minLoadableRetryCount; private long livePresentationDelayMs; + private long defaultLivePresentationDelayMs; private boolean isCreateCalled; private @Nullable Object tag; @@ -98,6 +99,7 @@ public final class DashMediaSource extends BaseMediaSource { this.manifestDataSourceFactory = manifestDataSourceFactory; minLoadableRetryCount = DEFAULT_MIN_LOADABLE_RETRY_COUNT; livePresentationDelayMs = DEFAULT_LIVE_PRESENTATION_DELAY_PREFER_MANIFEST_MS; + defaultLivePresentationDelayMs = DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS; compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory(); } @@ -147,6 +149,26 @@ public final class DashMediaSource extends BaseMediaSource { this.livePresentationDelayMs = livePresentationDelayMs; return this; } + + /** + * Sets the duration in milliseconds by which the default start position should precede the end + * of the live window for live playbacks if the value is not present in the manifest. + * The default value is {@link #DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS}. This value is only + * used when {@link setLivePresentationDelayMs} has not overwritten the presentation delay to a + * value other than #DEFAULT_LIVE_PRESENTATION_DELAY_PREFER_MANIFEST_MS + * + * @param defaultLivePresentationDelayMs For live playbacks, the duration in milliseconds by + * which the default start position should precede the end of the live window if the + * duration is not specifed in the manifest or overwritten using + * {@link setLivePresentationDelayMs}. + * @return This factory, for convenience. + * @throws IllegalStateException If one of the {@code create} methods has already been called. + */ + public Factory setDefaultLivePresentationDelayMs(long defaultLivePresentationDelayMs) { + Assertions.checkState(!isCreateCalled); + this.defaultLivePresentationDelayMs = defaultLivePresentationDelayMs; + return this; + } /** * Sets the manifest parser to parse loaded manifest data when loading a manifest URI. @@ -201,6 +223,7 @@ public final class DashMediaSource extends BaseMediaSource { compositeSequenceableLoaderFactory, minLoadableRetryCount, livePresentationDelayMs, + defaultLivePresentationDelayMs, tag); } @@ -241,6 +264,7 @@ public final class DashMediaSource extends BaseMediaSource { compositeSequenceableLoaderFactory, minLoadableRetryCount, livePresentationDelayMs, + defaultLivePresentationDelayMs, tag); } @@ -302,6 +326,7 @@ public final class DashMediaSource extends BaseMediaSource { private final CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory; private final int minLoadableRetryCount; private final long livePresentationDelayMs; + private final long defaultLivePresentationDelayMs; private final EventDispatcher manifestEventDispatcher; private final ParsingLoadable.Parser manifestParser; private final ManifestCallback manifestCallback; @@ -379,6 +404,7 @@ public final class DashMediaSource extends BaseMediaSource { new DefaultCompositeSequenceableLoaderFactory(), minLoadableRetryCount, DEFAULT_LIVE_PRESENTATION_DELAY_PREFER_MANIFEST_MS, + DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS, /* tag= */ null); if (eventHandler != null && eventListener != null) { addEventListener(eventHandler, eventListener); @@ -476,6 +502,7 @@ public final class DashMediaSource extends BaseMediaSource { new DefaultCompositeSequenceableLoaderFactory(), minLoadableRetryCount, livePresentationDelayMs, + DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS, /* tag= */ null); if (eventHandler != null && eventListener != null) { addEventListener(eventHandler, eventListener); @@ -491,6 +518,7 @@ public final class DashMediaSource extends BaseMediaSource { CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory, int minLoadableRetryCount, long livePresentationDelayMs, + long defaultLivePresentationDelayMs, @Nullable Object tag) { this.initialManifestUri = manifestUri; this.manifest = manifest; @@ -500,6 +528,7 @@ public final class DashMediaSource extends BaseMediaSource { this.chunkSourceFactory = chunkSourceFactory; this.minLoadableRetryCount = minLoadableRetryCount; this.livePresentationDelayMs = livePresentationDelayMs; + this.defaultLivePresentationDelayMs = defaultLivePresentationDelayMs; this.compositeSequenceableLoaderFactory = compositeSequenceableLoaderFactory; this.tag = tag; sideloadedManifest = manifest != null; @@ -885,7 +914,7 @@ public final class DashMediaSource extends BaseMediaSource { long presentationDelayForManifestMs = livePresentationDelayMs; if (presentationDelayForManifestMs == DEFAULT_LIVE_PRESENTATION_DELAY_PREFER_MANIFEST_MS) { presentationDelayForManifestMs = manifest.suggestedPresentationDelayMs != C.TIME_UNSET - ? manifest.suggestedPresentationDelayMs : DEFAULT_LIVE_PRESENTATION_DELAY_FIXED_MS; + ? manifest.suggestedPresentationDelayMs : defaultLivePresentationDelayMs; } // Snap the default position to the start of the segment containing it. windowDefaultStartPositionUs = windowDurationUs - C.msToUs(presentationDelayForManifestMs);