mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Plumb an ExecutorService into Downloader implementations
Issue: #5978 PiperOrigin-RevId: 307819608
This commit is contained in:
parent
37f0ff925a
commit
cd828e5c10
@ -51,15 +51,15 @@
|
|||||||
# Constructors accessed via reflection in DefaultDownloaderFactory
|
# Constructors accessed via reflection in DefaultDownloaderFactory
|
||||||
-dontnote com.google.android.exoplayer2.source.dash.offline.DashDownloader
|
-dontnote com.google.android.exoplayer2.source.dash.offline.DashDownloader
|
||||||
-keepclassmembers class com.google.android.exoplayer2.source.dash.offline.DashDownloader {
|
-keepclassmembers class com.google.android.exoplayer2.source.dash.offline.DashDownloader {
|
||||||
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory);
|
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory, java.util.concurrent.ExecutorService);
|
||||||
}
|
}
|
||||||
-dontnote com.google.android.exoplayer2.source.hls.offline.HlsDownloader
|
-dontnote com.google.android.exoplayer2.source.hls.offline.HlsDownloader
|
||||||
-keepclassmembers class com.google.android.exoplayer2.source.hls.offline.HlsDownloader {
|
-keepclassmembers class com.google.android.exoplayer2.source.hls.offline.HlsDownloader {
|
||||||
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory);
|
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory, java.util.concurrent.ExecutorService);
|
||||||
}
|
}
|
||||||
-dontnote com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader
|
-dontnote com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader
|
||||||
-keepclassmembers class com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader {
|
-keepclassmembers class com.google.android.exoplayer2.source.smoothstreaming.offline.SsDownloader {
|
||||||
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory);
|
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory, java.util.concurrent.ExecutorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
# Constructors accessed via reflection in DefaultMediaSourceFactory and DownloadHelper
|
# Constructors accessed via reflection in DefaultMediaSourceFactory and DownloadHelper
|
||||||
|
@ -20,6 +20,7 @@ import androidx.annotation.Nullable;
|
|||||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default {@link DownloaderFactory}, supporting creation of progressive, DASH, HLS and
|
* Default {@link DownloaderFactory}, supporting creation of progressive, DASH, HLS and
|
||||||
@ -70,6 +71,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final CacheDataSource.Factory cacheDataSourceFactory;
|
private final CacheDataSource.Factory cacheDataSourceFactory;
|
||||||
|
@Nullable private final ExecutorService executorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates an instance.
|
||||||
@ -78,7 +80,24 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||||||
* downloads will be written.
|
* downloads will be written.
|
||||||
*/
|
*/
|
||||||
public DefaultDownloaderFactory(CacheDataSource.Factory cacheDataSourceFactory) {
|
public DefaultDownloaderFactory(CacheDataSource.Factory cacheDataSourceFactory) {
|
||||||
|
this(cacheDataSourceFactory, /* executorService= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance.
|
||||||
|
*
|
||||||
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which
|
||||||
|
* downloads will be written.
|
||||||
|
* @param executorService An {@link ExecutorService} used to make requests for media being
|
||||||
|
* downloaded. Must not be a direct executor, but may be {@code null} if each download should
|
||||||
|
* make its requests directly on its own thread. Providing an {@link ExecutorService} that
|
||||||
|
* uses multiple threads will speed up download tasks that can be split into smaller parts for
|
||||||
|
* parallel execution.
|
||||||
|
*/
|
||||||
|
public DefaultDownloaderFactory(
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory, @Nullable ExecutorService executorService) {
|
||||||
this.cacheDataSourceFactory = cacheDataSourceFactory;
|
this.cacheDataSourceFactory = cacheDataSourceFactory;
|
||||||
|
this.executorService = executorService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -86,7 +105,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||||||
switch (request.type) {
|
switch (request.type) {
|
||||||
case DownloadRequest.TYPE_PROGRESSIVE:
|
case DownloadRequest.TYPE_PROGRESSIVE:
|
||||||
return new ProgressiveDownloader(
|
return new ProgressiveDownloader(
|
||||||
request.uri, request.customCacheKey, cacheDataSourceFactory);
|
request.uri, request.customCacheKey, cacheDataSourceFactory, executorService);
|
||||||
case DownloadRequest.TYPE_DASH:
|
case DownloadRequest.TYPE_DASH:
|
||||||
return createDownloader(request, DASH_DOWNLOADER_CONSTRUCTOR);
|
return createDownloader(request, DASH_DOWNLOADER_CONSTRUCTOR);
|
||||||
case DownloadRequest.TYPE_HLS:
|
case DownloadRequest.TYPE_HLS:
|
||||||
@ -98,13 +117,18 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Checker framework has no way of knowing whether arguments to newInstance can be null or not,
|
||||||
|
// and so opts to be conservative and assumes they cannot. In this case executorService can be
|
||||||
|
// nullable, so we suppress the warning.
|
||||||
|
@SuppressWarnings("nullness:argument.type.incompatible")
|
||||||
private Downloader createDownloader(
|
private Downloader createDownloader(
|
||||||
DownloadRequest request, @Nullable Constructor<? extends Downloader> constructor) {
|
DownloadRequest request, @Nullable Constructor<? extends Downloader> constructor) {
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
throw new IllegalStateException("Module missing for: " + request.type);
|
throw new IllegalStateException("Module missing for: " + request.type);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return constructor.newInstance(request.uri, request.streamKeys, cacheDataSourceFactory);
|
return constructor.newInstance(
|
||||||
|
request.uri, request.streamKeys, cacheDataSourceFactory, executorService);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("Failed to instantiate downloader for: " + request.type, e);
|
throw new RuntimeException("Failed to instantiate downloader for: " + request.type, e);
|
||||||
}
|
}
|
||||||
@ -115,7 +139,8 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||||||
try {
|
try {
|
||||||
return clazz
|
return clazz
|
||||||
.asSubclass(Downloader.class)
|
.asSubclass(Downloader.class)
|
||||||
.getConstructor(Uri.class, List.class, CacheDataSource.Factory.class);
|
.getConstructor(
|
||||||
|
Uri.class, List.class, CacheDataSource.Factory.class, ExecutorService.class);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
// The downloader is present, but the expected constructor is missing.
|
// The downloader is present, but the expected constructor is missing.
|
||||||
throw new RuntimeException("Downloader constructor missing", e);
|
throw new RuntimeException("Downloader constructor missing", e);
|
||||||
|
@ -23,6 +23,7 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
|||||||
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
|
import com.google.android.exoplayer2.upstream.cache.CacheUtil;
|
||||||
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/** A downloader for progressive media streams. */
|
/** A downloader for progressive media streams. */
|
||||||
@ -43,6 +44,26 @@ public final class ProgressiveDownloader implements Downloader {
|
|||||||
*/
|
*/
|
||||||
public ProgressiveDownloader(
|
public ProgressiveDownloader(
|
||||||
Uri uri, @Nullable String customCacheKey, CacheDataSource.Factory cacheDataSourceFactory) {
|
Uri uri, @Nullable String customCacheKey, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||||
|
this(uri, customCacheKey, cacheDataSourceFactory, /* executorService= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param uri Uri of the data to be downloaded.
|
||||||
|
* @param customCacheKey A custom key that uniquely identifies the original stream. Used for cache
|
||||||
|
* indexing. May be null.
|
||||||
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||||
|
* download will be written.
|
||||||
|
* @param executorService An {@link ExecutorService} used to make requests for the media being
|
||||||
|
* downloaded. Must not be a direct executor, but may be {@code null} if the requests should
|
||||||
|
* be made directly from the thread that calls {@link #download(ProgressListener)}. In the
|
||||||
|
* future, providing an {@link ExecutorService} that uses multiple threads may speed up the
|
||||||
|
* download by allowing parts of it to be executed in parallel.
|
||||||
|
*/
|
||||||
|
public ProgressiveDownloader(
|
||||||
|
Uri uri,
|
||||||
|
@Nullable String customCacheKey,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
@Nullable ExecutorService executorService) {
|
||||||
dataSpec =
|
dataSpec =
|
||||||
new DataSpec.Builder()
|
new DataSpec.Builder()
|
||||||
.setUri(uri)
|
.setUri(uri)
|
||||||
|
@ -32,6 +32,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,9 +78,17 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||||||
* If empty, all streams are downloaded.
|
* If empty, all streams are downloaded.
|
||||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||||
* download will be written.
|
* download will be written.
|
||||||
|
* @param executorService An {@link ExecutorService} used to make requests for the media being
|
||||||
|
* downloaded. Must not be a direct executor, but may be {@code null} if the requests should
|
||||||
|
* be made directly from the thread that calls {@link #download(ProgressListener)}. Providing
|
||||||
|
* an {@link ExecutorService} that uses multiple threads will speed up the download by
|
||||||
|
* allowing parts of it to be executed in parallel.
|
||||||
*/
|
*/
|
||||||
public SegmentDownloader(
|
public SegmentDownloader(
|
||||||
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
Uri manifestUri,
|
||||||
|
List<StreamKey> streamKeys,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
@Nullable ExecutorService executorService) {
|
||||||
this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
|
this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
|
||||||
this.streamKeys = new ArrayList<>(streamKeys);
|
this.streamKeys = new ArrayList<>(streamKeys);
|
||||||
this.dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
|
this.dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
|
||||||
|
@ -38,6 +38,7 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A downloader for DASH streams.
|
* A downloader for DASH streams.
|
||||||
@ -73,7 +74,27 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
|
|||||||
*/
|
*/
|
||||||
public DashDownloader(
|
public DashDownloader(
|
||||||
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||||
super(manifestUri, streamKeys, cacheDataSourceFactory);
|
this(manifestUri, streamKeys, cacheDataSourceFactory, /* executorService= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
|
||||||
|
* @param streamKeys Keys defining which representations in the manifest should be selected for
|
||||||
|
* download. If empty, all representations are downloaded.
|
||||||
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||||
|
* download will be written.
|
||||||
|
* @param executorService An {@link ExecutorService} used to make requests for the media being
|
||||||
|
* downloaded. Must not be a direct executor, but may be {@code null} if the requests should
|
||||||
|
* be made directly from the thread that calls {@link #download(ProgressListener)}. Providing
|
||||||
|
* an {@link ExecutorService} that uses multiple threads will speed up the download by
|
||||||
|
* allowing parts of it to be executed in parallel.
|
||||||
|
*/
|
||||||
|
public DashDownloader(
|
||||||
|
Uri manifestUri,
|
||||||
|
List<StreamKey> streamKeys,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
@Nullable ExecutorService executorService) {
|
||||||
|
super(manifestUri, streamKeys, cacheDataSourceFactory, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer2.source.hls.offline;
|
package com.google.android.exoplayer2.source.hls.offline;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
@ -32,6 +33,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A downloader for HLS streams.
|
* A downloader for HLS streams.
|
||||||
@ -67,7 +69,27 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
|||||||
*/
|
*/
|
||||||
public HlsDownloader(
|
public HlsDownloader(
|
||||||
Uri playlistUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
Uri playlistUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||||
super(playlistUri, streamKeys, cacheDataSourceFactory);
|
this(playlistUri, streamKeys, cacheDataSourceFactory, /* executorService= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param playlistUri The {@link Uri} of the playlist to be downloaded.
|
||||||
|
* @param streamKeys Keys defining which renditions in the playlist should be selected for
|
||||||
|
* download. If empty, all renditions are downloaded.
|
||||||
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||||
|
* download will be written.
|
||||||
|
* @param executorService An {@link ExecutorService} used to make requests for the media being
|
||||||
|
* downloaded. Must not be a direct executor, but may be {@code null} if the requests should
|
||||||
|
* be made directly from the thread that calls {@link #download(ProgressListener)}. Providing
|
||||||
|
* an {@link ExecutorService} that uses multiple threads will speed up the download by
|
||||||
|
* allowing parts of it to be executed in parallel.
|
||||||
|
*/
|
||||||
|
public HlsDownloader(
|
||||||
|
Uri playlistUri,
|
||||||
|
List<StreamKey> streamKeys,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
@Nullable ExecutorService executorService) {
|
||||||
|
super(playlistUri, streamKeys, cacheDataSourceFactory, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer2.source.smoothstreaming.offline;
|
package com.google.android.exoplayer2.source.smoothstreaming.offline;
|
||||||
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
@ -30,6 +31,7 @@ import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A downloader for SmoothStreaming streams.
|
* A downloader for SmoothStreaming streams.
|
||||||
@ -66,7 +68,27 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
|
|||||||
*/
|
*/
|
||||||
public SsDownloader(
|
public SsDownloader(
|
||||||
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||||
super(SsUtil.fixManifestUri(manifestUri), streamKeys, cacheDataSourceFactory);
|
this(manifestUri, streamKeys, cacheDataSourceFactory, /* executorService= */ null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
|
||||||
|
* @param streamKeys Keys defining which streams in the manifest should be selected for download.
|
||||||
|
* If empty, all streams are downloaded.
|
||||||
|
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||||
|
* download will be written.
|
||||||
|
* @param executorService An {@link ExecutorService} used to make requests for the media being
|
||||||
|
* downloaded. Must not be a direct executor, but may be {@code null} if the requests should
|
||||||
|
* be made directly from the thread that calls {@link #download(ProgressListener)}. Providing
|
||||||
|
* an {@link ExecutorService} that uses multiple threads will speed up the download by
|
||||||
|
* allowing parts of it to be executed in parallel.
|
||||||
|
*/
|
||||||
|
public SsDownloader(
|
||||||
|
Uri manifestUri,
|
||||||
|
List<StreamKey> streamKeys,
|
||||||
|
CacheDataSource.Factory cacheDataSourceFactory,
|
||||||
|
@Nullable ExecutorService executorService) {
|
||||||
|
super(SsUtil.fixManifestUri(manifestUri), streamKeys, cacheDataSourceFactory, executorService);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
x
Reference in New Issue
Block a user