mirror of
https://github.com/samsonjs/media.git
synced 2026-03-29 10:05:48 +00:00
Remove DownloadConstructorHelper
Something that helps a constructor always seemed a bit strange. It's now possible to use CacheDataSource.Factory directly instead. PiperOrigin-RevId: 307661930
This commit is contained in:
parent
722a5b2279
commit
4abaaf138c
19 changed files with 198 additions and 266 deletions
|
|
@ -60,8 +60,6 @@
|
|||
`DecoderVideoRenderer` and `DecoderAudioRenderer` respectively, and
|
||||
generalized to work with `Decoder` rather than `SimpleDecoder`.
|
||||
* Add media item based playlist API to Player.
|
||||
* Update `CachedContentIndex` to use `SecureRandom` for generating the
|
||||
initialization vector used to encrypt the cache contents.
|
||||
* Remove deprecated members in `DefaultTrackSelector`.
|
||||
* Add `Player.DeviceComponent` and implement it for `SimpleExoPlayer` so
|
||||
that the device volume can be controlled by player.
|
||||
|
|
@ -108,8 +106,15 @@
|
|||
`OfflineLicenseHelper`
|
||||
([#7078](https://github.com/google/ExoPlayer/issues/7078)).
|
||||
* Remove generics from DRM components.
|
||||
* Downloads: Merge downloads in `SegmentDownloader` to improve overall
|
||||
download speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)).
|
||||
* Downloads and caching:
|
||||
* Merge downloads in `SegmentDownloader` to improve overall download
|
||||
speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)).
|
||||
* Replace `CacheDataSinkFactory` and `CacheDataSourceFactory` with
|
||||
`CacheDataSink.Factory` and `CacheDataSource.Factory` respectively.
|
||||
* Remove `DownloadConstructorHelper` and use `CacheDataSource.Factory`
|
||||
directly instead.
|
||||
* Update `CachedContentIndex` to use `SecureRandom` for generating the
|
||||
initialization vector used to encrypt the cache contents.
|
||||
* DASH:
|
||||
* Merge trick play adaptation sets (i.e., adaptation sets marked with
|
||||
`http://dashif.org/guidelines/trickmode`) into the same `TrackGroup` as
|
||||
|
|
|
|||
|
|
@ -22,18 +22,14 @@ import com.google.android.exoplayer2.database.DatabaseProvider;
|
|||
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
|
||||
import com.google.android.exoplayer2.offline.ActionFileUpgradeUtil;
|
||||
import com.google.android.exoplayer2.offline.DefaultDownloadIndex;
|
||||
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.ui.DownloadNotificationHelper;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||
import com.google.android.exoplayer2.upstream.HttpDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
|
|
@ -131,11 +127,9 @@ public class DemoApplication extends Application {
|
|||
DOWNLOAD_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ false);
|
||||
upgradeActionFile(
|
||||
DOWNLOAD_TRACKER_ACTION_FILE, downloadIndex, /* addNewDownloadsAsCompleted= */ true);
|
||||
DownloaderConstructorHelper downloaderConstructorHelper =
|
||||
new DownloaderConstructorHelper(getDownloadCache(), buildHttpDataSourceFactory());
|
||||
downloadManager =
|
||||
new DownloadManager(
|
||||
this, downloadIndex, new DefaultDownloaderFactory(downloaderConstructorHelper));
|
||||
this, getDatabaseProvider(), getDownloadCache(), buildHttpDataSourceFactory());
|
||||
downloadTracker =
|
||||
new DownloadTracker(/* context= */ this, buildDataSourceFactory(), downloadManager);
|
||||
}
|
||||
|
|
@ -172,14 +166,12 @@ public class DemoApplication extends Application {
|
|||
return downloadDirectory;
|
||||
}
|
||||
|
||||
protected static CacheDataSourceFactory buildReadOnlyCacheDataSource(
|
||||
protected static CacheDataSource.Factory buildReadOnlyCacheDataSource(
|
||||
DataSource.Factory upstreamFactory, Cache cache) {
|
||||
return new CacheDataSourceFactory(
|
||||
cache,
|
||||
upstreamFactory,
|
||||
new FileDataSource.Factory(),
|
||||
/* cacheWriteDataSinkFactory= */ null,
|
||||
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
|
||||
/* eventListener= */ null);
|
||||
return new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(upstreamFactory)
|
||||
.setCacheWriteDataSinkFactory(null)
|
||||
.setFlags(CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,15 +51,15 @@
|
|||
# Constructors accessed via reflection in DefaultDownloaderFactory
|
||||
-dontnote 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.offline.DownloaderConstructorHelper);
|
||||
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory);
|
||||
}
|
||||
-dontnote 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.offline.DownloaderConstructorHelper);
|
||||
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory);
|
||||
}
|
||||
-dontnote 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.offline.DownloaderConstructorHelper);
|
||||
<init>(android.net.Uri, java.util.List, com.google.android.exoplayer2.upstream.cache.CacheDataSource.Factory);
|
||||
}
|
||||
|
||||
# Constructors accessed via reflection in DefaultMediaSourceFactory and DownloadHelper
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ package com.google.android.exoplayer2.offline;
|
|||
|
||||
import android.net.Uri;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -32,7 +33,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
@Nullable private static final Constructor<? extends Downloader> SS_DOWNLOADER_CONSTRUCTOR;
|
||||
|
||||
static {
|
||||
Constructor<? extends Downloader> dashDownloaderConstructor = null;
|
||||
@Nullable Constructor<? extends Downloader> dashDownloaderConstructor = null;
|
||||
try {
|
||||
// LINT.IfChange
|
||||
dashDownloaderConstructor =
|
||||
|
|
@ -43,7 +44,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
// Expected if the app was built without the DASH module.
|
||||
}
|
||||
DASH_DOWNLOADER_CONSTRUCTOR = dashDownloaderConstructor;
|
||||
Constructor<? extends Downloader> hlsDownloaderConstructor = null;
|
||||
@Nullable Constructor<? extends Downloader> hlsDownloaderConstructor = null;
|
||||
try {
|
||||
// LINT.IfChange
|
||||
hlsDownloaderConstructor =
|
||||
|
|
@ -54,7 +55,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
// Expected if the app was built without the HLS module.
|
||||
}
|
||||
HLS_DOWNLOADER_CONSTRUCTOR = hlsDownloaderConstructor;
|
||||
Constructor<? extends Downloader> ssDownloaderConstructor = null;
|
||||
@Nullable Constructor<? extends Downloader> ssDownloaderConstructor = null;
|
||||
try {
|
||||
// LINT.IfChange
|
||||
ssDownloaderConstructor =
|
||||
|
|
@ -68,11 +69,16 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
SS_DOWNLOADER_CONSTRUCTOR = ssDownloaderConstructor;
|
||||
}
|
||||
|
||||
private final DownloaderConstructorHelper downloaderConstructorHelper;
|
||||
private final CacheDataSource.Factory cacheDataSourceFactory;
|
||||
|
||||
/** @param downloaderConstructorHelper A helper for instantiating downloaders. */
|
||||
public DefaultDownloaderFactory(DownloaderConstructorHelper downloaderConstructorHelper) {
|
||||
this.downloaderConstructorHelper = downloaderConstructorHelper;
|
||||
/**
|
||||
* Creates an instance.
|
||||
*
|
||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which
|
||||
* downloads will be written.
|
||||
*/
|
||||
public DefaultDownloaderFactory(CacheDataSource.Factory cacheDataSourceFactory) {
|
||||
this.cacheDataSourceFactory = cacheDataSourceFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,7 +86,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
switch (request.type) {
|
||||
case DownloadRequest.TYPE_PROGRESSIVE:
|
||||
return new ProgressiveDownloader(
|
||||
request.uri, request.customCacheKey, downloaderConstructorHelper);
|
||||
request.uri, request.customCacheKey, cacheDataSourceFactory);
|
||||
case DownloadRequest.TYPE_DASH:
|
||||
return createDownloader(request, DASH_DOWNLOADER_CONSTRUCTOR);
|
||||
case DownloadRequest.TYPE_HLS:
|
||||
|
|
@ -98,7 +104,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
throw new IllegalStateException("Module missing for: " + request.type);
|
||||
}
|
||||
try {
|
||||
return constructor.newInstance(request.uri, request.streamKeys, downloaderConstructorHelper);
|
||||
return constructor.newInstance(request.uri, request.streamKeys, cacheDataSourceFactory);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to instantiate downloader for: " + request.type, e);
|
||||
}
|
||||
|
|
@ -109,7 +115,7 @@ public class DefaultDownloaderFactory implements DownloaderFactory {
|
|||
try {
|
||||
return clazz
|
||||
.asSubclass(Downloader.class)
|
||||
.getConstructor(Uri.class, List.class, DownloaderConstructorHelper.class);
|
||||
.getConstructor(Uri.class, List.class, CacheDataSource.Factory.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// The downloader is present, but the expected constructor is missing.
|
||||
throw new RuntimeException("Downloader constructor missing", e);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import com.google.android.exoplayer2.scheduler.RequirementsWatcher;
|
|||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSource.Factory;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
|
|
@ -197,7 +198,10 @@ public final class DownloadManager {
|
|||
this(
|
||||
context,
|
||||
new DefaultDownloadIndex(databaseProvider),
|
||||
new DefaultDownloaderFactory(new DownloaderConstructorHelper(cache, upstreamFactory)));
|
||||
new DefaultDownloaderFactory(
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(upstreamFactory)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.offline;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.upstream.DataSink;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.FileDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSinkFactory;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheKeyFactory;
|
||||
import com.google.android.exoplayer2.util.PriorityTaskManager;
|
||||
|
||||
/** A helper class that holds necessary parameters for {@link Downloader} construction. */
|
||||
public final class DownloaderConstructorHelper {
|
||||
|
||||
private final CacheDataSource.Factory onlineCacheDataSourceFactory;
|
||||
private final CacheDataSource.Factory offlineCacheDataSourceFactory;
|
||||
|
||||
/**
|
||||
* @param cache Cache instance to be used to store downloaded data.
|
||||
* @param upstreamFactory A {@link DataSource.Factory} for creating {@link DataSource}s for
|
||||
* downloading data.
|
||||
*/
|
||||
public DownloaderConstructorHelper(Cache cache, DataSource.Factory upstreamFactory) {
|
||||
this(
|
||||
cache,
|
||||
upstreamFactory,
|
||||
/* cacheReadDataSourceFactory= */ null,
|
||||
/* cacheWriteDataSinkFactory= */ null,
|
||||
/* priorityTaskManager= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cache Cache instance to be used to store downloaded data.
|
||||
* @param upstreamFactory A {@link DataSource.Factory} for creating {@link DataSource}s for
|
||||
* downloading data.
|
||||
* @param cacheReadDataSourceFactory A {@link DataSource.Factory} for creating {@link DataSource}s
|
||||
* for reading data from the cache. If null then a {@link FileDataSource.Factory} will be
|
||||
* used.
|
||||
* @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for creating {@link DataSource}s
|
||||
* for writing data to the cache. If null then a {@link CacheDataSinkFactory} will be used.
|
||||
* @param priorityTaskManager A {@link PriorityTaskManager} to use when downloading. If non-null,
|
||||
* downloaders will register as tasks with priority {@link C#PRIORITY_DOWNLOAD} whilst
|
||||
* downloading.
|
||||
*/
|
||||
public DownloaderConstructorHelper(
|
||||
Cache cache,
|
||||
DataSource.Factory upstreamFactory,
|
||||
@Nullable DataSource.Factory cacheReadDataSourceFactory,
|
||||
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
|
||||
@Nullable PriorityTaskManager priorityTaskManager) {
|
||||
this(
|
||||
cache,
|
||||
upstreamFactory,
|
||||
cacheReadDataSourceFactory,
|
||||
cacheWriteDataSinkFactory,
|
||||
priorityTaskManager,
|
||||
/* cacheKeyFactory= */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cache Cache instance to be used to store downloaded data.
|
||||
* @param upstreamFactory A {@link DataSource.Factory} for creating {@link DataSource}s for
|
||||
* downloading data.
|
||||
* @param cacheReadDataSourceFactory A {@link DataSource.Factory} for creating {@link DataSource}s
|
||||
* for reading data from the cache. If null then a {@link FileDataSource.Factory} will be
|
||||
* used.
|
||||
* @param cacheWriteDataSinkFactory A {@link DataSink.Factory} for creating {@link DataSource}s
|
||||
* for writing data to the cache. If null then a {@link CacheDataSinkFactory} will be used.
|
||||
* @param priorityTaskManager A {@link PriorityTaskManager} to use when downloading. If non-null,
|
||||
* downloaders will register as tasks with priority {@link C#PRIORITY_DOWNLOAD} whilst
|
||||
* downloading.
|
||||
* @param cacheKeyFactory An optional factory for cache keys.
|
||||
*/
|
||||
public DownloaderConstructorHelper(
|
||||
Cache cache,
|
||||
DataSource.Factory upstreamFactory,
|
||||
@Nullable DataSource.Factory cacheReadDataSourceFactory,
|
||||
@Nullable DataSink.Factory cacheWriteDataSinkFactory,
|
||||
@Nullable PriorityTaskManager priorityTaskManager,
|
||||
@Nullable CacheKeyFactory cacheKeyFactory) {
|
||||
onlineCacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(upstreamFactory)
|
||||
.setUpstreamPriorityTaskManager(priorityTaskManager)
|
||||
.setUpstreamPriority(C.PRIORITY_DOWNLOAD)
|
||||
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||
offlineCacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setCacheWriteDataSinkFactory(null)
|
||||
.setFlags(CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||
if (cacheKeyFactory != null) {
|
||||
onlineCacheDataSourceFactory.setCacheKeyFactory(cacheKeyFactory);
|
||||
offlineCacheDataSourceFactory.setCacheKeyFactory(cacheKeyFactory);
|
||||
}
|
||||
if (cacheReadDataSourceFactory != null) {
|
||||
onlineCacheDataSourceFactory.setCacheReadDataSourceFactory(cacheReadDataSourceFactory);
|
||||
offlineCacheDataSourceFactory.setCacheReadDataSourceFactory(cacheReadDataSourceFactory);
|
||||
}
|
||||
if (cacheWriteDataSinkFactory != null) {
|
||||
onlineCacheDataSourceFactory.setCacheWriteDataSinkFactory(cacheWriteDataSinkFactory);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns a new {@link CacheDataSource} instance. */
|
||||
public CacheDataSource createCacheDataSource() {
|
||||
return onlineCacheDataSourceFactory.createDataSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@link CacheDataSource} instance which accesses cache read-only and throws an
|
||||
* exception on cache miss.
|
||||
*/
|
||||
public CacheDataSource createOfflineCacheDataSource() {
|
||||
return offlineCacheDataSourceFactory.createDataSource();
|
||||
}
|
||||
}
|
||||
|
|
@ -25,15 +25,7 @@ import com.google.android.exoplayer2.util.PriorityTaskManager;
|
|||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* A downloader for progressive media streams.
|
||||
*
|
||||
* <p>The downloader attempts to download the entire media bytes referenced by a {@link Uri} into a
|
||||
* cache as defined by {@link DownloaderConstructorHelper}. Callers can use the constructor to
|
||||
* specify a custom cache key for the downloaded bytes.
|
||||
*
|
||||
* <p>The downloader will avoid downloading already-downloaded media bytes.
|
||||
*/
|
||||
/** A downloader for progressive media streams. */
|
||||
public final class ProgressiveDownloader implements Downloader {
|
||||
|
||||
private static final int BUFFER_SIZE_BYTES = 128 * 1024;
|
||||
|
|
@ -46,17 +38,18 @@ public final class ProgressiveDownloader implements Downloader {
|
|||
* @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 constructorHelper A {@link DownloaderConstructorHelper} instance.
|
||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||
* download will be written.
|
||||
*/
|
||||
public ProgressiveDownloader(
|
||||
Uri uri, @Nullable String customCacheKey, DownloaderConstructorHelper constructorHelper) {
|
||||
this.dataSpec =
|
||||
Uri uri, @Nullable String customCacheKey, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||
dataSpec =
|
||||
new DataSpec.Builder()
|
||||
.setUri(uri)
|
||||
.setKey(customCacheKey)
|
||||
.setFlags(DataSpec.FLAG_ALLOW_CACHE_FRAGMENTATION)
|
||||
.build();
|
||||
this.dataSource = constructorHelper.createCacheDataSource();
|
||||
dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
|
||||
isCanceled = new AtomicBoolean();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||
|
||||
private final DataSpec manifestDataSpec;
|
||||
private final CacheDataSource dataSource;
|
||||
private final CacheDataSource offlineDataSource;
|
||||
private final CacheDataSource removingDataSource;
|
||||
private final ArrayList<StreamKey> streamKeys;
|
||||
private final AtomicBoolean isCanceled;
|
||||
|
||||
|
|
@ -75,14 +75,15 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||
* @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 constructorHelper A {@link DownloaderConstructorHelper} instance.
|
||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||
* download will be written.
|
||||
*/
|
||||
public SegmentDownloader(
|
||||
Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
|
||||
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||
this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
|
||||
this.streamKeys = new ArrayList<>(streamKeys);
|
||||
this.dataSource = constructorHelper.createCacheDataSource();
|
||||
this.offlineDataSource = constructorHelper.createOfflineCacheDataSource();
|
||||
this.dataSource = cacheDataSourceFactory.createDataSourceForDownloading();
|
||||
this.removingDataSource = cacheDataSourceFactory.createDataSourceForRemovingDownload();
|
||||
isCanceled = new AtomicBoolean();
|
||||
}
|
||||
|
||||
|
|
@ -176,8 +177,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
|
|||
@Override
|
||||
public final void remove() throws InterruptedException {
|
||||
try {
|
||||
M manifest = getManifest(offlineDataSource, manifestDataSpec);
|
||||
List<Segment> segments = getSegments(offlineDataSource, manifest, true);
|
||||
M manifest = getManifest(removingDataSource, manifestDataSpec);
|
||||
List<Segment> segments = getSegments(removingDataSource, manifest, true);
|
||||
for (int i = 0; i < segments.size(); i++) {
|
||||
removeDataSpec(segments.get(i).dataSpec);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,12 +207,54 @@ public final class CacheDataSource implements DataSource {
|
|||
|
||||
@Override
|
||||
public CacheDataSource createDataSource() {
|
||||
return createDataSourceInternal(
|
||||
upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null,
|
||||
flags,
|
||||
upstreamPriority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance suitable for downloading content. The created instance is equivalent to
|
||||
* one that would be created by {@link #createDataSource()}, except:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The {@link #FLAG_BLOCK_ON_CACHE} is always set.
|
||||
* <li>The task priority is overridden to be {@link C#PRIORITY_DOWNLOAD}.
|
||||
* </ul>
|
||||
*
|
||||
* @return An instance suitable for downloading content.
|
||||
*/
|
||||
public CacheDataSource createDataSourceForDownloading() {
|
||||
return createDataSourceInternal(
|
||||
upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null,
|
||||
flags | FLAG_BLOCK_ON_CACHE,
|
||||
C.PRIORITY_DOWNLOAD);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance suitable for reading cached content as part of removing a download. The
|
||||
* created instance is equivalent to one that would be created by {@link #createDataSource()},
|
||||
* except:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The upstream is overridden to be {@code null}, since when removing content we don't
|
||||
* want to request anything that's not already cached.
|
||||
* <li>The {@link #FLAG_BLOCK_ON_CACHE} is always set.
|
||||
* <li>The task priority is overridden to be {@link C#PRIORITY_DOWNLOAD}.
|
||||
* </ul>
|
||||
*
|
||||
* @return An instance suitable for reading cached content as part of removing a download.
|
||||
*/
|
||||
public CacheDataSource createDataSourceForRemovingDownload() {
|
||||
return createDataSourceInternal(
|
||||
/* upstreamDataSource= */ null, flags | FLAG_BLOCK_ON_CACHE, C.PRIORITY_DOWNLOAD);
|
||||
}
|
||||
|
||||
private CacheDataSource createDataSourceInternal(
|
||||
@Nullable DataSource upstreamDataSource, @Flags int flags, int upstreamPriority) {
|
||||
Cache cache = Assertions.checkNotNull(this.cache);
|
||||
@Nullable
|
||||
DataSource upstreamDataSource =
|
||||
upstreamDataSourceFactory != null ? upstreamDataSourceFactory.createDataSource() : null;
|
||||
@Nullable DataSink cacheWriteDataSink;
|
||||
if (cacheIsReadOnly) {
|
||||
if (cacheIsReadOnly || upstreamDataSource == null) {
|
||||
cacheWriteDataSink = null;
|
||||
} else if (cacheWriteDataSinkFactory != null) {
|
||||
cacheWriteDataSink = cacheWriteDataSinkFactory.createDataSink();
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import android.net.Uri;
|
|||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import java.util.Collections;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
@ -32,9 +33,11 @@ public final class DefaultDownloaderFactoryTest {
|
|||
|
||||
@Test
|
||||
public void createProgressiveDownloader() throws Exception {
|
||||
DownloaderConstructorHelper constructorHelper =
|
||||
new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper);
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(Mockito.mock(Cache.class))
|
||||
.setUpstreamDataSourceFactory(DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory);
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import androidx.annotation.Nullable;
|
|||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.extractor.ChunkIndex;
|
||||
import com.google.android.exoplayer2.offline.DownloadException;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.source.dash.DashSegmentIndex;
|
||||
|
|
@ -35,6 +34,7 @@ import com.google.android.exoplayer2.source.dash.manifest.Representation;
|
|||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -46,19 +46,20 @@ import java.util.List;
|
|||
*
|
||||
* <pre>{@code
|
||||
* SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor(), databaseProvider);
|
||||
* DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
|
||||
* DownloaderConstructorHelper constructorHelper =
|
||||
* new DownloaderConstructorHelper(cache, factory);
|
||||
* CacheDataSource.Factory cacheDataSourceFactory =
|
||||
* new CacheDataSource.Factory()
|
||||
* .setCache(cache)
|
||||
* .setUpstreamDataSourceFactory(new DefaultHttpDataSourceFactory(userAgent));
|
||||
* // Create a downloader for the first representation of the first adaptation set of the first
|
||||
* // period.
|
||||
* DashDownloader dashDownloader =
|
||||
* new DashDownloader(
|
||||
* manifestUrl, Collections.singletonList(new StreamKey(0, 0, 0)), constructorHelper);
|
||||
* manifestUrl, Collections.singletonList(new StreamKey(0, 0, 0)), cacheDataSourceFactory);
|
||||
* // Perform the download.
|
||||
* dashDownloader.download(progressListener);
|
||||
* // Access downloaded data using CacheDataSource
|
||||
* CacheDataSource cacheDataSource =
|
||||
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||
* // Use the downloaded data for playback.
|
||||
* DashMediaSource mediaSource =
|
||||
* new DashMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class DashDownloader extends SegmentDownloader<DashManifest> {
|
||||
|
|
@ -67,11 +68,12 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
|
|||
* @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 constructorHelper A {@link DownloaderConstructorHelper} instance.
|
||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||
* download will be written.
|
||||
*/
|
||||
public DashDownloader(
|
||||
Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
|
||||
super(manifestUri, streamKeys, constructorHelper);
|
||||
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||
super(manifestUri, streamKeys, cacheDataSourceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -32,17 +32,16 @@ import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
|
|||
import com.google.android.exoplayer2.offline.DownloadException;
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.Downloader;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.DownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource.Factory;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -81,9 +80,11 @@ public class DashDownloaderTest {
|
|||
|
||||
@Test
|
||||
public void createWithDefaultDownloaderFactory() {
|
||||
DownloaderConstructorHelper constructorHelper =
|
||||
new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper);
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(Mockito.mock(Cache.class))
|
||||
.setUpstreamDataSourceFactory(DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory);
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
|
|
@ -184,7 +185,7 @@ public class DashDownloaderTest {
|
|||
.setRandomData("text_segment_2", 2)
|
||||
.setRandomData("text_segment_3", 3);
|
||||
FakeDataSource fakeDataSource = new FakeDataSource(fakeDataSet);
|
||||
Factory factory = mock(Factory.class);
|
||||
FakeDataSource.Factory factory = mock(FakeDataSource.Factory.class);
|
||||
when(factory.createDataSource()).thenReturn(fakeDataSource);
|
||||
|
||||
DashDownloader dashDownloader =
|
||||
|
|
@ -216,7 +217,7 @@ public class DashDownloaderTest {
|
|||
.setRandomData("period_2_segment_2", 2)
|
||||
.setRandomData("period_2_segment_3", 3);
|
||||
FakeDataSource fakeDataSource = new FakeDataSource(fakeDataSet);
|
||||
Factory factory = mock(Factory.class);
|
||||
FakeDataSource.Factory factory = mock(FakeDataSource.Factory.class);
|
||||
when(factory.createDataSource()).thenReturn(fakeDataSource);
|
||||
|
||||
DashDownloader dashDownloader =
|
||||
|
|
@ -327,12 +328,16 @@ public class DashDownloaderTest {
|
|||
}
|
||||
|
||||
private DashDownloader getDashDownloader(FakeDataSet fakeDataSet, StreamKey... keys) {
|
||||
return getDashDownloader(new Factory().setFakeDataSet(fakeDataSet), keys);
|
||||
return getDashDownloader(new FakeDataSource.Factory().setFakeDataSet(fakeDataSet), keys);
|
||||
}
|
||||
|
||||
private DashDownloader getDashDownloader(Factory factory, StreamKey... keys) {
|
||||
return new DashDownloader(
|
||||
TEST_MPD_URI, keysList(keys), new DownloaderConstructorHelper(cache, factory));
|
||||
private DashDownloader getDashDownloader(
|
||||
FakeDataSource.Factory upstreamDataSourceFactory, StreamKey... keys) {
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(upstreamDataSourceFactory);
|
||||
return new DashDownloader(TEST_MPD_URI, keysList(keys), cacheDataSourceFactory);
|
||||
}
|
||||
|
||||
private static ArrayList<StreamKey> keysList(StreamKey... keys) {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import com.google.android.exoplayer2.offline.DefaultDownloadIndex;
|
|||
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.scheduler.Requirements;
|
||||
import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet;
|
||||
|
|
@ -40,6 +39,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource;
|
|||
import com.google.android.exoplayer2.testutil.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.upstream.DataSource.Factory;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -253,12 +253,14 @@ public class DownloadManagerDashTest {
|
|||
runOnMainThread(
|
||||
() -> {
|
||||
Factory fakeDataSourceFactory = new FakeDataSource.Factory().setFakeDataSet(fakeDataSet);
|
||||
DefaultDownloaderFactory downloaderFactory =
|
||||
new DefaultDownloaderFactory(
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(fakeDataSourceFactory));
|
||||
downloadManager =
|
||||
new DownloadManager(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
downloadIndex,
|
||||
new DefaultDownloaderFactory(
|
||||
new DownloaderConstructorHelper(cache, fakeDataSourceFactory)));
|
||||
ApplicationProvider.getApplicationContext(), downloadIndex, downloaderFactory);
|
||||
downloadManager.setRequirements(new Requirements(0));
|
||||
|
||||
downloadManagerListener =
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import com.google.android.exoplayer2.offline.Download;
|
|||
import com.google.android.exoplayer2.offline.DownloadManager;
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.DownloadService;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.scheduler.Scheduler;
|
||||
import com.google.android.exoplayer2.testutil.DummyMainThread;
|
||||
|
|
@ -42,6 +41,7 @@ import com.google.android.exoplayer2.testutil.FakeDataSource;
|
|||
import com.google.android.exoplayer2.testutil.TestDownloadManagerListener;
|
||||
import com.google.android.exoplayer2.testutil.TestUtil;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.ConditionVariable;
|
||||
|
|
@ -113,12 +113,14 @@ public class DownloadServiceDashTest {
|
|||
() -> {
|
||||
DefaultDownloadIndex downloadIndex =
|
||||
new DefaultDownloadIndex(TestUtil.getInMemoryDatabaseProvider());
|
||||
DefaultDownloaderFactory downloaderFactory =
|
||||
new DefaultDownloaderFactory(
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(fakeDataSourceFactory));
|
||||
final DownloadManager dashDownloadManager =
|
||||
new DownloadManager(
|
||||
ApplicationProvider.getApplicationContext(),
|
||||
downloadIndex,
|
||||
new DefaultDownloaderFactory(
|
||||
new DownloaderConstructorHelper(cache, fakeDataSourceFactory)));
|
||||
ApplicationProvider.getApplicationContext(), downloadIndex, downloaderFactory);
|
||||
downloadManagerListener =
|
||||
new TestDownloadManagerListener(dashDownloadManager, dummyMainThread);
|
||||
dashDownloadManager.resumeDownloads();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source.hls.offline;
|
|||
|
||||
import android.net.Uri;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
|
||||
|
|
@ -27,6 +26,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
|
|||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.util.UriUtil;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -40,20 +40,20 @@ import java.util.List;
|
|||
*
|
||||
* <pre>{@code
|
||||
* SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor(), databaseProvider);
|
||||
* DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
|
||||
* DownloaderConstructorHelper constructorHelper =
|
||||
* new DownloaderConstructorHelper(cache, factory);
|
||||
* CacheDataSource.Factory cacheDataSourceFactory =
|
||||
* new CacheDataSource.Factory()
|
||||
* .setCache(cache)
|
||||
* .setUpstreamDataSourceFactory(new DefaultHttpDataSourceFactory(userAgent));
|
||||
* // Create a downloader for the first variant in a master playlist.
|
||||
* HlsDownloader hlsDownloader =
|
||||
* new HlsDownloader(
|
||||
* playlistUri,
|
||||
* Collections.singletonList(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0)),
|
||||
* constructorHelper);
|
||||
* Collections.singletonList(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0));
|
||||
* // Perform the download.
|
||||
* hlsDownloader.download(progressListener);
|
||||
* // Access downloaded data using CacheDataSource
|
||||
* CacheDataSource cacheDataSource =
|
||||
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||
* // Use the downloaded data for playback.
|
||||
* HlsMediaSource mediaSource =
|
||||
* new HlsMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
||||
|
|
@ -62,11 +62,12 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
|||
* @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 constructorHelper A {@link DownloaderConstructorHelper} instance.
|
||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||
* download will be written.
|
||||
*/
|
||||
public HlsDownloader(
|
||||
Uri playlistUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
|
||||
super(playlistUri, streamKeys, constructorHelper);
|
||||
Uri playlistUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||
super(playlistUri, streamKeys, cacheDataSourceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -40,15 +40,15 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|||
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.Downloader;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.DownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
|
||||
import com.google.android.exoplayer2.testutil.CacheAsserts.RequestSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSet;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource.Factory;
|
||||
import com.google.android.exoplayer2.testutil.FakeDataSource;
|
||||
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
|
||||
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
|
@ -97,9 +97,11 @@ public class HlsDownloaderTest {
|
|||
|
||||
@Test
|
||||
public void createWithDefaultDownloaderFactory() {
|
||||
DownloaderConstructorHelper constructorHelper =
|
||||
new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper);
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(Mockito.mock(Cache.class))
|
||||
.setUpstreamDataSourceFactory(DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory);
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
|
|
@ -213,9 +215,11 @@ public class HlsDownloaderTest {
|
|||
}
|
||||
|
||||
private HlsDownloader getHlsDownloader(String mediaPlaylistUri, List<StreamKey> keys) {
|
||||
Factory factory = new Factory().setFakeDataSet(fakeDataSet);
|
||||
return new HlsDownloader(
|
||||
Uri.parse(mediaPlaylistUri), keys, new DownloaderConstructorHelper(cache, factory));
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(new FakeDataSource.Factory().setFakeDataSet(fakeDataSet));
|
||||
return new HlsDownloader(Uri.parse(mediaPlaylistUri), keys, cacheDataSourceFactory);
|
||||
}
|
||||
|
||||
private static ArrayList<StreamKey> getKeys(int... variantIndices) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source.smoothstreaming.offline;
|
|||
|
||||
import android.net.Uri;
|
||||
import com.google.android.exoplayer2.C;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.SegmentDownloader;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
|
||||
|
|
@ -27,6 +26,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil;
|
|||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DataSpec;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -38,20 +38,21 @@ import java.util.List;
|
|||
*
|
||||
* <pre>{@code
|
||||
* SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor(), databaseProvider);
|
||||
* DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
|
||||
* DownloaderConstructorHelper constructorHelper =
|
||||
* new DownloaderConstructorHelper(cache, factory);
|
||||
* CacheDataSource.Factory cacheDataSourceFactory =
|
||||
* new CacheDataSource.Factory()
|
||||
* .setCache(cache)
|
||||
* .setUpstreamDataSourceFactory(new DefaultHttpDataSourceFactory(userAgent));
|
||||
* // Create a downloader for the first track of the first stream element.
|
||||
* SsDownloader ssDownloader =
|
||||
* new SsDownloader(
|
||||
* manifestUrl,
|
||||
* Collections.singletonList(new StreamKey(0, 0)),
|
||||
* constructorHelper);
|
||||
* cacheDataSourceFactory);
|
||||
* // Perform the download.
|
||||
* ssDownloader.download(progressListener);
|
||||
* // Access downloaded data using CacheDataSource
|
||||
* CacheDataSource cacheDataSource =
|
||||
* new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
|
||||
* // Use the downloaded data for playback.
|
||||
* SsMediaSource mediaSource =
|
||||
* new SsMediaSource.Factory(cacheDataSourceFactory).createMediaSource(mediaItem);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class SsDownloader extends SegmentDownloader<SsManifest> {
|
||||
|
|
@ -60,11 +61,12 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
|
|||
* @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 constructorHelper A {@link DownloaderConstructorHelper} instance.
|
||||
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
|
||||
* download will be written.
|
||||
*/
|
||||
public SsDownloader(
|
||||
Uri manifestUri, List<StreamKey> streamKeys, DownloaderConstructorHelper constructorHelper) {
|
||||
super(SsUtil.fixManifestUri(manifestUri), streamKeys, constructorHelper);
|
||||
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
|
||||
super(SsUtil.fixManifestUri(manifestUri), streamKeys, cacheDataSourceFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|||
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.DownloadRequest;
|
||||
import com.google.android.exoplayer2.offline.Downloader;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.DownloaderFactory;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.upstream.DummyDataSource;
|
||||
import com.google.android.exoplayer2.upstream.cache.Cache;
|
||||
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
|
||||
import java.util.Collections;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
|
@ -38,9 +38,11 @@ public final class SsDownloaderTest {
|
|||
|
||||
@Test
|
||||
public void createWithDefaultDownloaderFactory() throws Exception {
|
||||
DownloaderConstructorHelper constructorHelper =
|
||||
new DownloaderConstructorHelper(Mockito.mock(Cache.class), DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(constructorHelper);
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(Mockito.mock(Cache.class))
|
||||
.setUpstreamDataSourceFactory(DummyDataSource.FACTORY);
|
||||
DownloaderFactory factory = new DefaultDownloaderFactory(cacheDataSourceFactory);
|
||||
|
||||
Downloader downloader =
|
||||
factory.createDownloader(
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertWithMessage;
|
|||
import android.net.Uri;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
import com.google.android.exoplayer2.source.dash.DashUtil;
|
||||
import com.google.android.exoplayer2.source.dash.manifest.AdaptationSet;
|
||||
|
|
@ -120,9 +119,11 @@ public final class DashDownloadTest {
|
|||
}
|
||||
}
|
||||
}
|
||||
DownloaderConstructorHelper constructorHelper =
|
||||
new DownloaderConstructorHelper(cache, httpDataSourceFactory);
|
||||
return new DashDownloader(MANIFEST_URI, keys, constructorHelper);
|
||||
CacheDataSource.Factory cacheDataSourceFactory =
|
||||
new CacheDataSource.Factory()
|
||||
.setCache(cache)
|
||||
.setUpstreamDataSourceFactory(httpDataSourceFactory);
|
||||
return new DashDownloader(MANIFEST_URI, keys, cacheDataSourceFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue