Simplify DownloadHelper

PiperOrigin-RevId: 312467496
This commit is contained in:
bachinger 2020-05-20 14:03:15 +01:00 committed by tonihei
parent b9157a9e23
commit d233c04582
7 changed files with 342 additions and 377 deletions

View File

@ -24,7 +24,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.offline.Download; import com.google.android.exoplayer2.offline.Download;
@ -106,7 +105,9 @@ public class DownloadTracker {
} }
startDownloadDialogHelper = startDownloadDialogHelper =
new StartDownloadDialogHelper( new StartDownloadDialogHelper(
fragmentManager, getDownloadHelper(mediaItem, renderersFactory), mediaItem); fragmentManager,
DownloadHelper.forMediaItem(context, mediaItem, renderersFactory, dataSourceFactory),
mediaItem);
} }
} }
@ -121,28 +122,6 @@ public class DownloadTracker {
} }
} }
private DownloadHelper getDownloadHelper(MediaItem mediaItem, RenderersFactory renderersFactory) {
MediaItem.PlaybackProperties playbackProperties = checkNotNull(mediaItem.playbackProperties);
@C.ContentType
int type =
Util.inferContentTypeWithMimeType(playbackProperties.uri, playbackProperties.mimeType);
switch (type) {
case C.TYPE_DASH:
return DownloadHelper.forDash(
context, playbackProperties.uri, dataSourceFactory, renderersFactory);
case C.TYPE_SS:
return DownloadHelper.forSmoothStreaming(
context, playbackProperties.uri, dataSourceFactory, renderersFactory);
case C.TYPE_HLS:
return DownloadHelper.forHls(
context, playbackProperties.uri, dataSourceFactory, renderersFactory);
case C.TYPE_OTHER:
return DownloadHelper.forProgressive(context, playbackProperties.uri);
default:
throw new IllegalStateException("Unsupported type: " + type);
}
}
private class DownloadManagerListener implements DownloadManager.Listener { private class DownloadManagerListener implements DownloadManager.Listener {
@Override @Override

View File

@ -62,7 +62,7 @@
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory, java.util.concurrent.Executor); <init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory, java.util.concurrent.Executor);
} }
# Constructors accessed via reflection in DefaultMediaSourceFactory and DownloadHelper # Constructors accessed via reflection in DefaultMediaSourceFactory
-dontnote com.google.android.exoplayer2.source.dash.DashMediaSource$Factory -dontnote com.google.android.exoplayer2.source.dash.DashMediaSource$Factory
-keepclasseswithmembers class com.google.android.exoplayer2.source.dash.DashMediaSource$Factory { -keepclasseswithmembers class com.google.android.exoplayer2.source.dash.DashMediaSource$Factory {
<init>(com.google.android.exoplayer2.upstream.DataSource$Factory); <init>(com.google.android.exoplayer2.upstream.DataSource$Factory);

View File

@ -15,6 +15,9 @@
*/ */
package com.google.android.exoplayer2.offline; package com.google.android.exoplayer2.offline;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import android.os.Handler; import android.os.Handler;
@ -24,18 +27,18 @@ import android.util.SparseIntArray;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlaybackException; import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RendererCapabilities; import com.google.android.exoplayer2.RendererCapabilities;
import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioRendererEventListener; import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
import com.google.android.exoplayer2.source.MediaPeriod; import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId; import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller; import com.google.android.exoplayer2.source.MediaSource.MediaSourceCaller;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
import com.google.android.exoplayer2.source.TrackGroup; import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
@ -50,14 +53,13 @@ import com.google.android.exoplayer2.trackselection.TrackSelectorResult;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.BandwidthMeter; import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSource.Factory;
import com.google.android.exoplayer2.upstream.DefaultAllocator; import com.google.android.exoplayer2.upstream.DefaultAllocator;
import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoRendererEventListener; import com.google.android.exoplayer2.video.VideoRendererEventListener;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
@ -144,18 +146,6 @@ public final class DownloadHelper {
/** Thrown at an attempt to download live content. */ /** Thrown at an attempt to download live content. */
public static class LiveContentUnsupportedException extends IOException {} public static class LiveContentUnsupportedException extends IOException {}
@Nullable
private static final Constructor<? extends MediaSourceFactory> DASH_FACTORY_CONSTRUCTOR =
getConstructor("com.google.android.exoplayer2.source.dash.DashMediaSource$Factory");
@Nullable
private static final Constructor<? extends MediaSourceFactory> SS_FACTORY_CONSTRUCTOR =
getConstructor("com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource$Factory");
@Nullable
private static final Constructor<? extends MediaSourceFactory> HLS_FACTORY_CONSTRUCTOR =
getConstructor("com.google.android.exoplayer2.source.hls.HlsMediaSource$Factory");
/** /**
* Extracts renderer capabilities for the renderers created by the provided renderers factory. * Extracts renderer capabilities for the renderers created by the provided renderers factory.
* *
@ -178,262 +168,264 @@ public final class DownloadHelper {
return capabilities; return capabilities;
} }
/** @deprecated Use {@link #forProgressive(Context, Uri)} */ /** @deprecated Use {@link #forMediaItem(Context, MediaItem)} */
@Deprecated @Deprecated
@SuppressWarnings("deprecation")
public static DownloadHelper forProgressive(Uri uri) {
return forProgressive(uri, /* cacheKey= */ null);
}
/**
* Creates a {@link DownloadHelper} for progressive streams.
*
* @param context Any {@link Context}.
* @param uri A stream {@link Uri}.
* @return A {@link DownloadHelper} for progressive streams.
*/
public static DownloadHelper forProgressive(Context context, Uri uri) { public static DownloadHelper forProgressive(Context context, Uri uri) {
return forProgressive(context, uri, /* cacheKey= */ null); return forMediaItem(context, new MediaItem.Builder().setUri(uri).build());
} }
/** @deprecated Use {@link #forProgressive(Context, Uri, String)} */ /** @deprecated Use {@link #forMediaItem(Context, MediaItem)} */
@Deprecated @Deprecated
public static DownloadHelper forProgressive(Uri uri, @Nullable String cacheKey) {
return new DownloadHelper(
DownloadRequest.TYPE_PROGRESSIVE,
uri,
cacheKey,
/* mediaSource= */ null,
DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT,
/* rendererCapabilities= */ new RendererCapabilities[0]);
}
/**
* Creates a {@link DownloadHelper} for progressive streams.
*
* @param context Any {@link Context}.
* @param uri A stream {@link Uri}.
* @param cacheKey An optional cache key.
* @return A {@link DownloadHelper} for progressive streams.
*/
public static DownloadHelper forProgressive(Context context, Uri uri, @Nullable String cacheKey) { public static DownloadHelper forProgressive(Context context, Uri uri, @Nullable String cacheKey) {
return new DownloadHelper( return forMediaItem(
DownloadRequest.TYPE_PROGRESSIVE, context, new MediaItem.Builder().setUri(uri).setCustomCacheKey(cacheKey).build());
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory)} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
public static DownloadHelper forDash(
Context context,
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory) {
return forDash(
uri, uri,
cacheKey, dataSourceFactory,
/* mediaSource= */ null, renderersFactory,
/* drmSessionManager= */ null,
getDefaultTrackSelectorParameters(context));
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory, DrmSessionManager)} instead.
*/
@Deprecated
public static DownloadHelper forDash(
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory,
@Nullable DrmSessionManager drmSessionManager,
DefaultTrackSelector.Parameters trackSelectorParameters) {
return forMediaItem(
new MediaItem.Builder().setUri(uri).setMimeType(MimeTypes.APPLICATION_MPD).build(),
trackSelectorParameters,
renderersFactory,
dataSourceFactory,
drmSessionManager);
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory)} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
public static DownloadHelper forHls(
Context context,
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory) {
return forHls(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
getDefaultTrackSelectorParameters(context));
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory, DrmSessionManager)} instead.
*/
@Deprecated
public static DownloadHelper forHls(
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory,
@Nullable DrmSessionManager drmSessionManager,
DefaultTrackSelector.Parameters trackSelectorParameters) {
return forMediaItem(
new MediaItem.Builder().setUri(uri).setMimeType(MimeTypes.APPLICATION_M3U8).build(),
trackSelectorParameters,
renderersFactory,
dataSourceFactory,
drmSessionManager);
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory)} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
public static DownloadHelper forSmoothStreaming(
Uri uri, DataSource.Factory dataSourceFactory, RenderersFactory renderersFactory) {
return forSmoothStreaming(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT);
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory)} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
public static DownloadHelper forSmoothStreaming(
Context context,
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory) {
return forSmoothStreaming(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
getDefaultTrackSelectorParameters(context));
}
/**
* @deprecated Use {@link #forMediaItem(MediaItem, Parameters, RenderersFactory,
* DataSource.Factory, DrmSessionManager)} instead.
*/
@Deprecated
public static DownloadHelper forSmoothStreaming(
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory,
@Nullable DrmSessionManager drmSessionManager,
DefaultTrackSelector.Parameters trackSelectorParameters) {
return forMediaItem(
new MediaItem.Builder().setUri(uri).setMimeType(MimeTypes.APPLICATION_SS).build(),
trackSelectorParameters,
renderersFactory,
dataSourceFactory,
drmSessionManager);
}
/**
* Creates a {@link DownloadHelper} for the given progressive media item.
*
* @param context The context.
* @param mediaItem A {@link MediaItem}.
* @return A {@link DownloadHelper} for progressive streams.
* @throws IllegalStateException If the media item is of type DASH, HLS or SmoothStreaming.
*/
public static DownloadHelper forMediaItem(Context context, MediaItem mediaItem) {
Assertions.checkArgument(
DownloadRequest.TYPE_PROGRESSIVE.equals(
getDownloadType(checkNotNull(mediaItem.playbackProperties))));
return forMediaItem(
mediaItem,
getDefaultTrackSelectorParameters(context), getDefaultTrackSelectorParameters(context),
/* rendererCapabilities= */ new RendererCapabilities[0]); /* renderersFactory= */ null,
} /* dataSourceFactory= */ null,
/* drmSessionManager= */ null);
/** @deprecated Use {@link #forDash(Context, Uri, Factory, RenderersFactory)} */
@Deprecated
public static DownloadHelper forDash(
Uri uri, DataSource.Factory dataSourceFactory, RenderersFactory renderersFactory) {
return forDash(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT);
} }
/** /**
* Creates a {@link DownloadHelper} for DASH streams. * Creates a {@link DownloadHelper} for the given media item.
* *
* @param context Any {@link Context}. * @param context The context.
* @param uri A manifest {@link Uri}. * @param mediaItem A {@link MediaItem}.
* @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest.
* @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are * @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are
* selected. * selected.
* @return A {@link DownloadHelper} for DASH streams. * @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest for adaptive
* @throws IllegalStateException If the DASH module is missing. * streams. This argument is required for adaptive streams and ignored for progressive
* streams.
* @return A {@link DownloadHelper}.
* @throws IllegalStateException If the the corresponding module is missing for DASH, HLS or
* SmoothStreaming media items.
* @throws IllegalArgumentException If the {@code dataSourceFactory} is null for adaptive streams.
*/ */
public static DownloadHelper forDash( public static DownloadHelper forMediaItem(
Context context, Context context,
Uri uri, MediaItem mediaItem,
DataSource.Factory dataSourceFactory, @Nullable RenderersFactory renderersFactory,
RenderersFactory renderersFactory) { @Nullable DataSource.Factory dataSourceFactory) {
return forDash( return forMediaItem(
uri, mediaItem,
dataSourceFactory, getDefaultTrackSelectorParameters(context),
renderersFactory, renderersFactory,
/* drmSessionManager= */ null, dataSourceFactory,
getDefaultTrackSelectorParameters(context)); /* drmSessionManager= */ null);
} }
/** /**
* Creates a {@link DownloadHelper} for DASH streams. * Creates a {@link DownloadHelper} for the given media item.
* *
* @param uri A manifest {@link Uri}. * @param mediaItem A {@link MediaItem}.
* @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest.
* @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are * @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are
* selected. * selected.
* @param drmSessionManager An optional {@link DrmSessionManager}. Used to help determine which
* tracks can be selected.
* @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for * @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for
* downloading. * downloading.
* @return A {@link DownloadHelper} for DASH streams. * @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest for adaptive
* @throws IllegalStateException If the DASH module is missing. * streams. This argument is required for adaptive streams and ignored for progressive
* streams.
* @return A {@link DownloadHelper}.
* @throws IllegalStateException If the the corresponding module is missing for DASH, HLS or
* SmoothStreaming media items.
* @throws IllegalArgumentException If the {@code dataSourceFactory} is null for adaptive streams.
*/ */
public static DownloadHelper forDash( public static DownloadHelper forMediaItem(
Uri uri, MediaItem mediaItem,
DataSource.Factory dataSourceFactory, DefaultTrackSelector.Parameters trackSelectorParameters,
RenderersFactory renderersFactory, @Nullable RenderersFactory renderersFactory,
@Nullable DrmSessionManager drmSessionManager, @Nullable DataSource.Factory dataSourceFactory) {
DefaultTrackSelector.Parameters trackSelectorParameters) { return forMediaItem(
return new DownloadHelper( mediaItem,
DownloadRequest.TYPE_DASH,
uri,
/* cacheKey= */ null,
createMediaSourceInternal(
DASH_FACTORY_CONSTRUCTOR,
uri,
dataSourceFactory,
drmSessionManager,
/* streamKeys= */ null),
trackSelectorParameters, trackSelectorParameters,
getRendererCapabilities(renderersFactory));
}
/** @deprecated Use {@link #forHls(Context, Uri, Factory, RenderersFactory)} */
@Deprecated
public static DownloadHelper forHls(
Uri uri, DataSource.Factory dataSourceFactory, RenderersFactory renderersFactory) {
return forHls(
uri,
dataSourceFactory,
renderersFactory, renderersFactory,
/* drmSessionManager= */ null, dataSourceFactory,
DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT); /* drmSessionManager= */ null);
} }
/** /**
* Creates a {@link DownloadHelper} for HLS streams. * Creates a {@link DownloadHelper} for the given media item.
* *
* @param context Any {@link Context}. * @param mediaItem A {@link MediaItem}.
* @param uri A playlist {@link Uri}.
* @param dataSourceFactory A {@link DataSource.Factory} used to load the playlist.
* @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are * @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are
* selected. * selected.
* @return A {@link DownloadHelper} for HLS streams.
* @throws IllegalStateException If the HLS module is missing.
*/
public static DownloadHelper forHls(
Context context,
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory) {
return forHls(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
getDefaultTrackSelectorParameters(context));
}
/**
* Creates a {@link DownloadHelper} for HLS streams.
*
* @param uri A playlist {@link Uri}.
* @param dataSourceFactory A {@link DataSource.Factory} used to load the playlist.
* @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are
* selected.
* @param drmSessionManager An optional {@link DrmSessionManager}. Used to help determine which
* tracks can be selected.
* @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for * @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for
* downloading. * downloading.
* @return A {@link DownloadHelper} for HLS streams. * @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest for adaptive
* @throws IllegalStateException If the HLS module is missing. * streams. This argument is required for adaptive streams and ignored for progressive
*/ * streams.
public static DownloadHelper forHls(
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory,
@Nullable DrmSessionManager drmSessionManager,
DefaultTrackSelector.Parameters trackSelectorParameters) {
return new DownloadHelper(
DownloadRequest.TYPE_HLS,
uri,
/* cacheKey= */ null,
createMediaSourceInternal(
HLS_FACTORY_CONSTRUCTOR,
uri,
dataSourceFactory,
drmSessionManager,
/* streamKeys= */ null),
trackSelectorParameters,
getRendererCapabilities(renderersFactory));
}
/** @deprecated Use {@link #forSmoothStreaming(Context, Uri, Factory, RenderersFactory)} */
@Deprecated
public static DownloadHelper forSmoothStreaming(
Uri uri, DataSource.Factory dataSourceFactory, RenderersFactory renderersFactory) {
return forSmoothStreaming(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT);
}
/**
* Creates a {@link DownloadHelper} for SmoothStreaming streams.
*
* @param context Any {@link Context}.
* @param uri A manifest {@link Uri}.
* @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest.
* @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are
* selected.
* @return A {@link DownloadHelper} for SmoothStreaming streams.
* @throws IllegalStateException If the SmoothStreaming module is missing.
*/
public static DownloadHelper forSmoothStreaming(
Context context,
Uri uri,
DataSource.Factory dataSourceFactory,
RenderersFactory renderersFactory) {
return forSmoothStreaming(
uri,
dataSourceFactory,
renderersFactory,
/* drmSessionManager= */ null,
getDefaultTrackSelectorParameters(context));
}
/**
* Creates a {@link DownloadHelper} for SmoothStreaming streams.
*
* @param uri A manifest {@link Uri}.
* @param dataSourceFactory A {@link DataSource.Factory} used to load the manifest.
* @param renderersFactory A {@link RenderersFactory} creating the renderers for which tracks are
* selected.
* @param drmSessionManager An optional {@link DrmSessionManager}. Used to help determine which * @param drmSessionManager An optional {@link DrmSessionManager}. Used to help determine which
* tracks can be selected. * tracks can be selected.
* @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for * @return A {@link DownloadHelper}.
* downloading. * @throws IllegalStateException If the the corresponding module is missing for DASH, HLS or
* @return A {@link DownloadHelper} for SmoothStreaming streams. * SmoothStreaming media items.
* @throws IllegalStateException If the SmoothStreaming module is missing. * @throws IllegalArgumentException If the {@code dataSourceFactory} is null for adaptive streams.
*/ */
public static DownloadHelper forSmoothStreaming( public static DownloadHelper forMediaItem(
Uri uri, MediaItem mediaItem,
DataSource.Factory dataSourceFactory, DefaultTrackSelector.Parameters trackSelectorParameters,
RenderersFactory renderersFactory, @Nullable RenderersFactory renderersFactory,
@Nullable DrmSessionManager drmSessionManager, @Nullable DataSource.Factory dataSourceFactory,
DefaultTrackSelector.Parameters trackSelectorParameters) { @Nullable DrmSessionManager drmSessionManager) {
boolean isProgressive =
DownloadRequest.TYPE_PROGRESSIVE.equals(
getDownloadType(checkNotNull(mediaItem.playbackProperties)));
Assertions.checkArgument(isProgressive || dataSourceFactory != null);
return new DownloadHelper( return new DownloadHelper(
DownloadRequest.TYPE_SS, mediaItem,
uri, isProgressive
/* cacheKey= */ null, ? null
createMediaSourceInternal( : createMediaSourceInternal(
SS_FACTORY_CONSTRUCTOR, mediaItem, castNonNull(dataSourceFactory), drmSessionManager),
uri,
dataSourceFactory,
drmSessionManager,
/* streamKeys= */ null),
trackSelectorParameters, trackSelectorParameters,
getRendererCapabilities(renderersFactory)); renderersFactory != null
? getRendererCapabilities(renderersFactory)
: new RendererCapabilities[0]);
} }
/** /**
@ -459,35 +451,18 @@ public final class DownloadHelper {
DownloadRequest downloadRequest, DownloadRequest downloadRequest,
DataSource.Factory dataSourceFactory, DataSource.Factory dataSourceFactory,
@Nullable DrmSessionManager drmSessionManager) { @Nullable DrmSessionManager drmSessionManager) {
@Nullable Constructor<? extends MediaSourceFactory> constructor;
switch (downloadRequest.type) {
case DownloadRequest.TYPE_DASH:
constructor = DASH_FACTORY_CONSTRUCTOR;
break;
case DownloadRequest.TYPE_SS:
constructor = SS_FACTORY_CONSTRUCTOR;
break;
case DownloadRequest.TYPE_HLS:
constructor = HLS_FACTORY_CONSTRUCTOR;
break;
case DownloadRequest.TYPE_PROGRESSIVE:
return new ProgressiveMediaSource.Factory(dataSourceFactory)
.setCustomCacheKey(downloadRequest.customCacheKey)
.createMediaSource(downloadRequest.uri);
default:
throw new IllegalStateException("Unsupported type: " + downloadRequest.type);
}
return createMediaSourceInternal( return createMediaSourceInternal(
constructor, new MediaItem.Builder()
downloadRequest.uri, .setUri(downloadRequest.uri)
.setCustomCacheKey(downloadRequest.customCacheKey)
.setMimeType(getMimeType(downloadRequest.type))
.setStreamKeys(downloadRequest.streamKeys)
.build(),
dataSourceFactory, dataSourceFactory,
drmSessionManager, drmSessionManager);
downloadRequest.streamKeys);
} }
private final String downloadType; private final MediaItem.PlaybackProperties playbackProperties;
private final Uri uri;
@Nullable private final String cacheKey;
@Nullable private final MediaSource mediaSource; @Nullable private final MediaSource mediaSource;
private final DefaultTrackSelector trackSelector; private final DefaultTrackSelector trackSelector;
private final RendererCapabilities[] rendererCapabilities; private final RendererCapabilities[] rendererCapabilities;
@ -506,9 +481,7 @@ public final class DownloadHelper {
/** /**
* Creates download helper. * Creates download helper.
* *
* @param downloadType A download type. This value will be used as {@link DownloadRequest#type}. * @param mediaItem The media item.
* @param uri A {@link Uri}.
* @param cacheKey An optional cache key.
* @param mediaSource A {@link MediaSource} for which tracks are selected, or null if no track * @param mediaSource A {@link MediaSource} for which tracks are selected, or null if no track
* selection needs to be made. * selection needs to be made.
* @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for * @param trackSelectorParameters {@link DefaultTrackSelector.Parameters} for selecting tracks for
@ -517,15 +490,11 @@ public final class DownloadHelper {
* are selected. * are selected.
*/ */
public DownloadHelper( public DownloadHelper(
String downloadType, MediaItem mediaItem,
Uri uri,
@Nullable String cacheKey,
@Nullable MediaSource mediaSource, @Nullable MediaSource mediaSource,
DefaultTrackSelector.Parameters trackSelectorParameters, DefaultTrackSelector.Parameters trackSelectorParameters,
RendererCapabilities[] rendererCapabilities) { RendererCapabilities[] rendererCapabilities) {
this.downloadType = downloadType; this.playbackProperties = checkNotNull(mediaItem.playbackProperties);
this.uri = uri;
this.cacheKey = cacheKey;
this.mediaSource = mediaSource; this.mediaSource = mediaSource;
this.trackSelector = this.trackSelector =
new DefaultTrackSelector(trackSelectorParameters, new DownloadTrackSelection.Factory()); new DefaultTrackSelector(trackSelectorParameters, new DownloadTrackSelection.Factory());
@ -766,7 +735,7 @@ public final class DownloadHelper {
* @return The built {@link DownloadRequest}. * @return The built {@link DownloadRequest}.
*/ */
public DownloadRequest getDownloadRequest(@Nullable byte[] data) { public DownloadRequest getDownloadRequest(@Nullable byte[] data) {
return getDownloadRequest(uri.toString(), data); return getDownloadRequest(playbackProperties.uri.toString(), data);
} }
/** /**
@ -778,9 +747,15 @@ public final class DownloadHelper {
* @return The built {@link DownloadRequest}. * @return The built {@link DownloadRequest}.
*/ */
public DownloadRequest getDownloadRequest(String id, @Nullable byte[] data) { public DownloadRequest getDownloadRequest(String id, @Nullable byte[] data) {
String downloadType = getDownloadType(playbackProperties);
if (mediaSource == null) { if (mediaSource == null) {
return new DownloadRequest( return new DownloadRequest(
id, downloadType, uri, /* streamKeys= */ Collections.emptyList(), cacheKey, data); id,
downloadType,
playbackProperties.uri,
/* streamKeys= */ Collections.emptyList(),
playbackProperties.customCacheKey,
data);
} }
assertPreparedWithMedia(); assertPreparedWithMedia();
List<StreamKey> streamKeys = new ArrayList<>(); List<StreamKey> streamKeys = new ArrayList<>();
@ -794,15 +769,21 @@ public final class DownloadHelper {
} }
streamKeys.addAll(mediaPreparer.mediaPeriods[periodIndex].getStreamKeys(allSelections)); streamKeys.addAll(mediaPreparer.mediaPeriods[periodIndex].getStreamKeys(allSelections));
} }
return new DownloadRequest(id, downloadType, uri, streamKeys, cacheKey, data); return new DownloadRequest(
id,
downloadType,
playbackProperties.uri,
streamKeys,
playbackProperties.customCacheKey,
data);
} }
// Initialization of array of Lists. // Initialization of array of Lists.
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private void onMediaPrepared() { private void onMediaPrepared() {
Assertions.checkNotNull(mediaPreparer); checkNotNull(mediaPreparer);
Assertions.checkNotNull(mediaPreparer.mediaPeriods); checkNotNull(mediaPreparer.mediaPeriods);
Assertions.checkNotNull(mediaPreparer.timeline); checkNotNull(mediaPreparer.timeline);
int periodCount = mediaPreparer.mediaPeriods.length; int periodCount = mediaPreparer.mediaPeriods.length;
int rendererCount = rendererCapabilities.length; int rendererCount = rendererCapabilities.length;
trackSelectionsByPeriodAndRenderer = trackSelectionsByPeriodAndRenderer =
@ -822,16 +803,14 @@ public final class DownloadHelper {
trackGroupArrays[i] = mediaPreparer.mediaPeriods[i].getTrackGroups(); trackGroupArrays[i] = mediaPreparer.mediaPeriods[i].getTrackGroups();
TrackSelectorResult trackSelectorResult = runTrackSelection(/* periodIndex= */ i); TrackSelectorResult trackSelectorResult = runTrackSelection(/* periodIndex= */ i);
trackSelector.onSelectionActivated(trackSelectorResult.info); trackSelector.onSelectionActivated(trackSelectorResult.info);
mappedTrackInfos[i] = Assertions.checkNotNull(trackSelector.getCurrentMappedTrackInfo()); mappedTrackInfos[i] = checkNotNull(trackSelector.getCurrentMappedTrackInfo());
} }
setPreparedWithMedia(); setPreparedWithMedia();
Assertions.checkNotNull(callbackHandler) checkNotNull(callbackHandler).post(() -> checkNotNull(callback).onPrepared(this));
.post(() -> Assertions.checkNotNull(callback).onPrepared(this));
} }
private void onMediaPreparationFailed(IOException error) { private void onMediaPreparationFailed(IOException error) {
Assertions.checkNotNull(callbackHandler) checkNotNull(callbackHandler).post(() -> checkNotNull(callback).onPrepareError(this, error));
.post(() -> Assertions.checkNotNull(callback).onPrepareError(this, error));
} }
@RequiresNonNull({ @RequiresNonNull({
@ -921,43 +900,43 @@ public final class DownloadHelper {
} }
} }
@Nullable private static MediaSource createMediaSourceInternal(
private static Constructor<? extends MediaSourceFactory> getConstructor(String className) { MediaItem mediaItem,
try { DataSource.Factory dataSourceFactory,
// LINT.IfChange @Nullable DrmSessionManager drmSessionManager) {
Class<? extends MediaSourceFactory> factoryClazz = return new DefaultMediaSourceFactory(dataSourceFactory, /* adSupportProvider= */ null)
Class.forName(className).asSubclass(MediaSourceFactory.class); .setDrmSessionManager(drmSessionManager)
return factoryClazz.getConstructor(Factory.class); .createMediaSource(mediaItem);
// LINT.ThenChange(../../../../../../../../proguard-rules.txt) }
} catch (ClassNotFoundException e) {
// Expected if the app was built without the respective module. private static String getDownloadType(MediaItem.PlaybackProperties playbackProperties) {
return null; int contentType =
} catch (NoSuchMethodException e) { Util.inferContentTypeWithMimeType(playbackProperties.uri, playbackProperties.mimeType);
// Something is wrong with the library or the proguard configuration. switch (contentType) {
throw new IllegalStateException(e); case C.TYPE_DASH:
return DownloadRequest.TYPE_DASH;
case C.TYPE_HLS:
return DownloadRequest.TYPE_HLS;
case C.TYPE_SS:
return DownloadRequest.TYPE_SS;
default:
return DownloadRequest.TYPE_PROGRESSIVE;
} }
} }
private static MediaSource createMediaSourceInternal( @Nullable
@Nullable Constructor<? extends MediaSourceFactory> constructor, private static String getMimeType(String downloadType) {
Uri uri, switch (downloadType) {
Factory dataSourceFactory, case DownloadRequest.TYPE_DASH:
@Nullable DrmSessionManager drmSessionManager, return MimeTypes.APPLICATION_MPD;
@Nullable List<StreamKey> streamKeys) { case DownloadRequest.TYPE_HLS:
if (constructor == null) { return MimeTypes.APPLICATION_M3U8;
throw new IllegalStateException("Module missing to create media source."); case DownloadRequest.TYPE_SS:
} return MimeTypes.APPLICATION_SS;
try { case DownloadRequest.TYPE_PROGRESSIVE:
MediaSourceFactory factory = constructor.newInstance(dataSourceFactory); return null;
if (drmSessionManager != null) { default:
factory.setDrmSessionManager(drmSessionManager); throw new IllegalArgumentException();
}
if (streamKeys != null) {
factory.setStreamKeys(streamKeys);
}
return Assertions.checkNotNull(factory.createMediaSource(uri));
} catch (Exception e) {
throw new IllegalStateException("Failed to instantiate media source.", e);
} }
} }
@ -1115,7 +1094,7 @@ public final class DownloadHelper {
return true; return true;
case DOWNLOAD_HELPER_CALLBACK_MESSAGE_FAILED: case DOWNLOAD_HELPER_CALLBACK_MESSAGE_FAILED:
release(); release();
downloadHelper.onMediaPreparationFailed((IOException) Util.castNonNull(msg.obj)); downloadHelper.onMediaPreparationFailed((IOException) castNonNull(msg.obj));
return true; return true;
default: default:
return false; return false;

View File

@ -18,11 +18,11 @@ package com.google.android.exoplayer2.offline;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.robolectric.shadows.ShadowBaseLooper.shadowMainLooper; import static org.robolectric.shadows.ShadowBaseLooper.shadowMainLooper;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RenderersFactory; import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.Timeline; import com.google.android.exoplayer2.Timeline;
@ -59,8 +59,6 @@ import org.robolectric.annotation.LooperMode;
@LooperMode(LooperMode.Mode.PAUSED) @LooperMode(LooperMode.Mode.PAUSED)
public class DownloadHelperTest { public class DownloadHelperTest {
private static final String TEST_DOWNLOAD_TYPE = "downloadType";
private static final String TEST_CACHE_KEY = "cacheKey";
private static final Object TEST_MANIFEST = new Object(); private static final Object TEST_MANIFEST = new Object();
private static final Timeline TEST_TIMELINE = private static final Timeline TEST_TIMELINE =
new FakeTimeline( new FakeTimeline(
@ -86,7 +84,7 @@ public class DownloadHelperTest {
private static TrackGroupArray trackGroupArraySingle; private static TrackGroupArray trackGroupArraySingle;
private static TrackGroupArray[] trackGroupArrays; private static TrackGroupArray[] trackGroupArrays;
private static Uri testUri; private static MediaItem testMediaItem;
private DownloadHelper downloadHelper; private DownloadHelper downloadHelper;
@ -114,7 +112,8 @@ public class DownloadHelperTest {
trackGroupArrays = trackGroupArrays =
new TrackGroupArray[] {trackGroupArrayAll, trackGroupArraySingle}; new TrackGroupArray[] {trackGroupArrayAll, trackGroupArraySingle};
testUri = Uri.parse("http://test.uri"); testMediaItem =
new MediaItem.Builder().setUri("http://test.uri").setCustomCacheKey("cacheKey").build();
} }
@Before @Before
@ -128,9 +127,7 @@ public class DownloadHelperTest {
downloadHelper = downloadHelper =
new DownloadHelper( new DownloadHelper(
TEST_DOWNLOAD_TYPE, testMediaItem,
testUri,
TEST_CACHE_KEY,
new TestMediaSource(), new TestMediaSource(),
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT, DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT,
DownloadHelper.getRendererCapabilities(renderersFactory)); DownloadHelper.getRendererCapabilities(renderersFactory));
@ -414,9 +411,10 @@ public class DownloadHelperTest {
DownloadRequest downloadRequest = downloadHelper.getDownloadRequest(data); DownloadRequest downloadRequest = downloadHelper.getDownloadRequest(data);
assertThat(downloadRequest.type).isEqualTo(TEST_DOWNLOAD_TYPE); assertThat(downloadRequest.type).isEqualTo(DownloadRequest.TYPE_PROGRESSIVE);
assertThat(downloadRequest.uri).isEqualTo(testUri); assertThat(downloadRequest.uri).isEqualTo(testMediaItem.playbackProperties.uri);
assertThat(downloadRequest.customCacheKey).isEqualTo(TEST_CACHE_KEY); assertThat(downloadRequest.customCacheKey)
.isEqualTo(testMediaItem.playbackProperties.customCacheKey);
assertThat(downloadRequest.data).isEqualTo(data); assertThat(downloadRequest.data).isEqualTo(data);
assertThat(downloadRequest.streamKeys) assertThat(downloadRequest.streamKeys)
.containsExactly( .containsExactly(

View File

@ -15,13 +15,14 @@
*/ */
package com.google.android.exoplayer2.source.dash.offline; package com.google.android.exoplayer2.source.dash.offline;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.drm.DrmSessionManager; import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.offline.DownloadHelper; import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -31,16 +32,16 @@ public final class DownloadHelperTest {
@Test @Test
public void staticDownloadHelperForDash_doesNotThrow() { public void staticDownloadHelperForDash_doesNotThrow() {
DownloadHelper.forDash( DownloadHelper.forMediaItem(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
Uri.parse("http://uri"), new MediaItem.Builder().setUri("http://uri").setMimeType(MimeTypes.APPLICATION_MPD).build(),
new FakeDataSource.Factory(),
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0]);
DownloadHelper.forDash(
Uri.parse("http://uri"),
new FakeDataSource.Factory(),
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0], (handler, videoListener, audioListener, text, metadata) -> new Renderer[0],
/* drmSessionManager= */ DrmSessionManager.getDummyDrmSessionManager(), new FakeDataSource.Factory());
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT); DownloadHelper.forMediaItem(
new MediaItem.Builder().setUri("http://uri").setMimeType(MimeTypes.APPLICATION_MPD).build(),
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT,
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0],
new FakeDataSource.Factory(),
/* drmSessionManager= */ DrmSessionManager.getDummyDrmSessionManager());
} }
} }

View File

@ -15,12 +15,13 @@
*/ */
package com.google.android.exoplayer2.source.hls.offline; package com.google.android.exoplayer2.source.hls.offline;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.offline.DownloadHelper; import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -30,16 +31,22 @@ public final class DownloadHelperTest {
@Test @Test
public void staticDownloadHelperForHls_doesNotThrow() { public void staticDownloadHelperForHls_doesNotThrow() {
DownloadHelper.forHls( DownloadHelper.forMediaItem(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
Uri.parse("http://uri"), new MediaItem.Builder()
new FakeDataSource.Factory(), .setUri("http://uri")
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0]); .setMimeType(MimeTypes.APPLICATION_M3U8)
DownloadHelper.forHls( .build(),
Uri.parse("http://uri"),
new FakeDataSource.Factory(),
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0], (handler, videoListener, audioListener, text, metadata) -> new Renderer[0],
/* drmSessionManager= */ null, new FakeDataSource.Factory());
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT); DownloadHelper.forMediaItem(
new MediaItem.Builder()
.setUri("http://uri")
.setMimeType(MimeTypes.APPLICATION_M3U8)
.build(),
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT,
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0],
new FakeDataSource.Factory(),
/* drmSessionManager= */ null);
} }
} }

View File

@ -15,12 +15,13 @@
*/ */
package com.google.android.exoplayer2.source.smoothstreaming.offline; package com.google.android.exoplayer2.source.smoothstreaming.offline;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Renderer; import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.offline.DownloadHelper; import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.testutil.FakeDataSource; import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.util.MimeTypes;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -30,16 +31,16 @@ public final class DownloadHelperTest {
@Test @Test
public void staticDownloadHelperForSmoothStreaming_doesNotThrow() { public void staticDownloadHelperForSmoothStreaming_doesNotThrow() {
DownloadHelper.forSmoothStreaming( DownloadHelper.forMediaItem(
ApplicationProvider.getApplicationContext(), ApplicationProvider.getApplicationContext(),
Uri.parse("http://uri"), new MediaItem.Builder().setUri("http://uri").setMimeType(MimeTypes.APPLICATION_SS).build(),
new FakeDataSource.Factory(),
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0]);
DownloadHelper.forSmoothStreaming(
Uri.parse("http://uri"),
new FakeDataSource.Factory(),
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0], (handler, videoListener, audioListener, text, metadata) -> new Renderer[0],
/* drmSessionManager= */ null, new FakeDataSource.Factory());
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT); DownloadHelper.forMediaItem(
new MediaItem.Builder().setUri("http://uri").setMimeType(MimeTypes.APPLICATION_SS).build(),
DownloadHelper.DEFAULT_TRACK_SELECTOR_PARAMETERS_WITHOUT_VIEWPORT,
(handler, videoListener, audioListener, text, metadata) -> new Renderer[0],
new FakeDataSource.Factory(),
/* drmSessionManager= */ null);
} }
} }