Make all segment downloader use the media item

PiperOrigin-RevId: 311527440
This commit is contained in:
bachinger 2020-05-14 15:24:40 +01:00 committed by Oliver Woodman
parent c1aa9b917b
commit 9e35c6c28c
7 changed files with 146 additions and 59 deletions

View File

@ -15,10 +15,13 @@
*/
package com.google.android.exoplayer2.offline;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.net.Uri;
import android.util.Pair;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
@ -79,10 +82,8 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
@Nullable private volatile Thread downloadThread;
/**
* @param manifestUri The {@link Uri} of the manifest to be downloaded.
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param manifestParser A parser for the manifest.
* @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 executor An {@link Executor} used to make requests for the media being downloaded.
@ -90,14 +91,14 @@ public abstract class SegmentDownloader<M extends FilterableManifest<M>> impleme
* allowing parts of it to be executed in parallel.
*/
public SegmentDownloader(
Uri manifestUri,
MediaItem mediaItem,
Parser<M> manifestParser,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
this.manifestDataSpec = getCompressibleDataSpec(manifestUri);
checkNotNull(mediaItem.playbackProperties);
this.manifestDataSpec = getCompressibleDataSpec(mediaItem.playbackProperties.uri);
this.manifestParser = manifestParser;
this.streamKeys = new ArrayList<>(streamKeys);
this.streamKeys = new ArrayList<>(mediaItem.playbackProperties.streamKeys);
this.cacheDataSourceFactory = cacheDataSourceFactory;
this.executor = executor;
isCanceled = new AtomicBoolean();

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source.dash.offline;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.extractor.ChunkIndex;
import com.google.android.exoplayer2.offline.DownloadException;
import com.google.android.exoplayer2.offline.SegmentDownloader;
@ -54,7 +55,11 @@ import java.util.concurrent.Executor;
* // period.
* DashDownloader dashDownloader =
* new DashDownloader(
* manifestUrl, Collections.singletonList(new StreamKey(0, 0, 0)), cacheDataSourceFactory);
* new MediaItem.Builder()
* .setUri(manifestUrl)
* .setStreamKeys(Collections.singletonList(new StreamKey(0, 0, 0)))
* .build(),
* cacheDataSourceFactory);
* // Perform the download.
* dashDownloader.download(progressListener);
* // Use the downloaded data for playback.
@ -64,22 +69,44 @@ import java.util.concurrent.Executor;
*/
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 cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
*/
/** @deprecated Use {@link #DashDownloader(MediaItem, CacheDataSource.Factory)} instead. */
@SuppressWarnings("deprecation")
@Deprecated
public DashDownloader(
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
this(manifestUri, streamKeys, cacheDataSourceFactory, Runnable::run);
}
/**
* @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.
* Creates a new instance.
*
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
*/
public DashDownloader(MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory) {
this(mediaItem, cacheDataSourceFactory, Runnable::run);
}
/**
* @deprecated Use {@link #DashDownloader(MediaItem, CacheDataSource.Factory, Executor)} instead.
*/
@Deprecated
public DashDownloader(
Uri manifestUri,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
this(
new MediaItem.Builder().setUri(manifestUri).setStreamKeys(streamKeys).build(),
cacheDataSourceFactory,
executor);
}
/**
* Creates a new instance.
*
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
* @param executor An {@link Executor} used to make requests for the media being downloaded.
@ -87,11 +114,8 @@ public final class DashDownloader extends SegmentDownloader<DashManifest> {
* allowing parts of it to be executed in parallel.
*/
public DashDownloader(
Uri manifestUri,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
super(manifestUri, new DashManifestParser(), streamKeys, cacheDataSourceFactory, executor);
MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) {
super(mediaItem, new DashManifestParser(), cacheDataSourceFactory, executor);
}
@Override

View File

@ -28,6 +28,7 @@ import static org.mockito.Mockito.when;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
import com.google.android.exoplayer2.offline.DownloadException;
import com.google.android.exoplayer2.offline.DownloadRequest;
@ -337,7 +338,9 @@ public class DashDownloaderTest {
new CacheDataSource.Factory()
.setCache(cache)
.setUpstreamDataSourceFactory(upstreamDataSourceFactory);
return new DashDownloader(TEST_MPD_URI, keysList(keys), cacheDataSourceFactory);
return new DashDownloader(
new MediaItem.Builder().setUri(TEST_MPD_URI).setStreamKeys(keysList(keys)).build(),
cacheDataSourceFactory);
}
private static ArrayList<StreamKey> keysList(StreamKey... keys) {

View File

@ -17,6 +17,7 @@ package com.google.android.exoplayer2.source.hls.offline;
import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
@ -47,8 +48,13 @@ import java.util.concurrent.Executor;
* // 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));
* new MediaItem.Builder()
* .setUri(playlistUri)
* .setStreamKeys(
* Collections.singletonList(
* new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0)))
* .build(),
* Collections.singletonList();
* // Perform the download.
* hlsDownloader.download(progressListener);
* // Use the downloaded data for playback.
@ -58,22 +64,44 @@ import java.util.concurrent.Executor;
*/
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 cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
*/
/** @deprecated Use {@link #HlsDownloader(MediaItem, CacheDataSource.Factory)} instead. */
@SuppressWarnings("deprecation")
@Deprecated
public HlsDownloader(
Uri playlistUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
this(playlistUri, streamKeys, cacheDataSourceFactory, Runnable::run);
}
/**
* @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.
* Creates a new instance.
*
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
*/
public HlsDownloader(MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory) {
this(mediaItem, cacheDataSourceFactory, Runnable::run);
}
/**
* @deprecated Use {@link #HlsDownloader(MediaItem, CacheDataSource.Factory, Executor)} instead.
*/
@Deprecated
public HlsDownloader(
Uri playlistUri,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
this(
new MediaItem.Builder().setUri(playlistUri).setStreamKeys(streamKeys).build(),
cacheDataSourceFactory,
executor);
}
/**
* Creates a new instance.
*
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
* @param executor An {@link Executor} used to make requests for the media being downloaded.
@ -81,11 +109,8 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
* allowing parts of it to be executed in parallel.
*/
public HlsDownloader(
Uri playlistUri,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
super(playlistUri, new HlsPlaylistParser(), streamKeys, cacheDataSourceFactory, executor);
MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) {
super(mediaItem, new HlsPlaylistParser(), cacheDataSourceFactory, executor);
}
@Override

