Allow injection of DataSource's per type of data
This allows the client to define what data source is used for media chunks, encryption chunks and playlists. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=149537766
This commit is contained in:
parent
78e7c3c510
commit
3be4451e13
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.source.hls;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of {@link HlsDataSourceFactory}.
|
||||||
|
*/
|
||||||
|
public final class DefaultHlsDataSourceFactory implements HlsDataSourceFactory {
|
||||||
|
|
||||||
|
private final DataSource.Factory dataSourceFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dataSourceFactory The {@link DataSource.Factory} to use for all data types.
|
||||||
|
*/
|
||||||
|
public DefaultHlsDataSourceFactory(DataSource.Factory dataSourceFactory) {
|
||||||
|
this.dataSourceFactory = dataSourceFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataSource createDataSource(int dataType) {
|
||||||
|
return dataSourceFactory.createDataSource();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -81,7 +81,8 @@ import java.util.Locale;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DataSource dataSource;
|
private final DataSource mediaDataSource;
|
||||||
|
private final DataSource encryptionDataSource;
|
||||||
private final TimestampAdjusterProvider timestampAdjusterProvider;
|
private final TimestampAdjusterProvider timestampAdjusterProvider;
|
||||||
private final HlsUrl[] variants;
|
private final HlsUrl[] variants;
|
||||||
private final HlsPlaylistTracker playlistTracker;
|
private final HlsPlaylistTracker playlistTracker;
|
||||||
@ -105,18 +106,18 @@ import java.util.Locale;
|
|||||||
/**
|
/**
|
||||||
* @param playlistTracker The {@link HlsPlaylistTracker} from which to obtain media playlists.
|
* @param playlistTracker The {@link HlsPlaylistTracker} from which to obtain media playlists.
|
||||||
* @param variants The available variants.
|
* @param variants The available variants.
|
||||||
* @param dataSource A {@link DataSource} suitable for loading the media data.
|
* @param dataSourceFactory An {@link HlsDataSourceFactory} to create {@link DataSource}s for the
|
||||||
|
* chunks.
|
||||||
* @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If
|
* @param timestampAdjusterProvider A provider of {@link TimestampAdjuster} instances. If
|
||||||
* multiple {@link HlsChunkSource}s are used for a single playback, they should all share the
|
* multiple {@link HlsChunkSource}s are used for a single playback, they should all share the
|
||||||
* same provider.
|
* same provider.
|
||||||
* @param muxedCaptionFormats List of muxed caption {@link Format}s.
|
* @param muxedCaptionFormats List of muxed caption {@link Format}s.
|
||||||
*/
|
*/
|
||||||
public HlsChunkSource(HlsPlaylistTracker playlistTracker, HlsUrl[] variants,
|
public HlsChunkSource(HlsPlaylistTracker playlistTracker, HlsUrl[] variants,
|
||||||
DataSource dataSource, TimestampAdjusterProvider timestampAdjusterProvider,
|
HlsDataSourceFactory dataSourceFactory, TimestampAdjusterProvider timestampAdjusterProvider,
|
||||||
List<Format> muxedCaptionFormats) {
|
List<Format> muxedCaptionFormats) {
|
||||||
this.playlistTracker = playlistTracker;
|
this.playlistTracker = playlistTracker;
|
||||||
this.variants = variants;
|
this.variants = variants;
|
||||||
this.dataSource = dataSource;
|
|
||||||
this.timestampAdjusterProvider = timestampAdjusterProvider;
|
this.timestampAdjusterProvider = timestampAdjusterProvider;
|
||||||
this.muxedCaptionFormats = muxedCaptionFormats;
|
this.muxedCaptionFormats = muxedCaptionFormats;
|
||||||
Format[] variantFormats = new Format[variants.length];
|
Format[] variantFormats = new Format[variants.length];
|
||||||
@ -125,6 +126,8 @@ import java.util.Locale;
|
|||||||
variantFormats[i] = variants[i].format;
|
variantFormats[i] = variants[i].format;
|
||||||
initialTrackSelection[i] = i;
|
initialTrackSelection[i] = i;
|
||||||
}
|
}
|
||||||
|
mediaDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_MEDIA);
|
||||||
|
encryptionDataSource = dataSourceFactory.createDataSource(C.DATA_TYPE_DRM);
|
||||||
trackGroup = new TrackGroup(variantFormats);
|
trackGroup = new TrackGroup(variantFormats);
|
||||||
trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection);
|
trackSelection = new InitializationTrackSelection(trackGroup, initialTrackSelection);
|
||||||
}
|
}
|
||||||
@ -285,7 +288,7 @@ import java.util.Locale;
|
|||||||
Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
|
Uri chunkUri = UriUtil.resolveToUri(mediaPlaylist.baseUri, segment.url);
|
||||||
DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength,
|
DataSpec dataSpec = new DataSpec(chunkUri, segment.byterangeOffset, segment.byterangeLength,
|
||||||
null);
|
null);
|
||||||
out.chunk = new HlsMediaChunk(dataSource, dataSpec, initDataSpec, selectedUrl,
|
out.chunk = new HlsMediaChunk(mediaDataSource, dataSpec, initDataSpec, selectedUrl,
|
||||||
muxedCaptionFormats, trackSelection.getSelectionReason(), trackSelection.getSelectionData(),
|
muxedCaptionFormats, trackSelection.getSelectionReason(), trackSelection.getSelectionData(),
|
||||||
startTimeUs, startTimeUs + segment.durationUs, chunkMediaSequence, discontinuitySequence,
|
startTimeUs, startTimeUs + segment.durationUs, chunkMediaSequence, discontinuitySequence,
|
||||||
isTimestampMaster, timestampAdjuster, previous, encryptionKey, encryptionIv);
|
isTimestampMaster, timestampAdjuster, previous, encryptionKey, encryptionIv);
|
||||||
@ -341,7 +344,7 @@ import java.util.Locale;
|
|||||||
private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv, int variantIndex,
|
private EncryptionKeyChunk newEncryptionKeyChunk(Uri keyUri, String iv, int variantIndex,
|
||||||
int trackSelectionReason, Object trackSelectionData) {
|
int trackSelectionReason, Object trackSelectionData) {
|
||||||
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP);
|
DataSpec dataSpec = new DataSpec(keyUri, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP);
|
||||||
return new EncryptionKeyChunk(dataSource, dataSpec, variants[variantIndex].format,
|
return new EncryptionKeyChunk(encryptionDataSource, dataSpec, variants[variantIndex].format,
|
||||||
trackSelectionReason, trackSelectionData, scratchSpace, iv);
|
trackSelectionReason, trackSelectionData, scratchSpace, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.source.hls;
|
||||||
|
|
||||||
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates {@link DataSource}s for HLS playlists, encryption and media chunks.
|
||||||
|
*/
|
||||||
|
public interface HlsDataSourceFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a {@link DataSource} for the given data type.
|
||||||
|
*
|
||||||
|
* @param dataType The data type for which the {@link DataSource} will be used. One of {@link C}
|
||||||
|
* {@code .DATA_TYPE_*} constants.
|
||||||
|
* @return A {@link DataSource} for the given data type.
|
||||||
|
*/
|
||||||
|
DataSource createDataSource(int dataType);
|
||||||
|
|
||||||
|
}
|
@ -30,7 +30,6 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUr
|
|||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
|
||||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||||
import com.google.android.exoplayer2.upstream.Allocator;
|
import com.google.android.exoplayer2.upstream.Allocator;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -44,7 +43,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||||||
HlsPlaylistTracker.PlaylistEventListener {
|
HlsPlaylistTracker.PlaylistEventListener {
|
||||||
|
|
||||||
private final HlsPlaylistTracker playlistTracker;
|
private final HlsPlaylistTracker playlistTracker;
|
||||||
private final DataSource.Factory dataSourceFactory;
|
private final HlsDataSourceFactory dataSourceFactory;
|
||||||
private final int minLoadableRetryCount;
|
private final int minLoadableRetryCount;
|
||||||
private final EventDispatcher eventDispatcher;
|
private final EventDispatcher eventDispatcher;
|
||||||
private final Allocator allocator;
|
private final Allocator allocator;
|
||||||
@ -61,7 +60,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||||||
private HlsSampleStreamWrapper[] enabledSampleStreamWrappers;
|
private HlsSampleStreamWrapper[] enabledSampleStreamWrappers;
|
||||||
private CompositeSequenceableLoader sequenceableLoader;
|
private CompositeSequenceableLoader sequenceableLoader;
|
||||||
|
|
||||||
public HlsMediaPeriod(HlsPlaylistTracker playlistTracker, DataSource.Factory dataSourceFactory,
|
public HlsMediaPeriod(HlsPlaylistTracker playlistTracker, HlsDataSourceFactory dataSourceFactory,
|
||||||
int minLoadableRetryCount, EventDispatcher eventDispatcher, Allocator allocator,
|
int minLoadableRetryCount, EventDispatcher eventDispatcher, Allocator allocator,
|
||||||
long positionUs) {
|
long positionUs) {
|
||||||
this.playlistTracker = playlistTracker;
|
this.playlistTracker = playlistTracker;
|
||||||
@ -349,9 +348,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||||||
|
|
||||||
private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, HlsUrl[] variants,
|
private HlsSampleStreamWrapper buildSampleStreamWrapper(int trackType, HlsUrl[] variants,
|
||||||
Format muxedAudioFormat, List<Format> muxedCaptionFormats) {
|
Format muxedAudioFormat, List<Format> muxedCaptionFormats) {
|
||||||
DataSource dataSource = dataSourceFactory.createDataSource();
|
HlsChunkSource defaultChunkSource = new HlsChunkSource(playlistTracker, variants,
|
||||||
HlsChunkSource defaultChunkSource = new HlsChunkSource(playlistTracker, variants, dataSource,
|
dataSourceFactory, timestampAdjusterProvider, muxedCaptionFormats);
|
||||||
timestampAdjusterProvider, muxedCaptionFormats);
|
|
||||||
return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator,
|
return new HlsSampleStreamWrapper(trackType, this, defaultChunkSource, allocator,
|
||||||
preparePositionUs, muxedAudioFormat, minLoadableRetryCount, eventDispatcher);
|
preparePositionUs, muxedAudioFormat, minLoadableRetryCount, eventDispatcher);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public final class HlsMediaSource implements MediaSource,
|
|||||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
||||||
|
|
||||||
private final Uri manifestUri;
|
private final Uri manifestUri;
|
||||||
private final DataSource.Factory dataSourceFactory;
|
private final HlsDataSourceFactory dataSourceFactory;
|
||||||
private final int minLoadableRetryCount;
|
private final int minLoadableRetryCount;
|
||||||
private final EventDispatcher eventDispatcher;
|
private final EventDispatcher eventDispatcher;
|
||||||
|
|
||||||
@ -60,6 +60,13 @@ public final class HlsMediaSource implements MediaSource,
|
|||||||
public HlsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
|
public HlsMediaSource(Uri manifestUri, DataSource.Factory dataSourceFactory,
|
||||||
int minLoadableRetryCount, Handler eventHandler,
|
int minLoadableRetryCount, Handler eventHandler,
|
||||||
AdaptiveMediaSourceEventListener eventListener) {
|
AdaptiveMediaSourceEventListener eventListener) {
|
||||||
|
this(manifestUri, new DefaultHlsDataSourceFactory(dataSourceFactory), minLoadableRetryCount,
|
||||||
|
eventHandler, eventListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HlsMediaSource(Uri manifestUri, HlsDataSourceFactory dataSourceFactory,
|
||||||
|
int minLoadableRetryCount, Handler eventHandler,
|
||||||
|
AdaptiveMediaSourceEventListener eventListener) {
|
||||||
this.manifestUri = manifestUri;
|
this.manifestUri = manifestUri;
|
||||||
this.dataSourceFactory = dataSourceFactory;
|
this.dataSourceFactory = dataSourceFactory;
|
||||||
this.minLoadableRetryCount = minLoadableRetryCount;
|
this.minLoadableRetryCount = minLoadableRetryCount;
|
||||||
|
@ -22,6 +22,7 @@ import com.google.android.exoplayer2.C;
|
|||||||
import com.google.android.exoplayer2.ParserException;
|
import com.google.android.exoplayer2.ParserException;
|
||||||
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
import com.google.android.exoplayer2.source.AdaptiveMediaSourceEventListener.EventDispatcher;
|
||||||
import com.google.android.exoplayer2.source.chunk.ChunkedTrackBlacklistUtil;
|
import com.google.android.exoplayer2.source.chunk.ChunkedTrackBlacklistUtil;
|
||||||
|
import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
|
||||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
||||||
import com.google.android.exoplayer2.upstream.DataSource;
|
import com.google.android.exoplayer2.upstream.DataSource;
|
||||||
@ -81,7 +82,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||||||
private static final long PRIMARY_URL_KEEPALIVE_MS = 15000;
|
private static final long PRIMARY_URL_KEEPALIVE_MS = 15000;
|
||||||
|
|
||||||
private final Uri initialPlaylistUri;
|
private final Uri initialPlaylistUri;
|
||||||
private final DataSource.Factory dataSourceFactory;
|
private final HlsDataSourceFactory dataSourceFactory;
|
||||||
private final HlsPlaylistParser playlistParser;
|
private final HlsPlaylistParser playlistParser;
|
||||||
private final int minRetryCount;
|
private final int minRetryCount;
|
||||||
private final IdentityHashMap<HlsUrl, MediaPlaylistBundle> playlistBundles;
|
private final IdentityHashMap<HlsUrl, MediaPlaylistBundle> playlistBundles;
|
||||||
@ -105,7 +106,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||||||
* playlist.
|
* playlist.
|
||||||
* @param primaryPlaylistListener A callback for the primary playlist change events.
|
* @param primaryPlaylistListener A callback for the primary playlist change events.
|
||||||
*/
|
*/
|
||||||
public HlsPlaylistTracker(Uri initialPlaylistUri, DataSource.Factory dataSourceFactory,
|
public HlsPlaylistTracker(Uri initialPlaylistUri, HlsDataSourceFactory dataSourceFactory,
|
||||||
EventDispatcher eventDispatcher, int minRetryCount,
|
EventDispatcher eventDispatcher, int minRetryCount,
|
||||||
PrimaryPlaylistListener primaryPlaylistListener) {
|
PrimaryPlaylistListener primaryPlaylistListener) {
|
||||||
this.initialPlaylistUri = initialPlaylistUri;
|
this.initialPlaylistUri = initialPlaylistUri;
|
||||||
@ -143,8 +144,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||||||
*/
|
*/
|
||||||
public void start() {
|
public void start() {
|
||||||
ParsingLoadable<HlsPlaylist> masterPlaylistLoadable = new ParsingLoadable<>(
|
ParsingLoadable<HlsPlaylist> masterPlaylistLoadable = new ParsingLoadable<>(
|
||||||
dataSourceFactory.createDataSource(), initialPlaylistUri, C.DATA_TYPE_MANIFEST,
|
dataSourceFactory.createDataSource(C.DATA_TYPE_MANIFEST), initialPlaylistUri,
|
||||||
playlistParser);
|
C.DATA_TYPE_MANIFEST, playlistParser);
|
||||||
initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount);
|
initialPlaylistLoader.startLoading(masterPlaylistLoadable, this, minRetryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -436,7 +437,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||||||
this.playlistUrl = playlistUrl;
|
this.playlistUrl = playlistUrl;
|
||||||
lastSnapshotAccessTimeMs = initialLastSnapshotAccessTimeMs;
|
lastSnapshotAccessTimeMs = initialLastSnapshotAccessTimeMs;
|
||||||
mediaPlaylistLoader = new Loader("HlsPlaylistTracker:MediaPlaylist");
|
mediaPlaylistLoader = new Loader("HlsPlaylistTracker:MediaPlaylist");
|
||||||
mediaPlaylistLoadable = new ParsingLoadable<>(dataSourceFactory.createDataSource(),
|
mediaPlaylistLoadable = new ParsingLoadable<>(
|
||||||
|
dataSourceFactory.createDataSource(C.DATA_TYPE_MANIFEST),
|
||||||
UriUtil.resolveToUri(masterPlaylist.baseUri, playlistUrl.url), C.DATA_TYPE_MANIFEST,
|
UriUtil.resolveToUri(masterPlaylist.baseUri, playlistUrl.url), C.DATA_TYPE_MANIFEST,
|
||||||
playlistParser);
|
playlistParser);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,9 @@ public final class DataSpec {
|
|||||||
*/
|
*/
|
||||||
public static final int FLAG_ALLOW_GZIP = 1 << 0;
|
public static final int FLAG_ALLOW_GZIP = 1 << 0;
|
||||||
|
|
||||||
/** Permits content to be cached even if its length can not be resolved. */
|
/**
|
||||||
|
* Permits content to be cached even if its length can not be resolved.
|
||||||
|
*/
|
||||||
public static final int FLAG_ALLOW_CACHING_UNKNOWN_LENGTH = 1 << 1;
|
public static final int FLAG_ALLOW_CACHING_UNKNOWN_LENGTH = 1 << 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user