Refactor #6.HLS.3
- Pull loading of the initial manifest up to HlsSampleSource. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=123305312
This commit is contained in:
parent
e74fc80aab
commit
1ea149a4d2
@ -36,7 +36,6 @@ import com.google.android.exoplayer.hls.playlist.Variant;
|
|||||||
import com.google.android.exoplayer.upstream.DataSource;
|
import com.google.android.exoplayer.upstream.DataSource;
|
||||||
import com.google.android.exoplayer.upstream.DataSpec;
|
import com.google.android.exoplayer.upstream.DataSpec;
|
||||||
import com.google.android.exoplayer.upstream.HttpDataSource.InvalidResponseCodeException;
|
import com.google.android.exoplayer.upstream.HttpDataSource.InvalidResponseCodeException;
|
||||||
import com.google.android.exoplayer.util.ManifestFetcher;
|
|
||||||
import com.google.android.exoplayer.util.MimeTypes;
|
import com.google.android.exoplayer.util.MimeTypes;
|
||||||
import com.google.android.exoplayer.util.UriUtil;
|
import com.google.android.exoplayer.util.UriUtil;
|
||||||
import com.google.android.exoplayer.util.Util;
|
import com.google.android.exoplayer.util.Util;
|
||||||
@ -51,7 +50,6 @@ import java.io.IOException;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -72,7 +70,6 @@ public class HlsChunkSource {
|
|||||||
private static final String VTT_FILE_EXTENSION = ".vtt";
|
private static final String VTT_FILE_EXTENSION = ".vtt";
|
||||||
private static final String WEBVTT_FILE_EXTENSION = ".webvtt";
|
private static final String WEBVTT_FILE_EXTENSION = ".webvtt";
|
||||||
|
|
||||||
private final ManifestFetcher<HlsPlaylist> manifestFetcher;
|
|
||||||
private final int type;
|
private final int type;
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final FormatEvaluator adaptiveFormatEvaluator;
|
private final FormatEvaluator adaptiveFormatEvaluator;
|
||||||
@ -84,8 +81,9 @@ public class HlsChunkSource {
|
|||||||
private boolean live;
|
private boolean live;
|
||||||
private long durationUs;
|
private long durationUs;
|
||||||
private IOException fatalError;
|
private IOException fatalError;
|
||||||
private HlsMasterPlaylist masterPlaylist;
|
|
||||||
private String baseUri;
|
private String baseUri;
|
||||||
|
private Format muxedAudioFormat;
|
||||||
|
private Format muxedCaptionFormat;
|
||||||
|
|
||||||
private Uri encryptionKeyUri;
|
private Uri encryptionKeyUri;
|
||||||
private byte[] encryptionKey;
|
private byte[] encryptionKey;
|
||||||
@ -103,7 +101,6 @@ public class HlsChunkSource {
|
|||||||
private boolean[] enabledVariantBlacklistFlags;
|
private boolean[] enabledVariantBlacklistFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param manifestFetcher A fetcher for the playlist.
|
|
||||||
* @param type The type of chunk provided by the source. One of {@link C#TRACK_TYPE_DEFAULT},
|
* @param type The type of chunk provided by the source. One of {@link C#TRACK_TYPE_DEFAULT},
|
||||||
* {@link C#TRACK_TYPE_AUDIO} and {@link C#TRACK_TYPE_TEXT}.
|
* {@link C#TRACK_TYPE_AUDIO} and {@link C#TRACK_TYPE_TEXT}.
|
||||||
* @param dataSource A {@link DataSource} suitable for loading the media data.
|
* @param dataSource A {@link DataSource} suitable for loading the media data.
|
||||||
@ -112,10 +109,9 @@ public class HlsChunkSource {
|
|||||||
* same provider.
|
* same provider.
|
||||||
* @param adaptiveFormatEvaluator For adaptive tracks, selects from the available formats.
|
* @param adaptiveFormatEvaluator For adaptive tracks, selects from the available formats.
|
||||||
*/
|
*/
|
||||||
public HlsChunkSource(ManifestFetcher<HlsPlaylist> manifestFetcher, int type,
|
public HlsChunkSource(int type, DataSource dataSource,
|
||||||
DataSource dataSource, PtsTimestampAdjusterProvider timestampAdjusterProvider,
|
PtsTimestampAdjusterProvider timestampAdjusterProvider,
|
||||||
FormatEvaluator adaptiveFormatEvaluator) {
|
FormatEvaluator adaptiveFormatEvaluator) {
|
||||||
this.manifestFetcher = manifestFetcher;
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.adaptiveFormatEvaluator = adaptiveFormatEvaluator;
|
this.adaptiveFormatEvaluator = adaptiveFormatEvaluator;
|
||||||
@ -148,38 +144,14 @@ public class HlsChunkSource {
|
|||||||
/**
|
/**
|
||||||
* Prepares the source.
|
* Prepares the source.
|
||||||
*
|
*
|
||||||
* @return True if the source was prepared, false otherwise.
|
* @param playlist A {@link HlsPlaylist}.
|
||||||
*/
|
*/
|
||||||
public boolean prepare() throws IOException {
|
public void prepare(HlsPlaylist playlist) {
|
||||||
if (masterPlaylist == null) {
|
processPlaylist(playlist);
|
||||||
HlsPlaylist playlist = manifestFetcher.getManifest();
|
if (variants.length > 0) {
|
||||||
if (playlist == null) {
|
// Select the first variant listed in the master playlist.
|
||||||
manifestFetcher.maybeThrowError();
|
selectTracks(new int[] {0});
|
||||||
manifestFetcher.requestRefresh();
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
baseUri = playlist.baseUri;
|
|
||||||
if (playlist.type == HlsPlaylist.TYPE_MASTER) {
|
|
||||||
masterPlaylist = (HlsMasterPlaylist) playlist;
|
|
||||||
} else {
|
|
||||||
Format format = Format.createContainerFormat("0", MimeTypes.APPLICATION_M3U8, null,
|
|
||||||
Format.NO_VALUE);
|
|
||||||
List<Variant> variants = new ArrayList<>();
|
|
||||||
variants.add(new Variant(baseUri, format, null));
|
|
||||||
masterPlaylist = new HlsMasterPlaylist(baseUri, variants,
|
|
||||||
Collections.<Variant>emptyList(), Collections.<Variant>emptyList(), null, null);
|
|
||||||
}
|
|
||||||
processMasterPlaylist(masterPlaylist);
|
|
||||||
if (variants.length > 0) {
|
|
||||||
if (playlist.type == HlsPlaylist.TYPE_MEDIA) {
|
|
||||||
setMediaPlaylist(0, (HlsMediaPlaylist) playlist);
|
|
||||||
}
|
|
||||||
// Select the first variant listed in the master playlist.
|
|
||||||
selectTracks(new int[] {0});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -235,7 +207,7 @@ public class HlsChunkSource {
|
|||||||
* @return The format of the audio muxed into variants, or null if unknown.
|
* @return The format of the audio muxed into variants, or null if unknown.
|
||||||
*/
|
*/
|
||||||
public Format getMuxedAudioFormat() {
|
public Format getMuxedAudioFormat() {
|
||||||
return masterPlaylist.muxedAudioFormat;
|
return muxedAudioFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,7 +218,7 @@ public class HlsChunkSource {
|
|||||||
* @return The format of the captions muxed into variants, or null if unknown.
|
* @return The format of the captions muxed into variants, or null if unknown.
|
||||||
*/
|
*/
|
||||||
public Format getMuxedCaptionFormat() {
|
public Format getMuxedCaptionFormat() {
|
||||||
return masterPlaylist.muxedCaptionFormat;
|
return muxedCaptionFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -521,9 +493,33 @@ public class HlsChunkSource {
|
|||||||
|
|
||||||
// Private methods.
|
// Private methods.
|
||||||
|
|
||||||
private void processMasterPlaylist(HlsMasterPlaylist playlist) {
|
private void processPlaylist(HlsPlaylist playlist) {
|
||||||
|
baseUri = playlist.baseUri;
|
||||||
|
|
||||||
|
if (playlist instanceof HlsMediaPlaylist) {
|
||||||
|
if (type == C.TRACK_TYPE_TEXT || type == C.TRACK_TYPE_AUDIO) {
|
||||||
|
variants = new Variant[0];
|
||||||
|
variantPlaylists = new HlsMediaPlaylist[variants.length];
|
||||||
|
variantLastPlaylistLoadTimesMs = new long[variants.length];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// type == C.TRACK_TYPE_DEFAULT
|
||||||
|
Format format = Format.createContainerFormat("0", MimeTypes.APPLICATION_M3U8, null,
|
||||||
|
Format.NO_VALUE);
|
||||||
|
variants = new Variant[] {new Variant(baseUri, format, null)};
|
||||||
|
variantPlaylists = new HlsMediaPlaylist[variants.length];
|
||||||
|
variantLastPlaylistLoadTimesMs = new long[variants.length];
|
||||||
|
setMediaPlaylist(0, (HlsMediaPlaylist) playlist);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
|
||||||
|
muxedAudioFormat = masterPlaylist.muxedAudioFormat;
|
||||||
|
muxedCaptionFormat = masterPlaylist.muxedCaptionFormat;
|
||||||
if (type == C.TRACK_TYPE_TEXT || type == C.TRACK_TYPE_AUDIO) {
|
if (type == C.TRACK_TYPE_TEXT || type == C.TRACK_TYPE_AUDIO) {
|
||||||
List<Variant> variantList = type == C.TRACK_TYPE_AUDIO ? playlist.audios : playlist.subtitles;
|
List<Variant> variantList = type == C.TRACK_TYPE_AUDIO ? masterPlaylist.audios
|
||||||
|
: masterPlaylist.subtitles;
|
||||||
if (variantList != null && !variantList.isEmpty()) {
|
if (variantList != null && !variantList.isEmpty()) {
|
||||||
variants = new Variant[variantList.size()];
|
variants = new Variant[variantList.size()];
|
||||||
variantList.toArray(variants);
|
variantList.toArray(variants);
|
||||||
@ -535,8 +531,8 @@ public class HlsChunkSource {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type is TYPE_DEFAULT.
|
// type == C.TRACK_TYPE_DEFAULT
|
||||||
List<Variant> enabledVariantList = new ArrayList<>(playlist.variants);
|
List<Variant> enabledVariantList = new ArrayList<>(masterPlaylist.variants);
|
||||||
ArrayList<Variant> definiteVideoVariants = new ArrayList<>();
|
ArrayList<Variant> definiteVideoVariants = new ArrayList<>();
|
||||||
ArrayList<Variant> definiteAudioOnlyVariants = new ArrayList<>();
|
ArrayList<Variant> definiteAudioOnlyVariants = new ArrayList<>();
|
||||||
for (int i = 0; i < enabledVariantList.size(); i++) {
|
for (int i = 0; i < enabledVariantList.size(); i++) {
|
||||||
|
@ -48,7 +48,14 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public final class HlsSampleSource implements SampleSource {
|
public final class HlsSampleSource implements SampleSource {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum number of times to retry loading data prior to failing.
|
||||||
|
*/
|
||||||
|
// TODO: Use this for playlist loads as well.
|
||||||
|
private static final int MIN_LOADABLE_RETRY_COUNT = 3;
|
||||||
|
|
||||||
private final ManifestFetcher<HlsPlaylist> manifestFetcher;
|
private final ManifestFetcher<HlsPlaylist> manifestFetcher;
|
||||||
|
private final HlsChunkSource[] chunkSources;
|
||||||
private final HlsTrackStreamWrapper[] trackStreamWrappers;
|
private final HlsTrackStreamWrapper[] trackStreamWrappers;
|
||||||
private final IdentityHashMap<TrackStream, HlsTrackStreamWrapper> trackStreamSources;
|
private final IdentityHashMap<TrackStream, HlsTrackStreamWrapper> trackStreamSources;
|
||||||
private final int[] selectedTrackCounts;
|
private final int[] selectedTrackCounts;
|
||||||
@ -56,6 +63,7 @@ public final class HlsSampleSource implements SampleSource {
|
|||||||
private boolean prepared;
|
private boolean prepared;
|
||||||
private boolean seenFirstTrackSelection;
|
private boolean seenFirstTrackSelection;
|
||||||
private long durationUs;
|
private long durationUs;
|
||||||
|
private HlsPlaylist playlist;
|
||||||
private TrackGroupArray trackGroups;
|
private TrackGroupArray trackGroups;
|
||||||
private HlsTrackStreamWrapper[] enabledTrackStreamWrappers;
|
private HlsTrackStreamWrapper[] enabledTrackStreamWrappers;
|
||||||
|
|
||||||
@ -71,27 +79,30 @@ public final class HlsSampleSource implements SampleSource {
|
|||||||
PtsTimestampAdjusterProvider timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
|
PtsTimestampAdjusterProvider timestampAdjusterProvider = new PtsTimestampAdjusterProvider();
|
||||||
|
|
||||||
DataSource defaultDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
DataSource defaultDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||||
HlsChunkSource defaultChunkSource = new HlsChunkSource(manifestFetcher, C.TRACK_TYPE_DEFAULT,
|
HlsChunkSource defaultChunkSource = new HlsChunkSource(C.TRACK_TYPE_DEFAULT,
|
||||||
defaultDataSource, timestampAdjusterProvider,
|
defaultDataSource, timestampAdjusterProvider,
|
||||||
new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter));
|
new FormatEvaluator.AdaptiveEvaluator(bandwidthMeter));
|
||||||
HlsTrackStreamWrapper defaultTrackStreamWrapper = new HlsTrackStreamWrapper(defaultChunkSource,
|
HlsTrackStreamWrapper defaultTrackStreamWrapper = new HlsTrackStreamWrapper(defaultChunkSource,
|
||||||
loadControl, C.DEFAULT_MUXED_BUFFER_SIZE, eventHandler, eventListener, C.TRACK_TYPE_VIDEO);
|
loadControl, C.DEFAULT_MUXED_BUFFER_SIZE, eventHandler, eventListener, C.TRACK_TYPE_VIDEO,
|
||||||
|
MIN_LOADABLE_RETRY_COUNT);
|
||||||
|
|
||||||
DataSource audioDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
DataSource audioDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||||
HlsChunkSource audioChunkSource = new HlsChunkSource(manifestFetcher, C.TRACK_TYPE_AUDIO,
|
HlsChunkSource audioChunkSource = new HlsChunkSource(C.TRACK_TYPE_AUDIO,
|
||||||
audioDataSource, timestampAdjusterProvider, null);
|
audioDataSource, timestampAdjusterProvider, null);
|
||||||
HlsTrackStreamWrapper audioTrackStreamWrapper = new HlsTrackStreamWrapper(audioChunkSource,
|
HlsTrackStreamWrapper audioTrackStreamWrapper = new HlsTrackStreamWrapper(audioChunkSource,
|
||||||
loadControl, C.DEFAULT_AUDIO_BUFFER_SIZE, eventHandler, eventListener, C.TRACK_TYPE_AUDIO);
|
loadControl, C.DEFAULT_AUDIO_BUFFER_SIZE, eventHandler, eventListener, C.TRACK_TYPE_AUDIO,
|
||||||
|
MIN_LOADABLE_RETRY_COUNT);
|
||||||
|
|
||||||
DataSource subtitleDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
DataSource textDataSource = dataSourceFactory.createDataSource(bandwidthMeter);
|
||||||
HlsChunkSource subtitleChunkSource = new HlsChunkSource(manifestFetcher, C.TRACK_TYPE_TEXT,
|
HlsChunkSource textChunkSource = new HlsChunkSource(C.TRACK_TYPE_TEXT, textDataSource,
|
||||||
subtitleDataSource, timestampAdjusterProvider, null);
|
timestampAdjusterProvider, null);
|
||||||
HlsTrackStreamWrapper subtitleTrackStreamWrapper = new HlsTrackStreamWrapper(
|
HlsTrackStreamWrapper textTrackStreamWrapper = new HlsTrackStreamWrapper(
|
||||||
subtitleChunkSource, loadControl, C.DEFAULT_TEXT_BUFFER_SIZE, eventHandler, eventListener,
|
textChunkSource, loadControl, C.DEFAULT_TEXT_BUFFER_SIZE, eventHandler, eventListener,
|
||||||
C.TRACK_TYPE_TEXT);
|
C.TRACK_TYPE_TEXT, MIN_LOADABLE_RETRY_COUNT);
|
||||||
|
|
||||||
|
chunkSources = new HlsChunkSource[] {defaultChunkSource, audioChunkSource, textChunkSource};
|
||||||
trackStreamWrappers = new HlsTrackStreamWrapper[] {defaultTrackStreamWrapper,
|
trackStreamWrappers = new HlsTrackStreamWrapper[] {defaultTrackStreamWrapper,
|
||||||
audioTrackStreamWrapper, subtitleTrackStreamWrapper};
|
audioTrackStreamWrapper, textTrackStreamWrapper};
|
||||||
selectedTrackCounts = new int[trackStreamWrappers.length];
|
selectedTrackCounts = new int[trackStreamWrappers.length];
|
||||||
trackStreamSources = new IdentityHashMap<>();
|
trackStreamSources = new IdentityHashMap<>();
|
||||||
}
|
}
|
||||||
@ -101,6 +112,19 @@ public final class HlsSampleSource implements SampleSource {
|
|||||||
if (prepared) {
|
if (prepared) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (playlist == null) {
|
||||||
|
playlist = manifestFetcher.getManifest();
|
||||||
|
if (playlist == null) {
|
||||||
|
manifestFetcher.maybeThrowError();
|
||||||
|
manifestFetcher.requestRefresh();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (HlsChunkSource chunkSource : chunkSources) {
|
||||||
|
chunkSource.prepare(playlist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean trackStreamWrappersPrepared = true;
|
boolean trackStreamWrappersPrepared = true;
|
||||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||||
trackStreamWrappersPrepared &= trackStreamWrapper.prepare(positionUs);
|
trackStreamWrappersPrepared &= trackStreamWrapper.prepare(positionUs);
|
||||||
@ -108,6 +132,7 @@ public final class HlsSampleSource implements SampleSource {
|
|||||||
if (!trackStreamWrappersPrepared) {
|
if (!trackStreamWrappersPrepared) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
durationUs = 0;
|
durationUs = 0;
|
||||||
int totalTrackGroupCount = 0;
|
int totalTrackGroupCount = 0;
|
||||||
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
for (HlsTrackStreamWrapper trackStreamWrapper : trackStreamWrappers) {
|
||||||
|
@ -49,11 +49,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
/* package */ final class HlsTrackStreamWrapper implements Loader.Callback<Chunk>, ExtractorOutput {
|
/* package */ final class HlsTrackStreamWrapper implements Loader.Callback<Chunk>, ExtractorOutput {
|
||||||
|
|
||||||
/**
|
|
||||||
* The default minimum number of times to retry loading data prior to failing.
|
|
||||||
*/
|
|
||||||
public static final int DEFAULT_MIN_LOADABLE_RETRY_COUNT = 3;
|
|
||||||
|
|
||||||
private static final int PRIMARY_TYPE_NONE = 0;
|
private static final int PRIMARY_TYPE_NONE = 0;
|
||||||
private static final int PRIMARY_TYPE_TEXT = 1;
|
private static final int PRIMARY_TYPE_TEXT = 1;
|
||||||
private static final int PRIMARY_TYPE_AUDIO = 2;
|
private static final int PRIMARY_TYPE_AUDIO = 2;
|
||||||
@ -89,32 +84,6 @@ import java.util.List;
|
|||||||
|
|
||||||
private boolean loadingFinished;
|
private boolean loadingFinished;
|
||||||
|
|
||||||
/**
|
|
||||||
* @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
|
|
||||||
* @param loadControl Controls when the source is permitted to load data.
|
|
||||||
* @param bufferSizeContribution The contribution of this source to the media buffer, in bytes.
|
|
||||||
*/
|
|
||||||
public HlsTrackStreamWrapper(HlsChunkSource chunkSource, LoadControl loadControl,
|
|
||||||
int bufferSizeContribution) {
|
|
||||||
this(chunkSource, loadControl, bufferSizeContribution, null, null, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
|
|
||||||
* @param loadControl Controls when the source is permitted to load data.
|
|
||||||
* @param bufferSizeContribution The contribution of this source to the media buffer, in bytes.
|
|
||||||
* @param eventHandler A handler to use when delivering events to {@code eventListener}. May be
|
|
||||||
* null if delivery of events is not required.
|
|
||||||
* @param eventListener A listener of events. May be null if delivery of events is not required.
|
|
||||||
* @param eventSourceId An identifier that gets passed to {@code eventListener} methods.
|
|
||||||
*/
|
|
||||||
public HlsTrackStreamWrapper(HlsChunkSource chunkSource, LoadControl loadControl,
|
|
||||||
int bufferSizeContribution, Handler eventHandler,
|
|
||||||
ChunkTrackStreamEventListener eventListener, int eventSourceId) {
|
|
||||||
this(chunkSource, loadControl, bufferSizeContribution, eventHandler, eventListener,
|
|
||||||
eventSourceId, DEFAULT_MIN_LOADABLE_RETRY_COUNT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
|
* @param chunkSource A {@link HlsChunkSource} from which chunks to load are obtained.
|
||||||
* @param loadControl Controls when the source is permitted to load data.
|
* @param loadControl Controls when the source is permitted to load data.
|
||||||
@ -144,9 +113,6 @@ import java.util.List;
|
|||||||
if (prepared) {
|
if (prepared) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!chunkSource.prepare()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (chunkSource.getTrackCount() == 0) {
|
if (chunkSource.getTrackCount() == 0) {
|
||||||
trackGroups = new TrackGroupArray();
|
trackGroups = new TrackGroupArray();
|
||||||
prepared = true;
|
prepared = true;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user