View File

@ -37,6 +37,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.offline.DefaultDownloaderFactory;
import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.offline.Downloader;
@ -219,7 +220,9 @@ public class HlsDownloaderTest {
new CacheDataSource.Factory()
.setCache(cache)
.setUpstreamDataSourceFactory(new FakeDataSource.Factory().setFakeDataSet(fakeDataSet));
return new HlsDownloader(Uri.parse(mediaPlaylistUri), keys, cacheDataSourceFactory);
return new HlsDownloader(
new MediaItem.Builder().setUri(mediaPlaylistUri).setStreamKeys(keys).build(),
cacheDataSourceFactory);
}
private static ArrayList<StreamKey> getKeys(int... variantIndices) {

View File

@ -15,7 +15,10 @@
*/
package com.google.android.exoplayer2.source.smoothstreaming.offline;
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
import android.net.Uri;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
@ -43,8 +46,10 @@ import java.util.concurrent.Executor;
* // Create a downloader for the first track of the first stream element.
* SsDownloader ssDownloader =
* new SsDownloader(
* manifestUrl,
* Collections.singletonList(new StreamKey(0, 0)),
* new MediaItem.Builder()
* .setUri(manifestUri)
* .setStreamKeys(Collections.singletonList(new StreamKey(0, 0)))
* .build(),
* cacheDataSourceFactory);
* // Perform the download.
* ssDownloader.download(progressListener);
@ -56,21 +61,45 @@ import java.util.concurrent.Executor;
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 cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
* @deprecated Use {@link #SsDownloader(MediaItem, CacheDataSource.Factory, Executor)} instead.
*/
@SuppressWarnings("deprecation")
@Deprecated
public SsDownloader(
Uri manifestUri, List<StreamKey> streamKeys, CacheDataSource.Factory cacheDataSourceFactory) {
this(manifestUri, streamKeys, cacheDataSourceFactory, Runnable::run);
}
/**
* @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.
* Creates an instance.
*
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
*/
public SsDownloader(MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory) {
this(mediaItem, cacheDataSourceFactory, Runnable::run);
}
/**
* @deprecated Use {@link #SsDownloader(MediaItem, CacheDataSource.Factory, Executor)} instead.
*/
@Deprecated
public SsDownloader(
Uri manifestUri,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
this(
new MediaItem.Builder().setUri(manifestUri).setStreamKeys(streamKeys).build(),
cacheDataSourceFactory,
executor);
}
/**
* Creates an instance.
*
* @param mediaItem The {@link MediaItem} to be downloaded.
* @param cacheDataSourceFactory A {@link CacheDataSource.Factory} for the cache into which the
* download will be written.
* @param executor An {@link Executor} used to make requests for the media being downloaded.
@ -78,14 +107,13 @@ public final class SsDownloader extends SegmentDownloader<SsManifest> {
* allowing parts of it to be executed in parallel.
*/
public SsDownloader(
Uri manifestUri,
List<StreamKey> streamKeys,
CacheDataSource.Factory cacheDataSourceFactory,
Executor executor) {
MediaItem mediaItem, CacheDataSource.Factory cacheDataSourceFactory, Executor executor) {
super(
SsUtil.fixManifestUri(manifestUri),
mediaItem
.buildUpon()
.setUri(SsUtil.fixManifestUri(checkNotNull(mediaItem.playbackProperties).uri))
.build(),
new SsManifestParser(),
streamKeys,
cacheDataSourceFactory,
executor);
}

View File

@ -20,6 +20,7 @@ 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.MediaItem;
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,7 +121,9 @@ public final class DashDownloadTest {
new CacheDataSource.Factory()
.setCache(cache)
.setUpstreamDataSourceFactory(httpDataSourceFactory);
return new DashDownloader(MANIFEST_URI, keys, cacheDataSourceFactory);
return new DashDownloader(
new MediaItem.Builder().setUri(MANIFEST_URI).setStreamKeys(keys).build(),
cacheDataSourceFactory);
}
}