Commit 65c44453 by tonihei Committed by Ian Baker

Rename HLS master playlist to multivariant playlist

The spec renamed this type of playlist in the latest revision
to use a more inclusive technical term (see
https://datatracker.ietf.org/doc/html/draft-pantos-hls-rfc8216bis-10)

PiperOrigin-RevId: 417560274
parent e3548f26
Showing with 202 additions and 161 deletions
......@@ -237,11 +237,11 @@
"uri": "https://devstreaming-cdn.apple.com/videos/streaming/examples/bipbop_16x9/bipbop_16x9_variant.m3u8"
},
{
"name": "Apple master playlist advanced (TS)",
"name": "Apple multivariant playlist advanced (TS)",
"uri": "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_ts/master.m3u8"
},
{
"name": "Apple master playlist advanced (FMP4)",
"name": "Apple multivariant playlist advanced (FMP4)",
"uri": "https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8"
},
{
......
......@@ -90,7 +90,7 @@ For more information, see the
A file that defines the structure and location of media in
[adaptive streaming](#adaptive-streaming) protocols. Examples include
[DASH](#dash) [MPD](#mpd) files, [HLS](#hls) master playlist files and
[DASH](#dash) [MPD](#mpd) files, [HLS](#hls) multivariant playlist files and
[Smooth Streaming](#smooth-streaming) manifest files. Not to be confused with an
AndroidManifest XML file.
......
......@@ -30,8 +30,8 @@ If your URI doesn't end with `.m3u8`, you can pass `MimeTypes.APPLICATION_M3U8`
to `setMimeType` of `MediaItem.Builder` to explicitly indicate the type of the
content.
The URI of the media item may point to either a media playlist or a master
playlist. If the URI points to a master playlist that declares multiple
The URI of the media item may point to either a media playlist or a multivariant
playlist. If the URI points to a multivariant playlist that declares multiple
`#EXT-X-STREAM-INF` tags then ExoPlayer will automatically adapt between
variants, taking into account both available bandwidth and device capabilities.
......@@ -89,17 +89,18 @@ app's needs. See the [Customization page][] for examples.
### Disabling chunkless preparation ###
By default, ExoPlayer will use chunkless preparation. This means that ExoPlayer
will only use the information in the master playlist to prepare the stream,
which works if the `#EXT-X-STREAM-INF` tags contain the `CODECS` attribute.
will only use the information in the multivariant playlist to prepare the
stream, which works if the `#EXT-X-STREAM-INF` tags contain the `CODECS`
attribute.
You may need to disable this feature if your media segments contain muxed
closed-caption tracks that are not declared in the master playlist with a
closed-caption tracks that are not declared in the multivariant playlist with a
`#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS` tag. Otherwise, these closed-caption tracks
won't be detected and played. You can disable chunkless preparation in the
`HlsMediaSource.Factory` as shown in the following snippet. Note that this
will increase start up time as ExoPlayer needs to download a media segment to
discover these additional tracks and it is preferable to declare the
closed-caption tracks in the master playlist instead.
closed-caption tracks in the multivariant playlist instead.
~~~
HlsMediaSource hlsMediaSource =
new HlsMediaSource.Factory(dataSourceFactory)
......@@ -119,7 +120,7 @@ ExoPlayer][] for a full explanation. The main points are:
segments.
* Use the `#EXT-X-INDEPENDENT-SEGMENTS` tag.
* Prefer demuxed streams, as opposed to files that include both video and audio.
* Include all information you can in the Master Playlist.
* Include all information you can in the Multivariant Playlist.
The following guidelines apply specifically for live streams:
......
......@@ -631,7 +631,8 @@ public final class Format implements Bundleable {
* <ul>
* <li>DASH representations: Always {@link Format#NO_VALUE}.
* <li>HLS variants: The {@code AVERAGE-BANDWIDTH} attribute defined on the corresponding {@code
* EXT-X-STREAM-INF} tag in the master playlist, or {@link Format#NO_VALUE} if not present.
* EXT-X-STREAM-INF} tag in the multivariant playlist, or {@link Format#NO_VALUE} if not
* present.
* <li>SmoothStreaming track elements: The {@code Bitrate} attribute defined on the
* corresponding {@code TrackElement} in the manifest, or {@link Format#NO_VALUE} if not
* present.
......
......@@ -40,20 +40,20 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
private static final PositionHolder POSITION_HOLDER = new PositionHolder();
@VisibleForTesting /* package */ final Extractor extractor;
private final Format masterPlaylistFormat;
private final Format multivariantPlaylistFormat;
private final TimestampAdjuster timestampAdjuster;
/**
* Creates a new instance.
*
* @param extractor The underlying {@link Extractor}.
* @param masterPlaylistFormat The {@link Format} obtained from the master playlist.
* @param multivariantPlaylistFormat The {@link Format} obtained from the multivariant playlist.
* @param timestampAdjuster A {@link TimestampAdjuster} to adjust sample timestamps.
*/
public BundledHlsMediaChunkExtractor(
Extractor extractor, Format masterPlaylistFormat, TimestampAdjuster timestampAdjuster) {
Extractor extractor, Format multivariantPlaylistFormat, TimestampAdjuster timestampAdjuster) {
this.extractor = extractor;
this.masterPlaylistFormat = masterPlaylistFormat;
this.multivariantPlaylistFormat = multivariantPlaylistFormat;
this.timestampAdjuster = timestampAdjuster;
}
......@@ -85,7 +85,8 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
Assertions.checkState(!isReusable());
Extractor newExtractorInstance;
if (extractor instanceof WebvttExtractor) {
newExtractorInstance = new WebvttExtractor(masterPlaylistFormat.language, timestampAdjuster);
newExtractorInstance =
new WebvttExtractor(multivariantPlaylistFormat.language, timestampAdjuster);
} else if (extractor instanceof AdtsExtractor) {
newExtractorInstance = new AdtsExtractor();
} else if (extractor instanceof Ac3Extractor) {
......@@ -99,7 +100,7 @@ public final class BundledHlsMediaChunkExtractor implements HlsMediaChunkExtract
"Unexpected extractor type for recreation: " + extractor.getClass().getSimpleName());
}
return new BundledHlsMediaChunkExtractor(
newExtractorInstance, masterPlaylistFormat, timestampAdjuster);
newExtractorInstance, multivariantPlaylistFormat, timestampAdjuster);
}
@Override
......
......@@ -79,8 +79,9 @@ public final class DefaultHlsExtractorFactory implements HlsExtractorFactory {
* DefaultTsPayloadReaderFactory} instances. Other flags may be added on top of {@code
* payloadReaderFactoryFlags} when creating {@link DefaultTsPayloadReaderFactory}.
* @param exposeCea608WhenMissingDeclarations Whether created {@link TsExtractor} instances should
* expose a CEA-608 track should the master playlist contain no Closed Captions declarations.
* If the master playlist contains any Closed Captions declarations, this flag is ignored.
* expose a CEA-608 track should the multivariant playlist contain no Closed Captions
* declarations. If the multivariant playlist contains any Closed Captions declarations, this
* flag is ignored.
*/
public DefaultHlsExtractorFactory(
int payloadReaderFactoryFlags, boolean exposeCea608WhenMissingDeclarations) {
......
......@@ -154,7 +154,7 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
* {@link HlsChunkSource}s are used for a single playback, they should all share the same
* provider.
* @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption
* information is available in the master playlist.
* information is available in the multivariant playlist.
*/
public HlsChunkSource(
HlsExtractorFactory extractorFactory,
......@@ -877,8 +877,8 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public InitializationTrackSelection(TrackGroup group, int[] tracks) {
super(group, tracks);
// The initially selected index corresponds to the first EXT-X-STREAMINF tag in the master
// playlist.
// The initially selected index corresponds to the first EXT-X-STREAMINF tag in the
// multivariant playlist.
selectedIndex = indexOf(group.getFormat(tracks[0]));
}
......
......@@ -38,7 +38,7 @@ public interface HlsExtractorFactory {
* @param uri The URI of the media chunk.
* @param format A {@link Format} associated with the chunk to extract.
* @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption
* information is available in the master playlist.
* information is available in the multivariant playlist.
* @param timestampAdjuster Adjuster corresponding to the provided discontinuity sequence number.
* @param responseHeaders The HTTP response headers associated with the media segment or
* initialization section to extract.
......
......@@ -17,21 +17,42 @@ package com.google.android.exoplayer2.source.hls;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist;
/** Holds a master playlist along with a snapshot of one of its media playlists. */
/** Holds a multivariant playlist along with a snapshot of one of its media playlists. */
public final class HlsManifest {
/** The master playlist of an HLS stream. */
/** @deprecated Use {@link #multivariantPlaylist} instead. */
@Deprecated
@SuppressWarnings("deprecation") // Keeping deprecated field with deprecated class.
public final HlsMasterPlaylist masterPlaylist;
/** A snapshot of a media playlist referred to by {@link #masterPlaylist}. */
/** The multivariant playlist of an HLS stream. */
public final HlsMultivariantPlaylist multivariantPlaylist;
/** A snapshot of a media playlist referred to by {@link #multivariantPlaylist}. */
public final HlsMediaPlaylist mediaPlaylist;
/**
* @param masterPlaylist The master playlist.
* @param multivariantPlaylist The multivariant playlist.
* @param mediaPlaylist The media playlist.
*/
HlsManifest(HlsMasterPlaylist masterPlaylist, HlsMediaPlaylist mediaPlaylist) {
this.masterPlaylist = masterPlaylist;
@SuppressWarnings("deprecation") // Intentionally creating deprecated hlsMasterPlaylist field.
/* package */ HlsManifest(
HlsMultivariantPlaylist multivariantPlaylist, HlsMediaPlaylist mediaPlaylist) {
this.multivariantPlaylist = multivariantPlaylist;
this.mediaPlaylist = mediaPlaylist;
this.masterPlaylist =
new HlsMasterPlaylist(
multivariantPlaylist.baseUri,
multivariantPlaylist.tags,
multivariantPlaylist.variants,
multivariantPlaylist.videos,
multivariantPlaylist.audios,
multivariantPlaylist.subtitles,
multivariantPlaylist.closedCaptions,
multivariantPlaylist.muxedAudioFormat,
multivariantPlaylist.muxedCaptionFormats,
multivariantPlaylist.hasIndependentSegments,
multivariantPlaylist.variableDefinitions,
multivariantPlaylist.sessionKeyDrmInitData);
}
}
......@@ -64,7 +64,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* @param segmentBaseHolder The segment holder.
* @param playlistUrl The url of the playlist from which this chunk was obtained.
* @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption
* information is available in the master playlist.
* information is available in the multivariant playlist.
* @param trackSelectionReason See {@link #trackSelectionReason}.
* @param trackSelectionData See {@link #trackSelectionData}.
* @param isMasterTimestampSource True if the chunk can initialize the timestamp adjuster.
......
......@@ -238,7 +238,8 @@ public final class HlsMediaSource extends BaseMediaSource
/**
* Sets whether chunkless preparation is allowed. If true, preparation without chunk downloads
* will be enabled for streams that provide sufficient information in their master playlist.
* will be enabled for streams that provide sufficient information in their multivariant
* playlist.
*
* @param allowChunklessPreparation Whether chunkless preparation is allowed.
* @return This factory, for convenience.
......@@ -273,10 +274,10 @@ public final class HlsMediaSource extends BaseMediaSource
}
/**
* Sets whether to use #EXT-X-SESSION-KEY tags provided in the master playlist. If enabled, it's
* assumed that any single session key declared in the master playlist can be used to obtain all
* of the keys required for playback. For media where this is not true, this option should not
* be enabled.
* Sets whether to use #EXT-X-SESSION-KEY tags provided in the multivariant playlist. If
* enabled, it's assumed that any single session key declared in the multivariant playlist can
* be used to obtain all of the keys required for playback. For media where this is not true,
* this option should not be enabled.
*
* @param useSessionKeys Whether to use #EXT-X-SESSION-KEY tags.
* @return This factory, for convenience.
......@@ -524,9 +525,9 @@ public final class HlsMediaSource extends BaseMediaSource
|| mediaPlaylist.playlistType == HlsMediaPlaylist.PLAYLIST_TYPE_VOD
? windowStartTimeMs
: C.TIME_UNSET;
// The master playlist is non-null because the first playlist has been fetched by now.
// The multivariant playlist is non-null because the first playlist has been fetched by now.
HlsManifest manifest =
new HlsManifest(checkNotNull(playlistTracker.getMasterPlaylist()), mediaPlaylist);
new HlsManifest(checkNotNull(playlistTracker.getMultivariantPlaylist()), mediaPlaylist);
SinglePeriodTimeline timeline =
playlistTracker.isLive()
? createTimelineForLive(
......
......@@ -103,7 +103,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* Called when the wrapper has been prepared.
*
* <p>Note: This method will be called on a later handler loop than the one on which either
* {@link #prepareWithMasterPlaylistInfo} or {@link #continuePreparing} are invoked.
* {@link #prepareWithMultivariantPlaylistInfo} or {@link #continuePreparing} are invoked.
*/
void onPrepared();
......@@ -197,7 +197,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* stream's {@link DrmInitData} will be overridden.
* @param allocator An {@link Allocator} from which to obtain media buffer allocations.
* @param positionUs The position from which to start loading media.
* @param muxedAudioFormat Optional muxed audio {@link Format} as defined by the master playlist.
* @param muxedAudioFormat Optional muxed audio {@link Format} as defined by the multivariant
* playlist.
* @param drmSessionManager The {@link DrmSessionManager} to acquire {@link DrmSession
* DrmSessions} with.
* @param drmEventDispatcher A dispatcher to notify of {@link DrmSessionEventListener} events.
......@@ -261,7 +262,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
/**
* Prepares the sample stream wrapper with master playlist information.
* Prepares the sample stream wrapper with multivariant playlist information.
*
* @param trackGroups The {@link TrackGroup TrackGroups} to expose through {@link
* #getTrackGroups()}.
......@@ -269,7 +270,7 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* @param optionalTrackGroupsIndices The indices of any {@code trackGroups} that should not
* trigger a failure if not found in the media playlist's segments.
*/
public void prepareWithMasterPlaylistInfo(
public void prepareWithMultivariantPlaylistInfo(
TrackGroup[] trackGroups, int primaryTrackGroupIndex, int... optionalTrackGroupsIndices) {
this.trackGroups = createTrackGroupArrayWithDrmInfo(trackGroups);
optionalTrackGroups = new HashSet<>();
......@@ -1298,8 +1299,8 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
}
if (trackGroups != null) {
// The track groups were created with master playlist information. They only need to be mapped
// to a sample queue.
// The track groups were created with multivariant playlist information. They only need to be
// mapped to a sample queue.
mapSampleQueuesToMatchTrackGroups();
} else {
// Tracks are created using media segment information.
......@@ -1334,18 +1335,18 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
* Builds tracks that are exposed by this {@link HlsSampleStreamWrapper} instance, as well as
* internal data-structures required for operation.
*
* <p>Tracks in HLS are complicated. A HLS master playlist contains a number of "variants". Each
* variant stream typically contains muxed video, audio and (possibly) additional audio, metadata
* and caption tracks. We wish to allow the user to select between an adaptive track that spans
* all variants, as well as each individual variant. If multiple audio tracks are present within
* each variant then we wish to allow the user to select between those also.
* <p>Tracks in HLS are complicated. A HLS multivariant playlist contains a number of "variants".
* Each variant stream typically contains muxed video, audio and (possibly) additional audio,
* metadata and caption tracks. We wish to allow the user to select between an adaptive track that
* spans all variants, as well as each individual variant. If multiple audio tracks are present
* within each variant then we wish to allow the user to select between those also.
*
* <p>To do this, tracks are constructed as follows. The {@link HlsChunkSource} exposes (N+1)
* tracks, where N is the number of variants defined in the HLS master playlist. These consist of
* one adaptive track defined to span all variants and a track for each individual variant. The
* adaptive track is initially selected. The extractor is then prepared to discover the tracks
* inside of each variant stream. The two sets of tracks are then combined by this method to
* create a third set, which is the set exposed by this {@link HlsSampleStreamWrapper}:
* tracks, where N is the number of variants defined in the HLS multivariant playlist. These
* consist of one adaptive track defined to span all variants and a track for each individual
* variant. The adaptive track is initially selected. The extractor is then prepared to discover
* the tracks inside of each variant stream. The two sets of tracks are then combined by this
* method to create a third set, which is the set exposed by this {@link HlsSampleStreamWrapper}:
*
* <ul>
* <li>The extractor tracks are inspected to infer a "primary" track type. If a video track is
......@@ -1518,14 +1519,14 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull;
}
/**
* Derives a track sample format from the corresponding format in the master playlist, and a
* Derives a track sample format from the corresponding format in the multivariant playlist, and a
* sample format that may have been obtained from a chunk belonging to a different track in the
* same track group.
*
* <p>Note: Since the sample format may have been obtained from a chunk belonging to a different
* track, it should not be used as a source for data that may vary between tracks.
*
* @param playlistFormat The format information obtained from the master playlist.
* @param playlistFormat The format information obtained from the multivariant playlist.
* @param sampleFormat The format information obtained from samples within a chunk. The chunk may
* belong to a different track in the same track group.
* @param propagateBitrates Whether the bitrates from the playlist format should be included in
......
......@@ -19,8 +19,8 @@ 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.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
import com.google.android.exoplayer2.upstream.DataSource;
......@@ -45,14 +45,14 @@ import java.util.concurrent.Executor;
* new CacheDataSource.Factory()
* .setCache(cache)
* .setUpstreamDataSourceFactory(new DefaultHttpDataSource.Factory());
* // Create a downloader for the first variant in a master playlist.
* // Create a downloader for the first variant in a multivariant playlist.
* HlsDownloader hlsDownloader =
* new HlsDownloader(
* new MediaItem.Builder()
* .setUri(playlistUri)
* .setStreamKeys(
* Collections.singletonList(
* new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, 0)))
* new StreamKey(HlsMultivariantPlaylist.GROUP_INDEX_VARIANT, 0)))
* .build(),
* Collections.singletonList();
* // Perform the download.
......@@ -113,9 +113,9 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
protected List<Segment> getSegments(DataSource dataSource, HlsPlaylist playlist, boolean removing)
throws IOException, InterruptedException {
ArrayList<DataSpec> mediaPlaylistDataSpecs = new ArrayList<>();
if (playlist instanceof HlsMasterPlaylist) {
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
addMediaPlaylistDataSpecs(masterPlaylist.mediaPlaylistUrls, mediaPlaylistDataSpecs);
if (playlist instanceof HlsMultivariantPlaylist) {
HlsMultivariantPlaylist multivariantPlaylist = (HlsMultivariantPlaylist) playlist;
addMediaPlaylistDataSpecs(multivariantPlaylist.mediaPlaylistUrls, mediaPlaylistDataSpecs);
} else {
mediaPlaylistDataSpecs.add(
SegmentDownloader.getCompressibleDataSpec(Uri.parse(playlist.baseUri)));
......
......@@ -28,7 +28,8 @@ public final class DefaultHlsPlaylistParserFactory implements HlsPlaylistParserF
@Override
public ParsingLoadable.Parser<HlsPlaylist> createPlaylistParser(
HlsMasterPlaylist masterPlaylist, @Nullable HlsMediaPlaylist previousMediaPlaylist) {
return new HlsPlaylistParser(masterPlaylist, previousMediaPlaylist);
HlsMultivariantPlaylist multivariantPlaylist,
@Nullable HlsMediaPlaylist previousMediaPlaylist) {
return new HlsPlaylistParser(multivariantPlaylist, previousMediaPlaylist);
}
}
......@@ -29,10 +29,10 @@ import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Part;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.RenditionReport;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
......@@ -72,7 +72,7 @@ public final class DefaultHlsPlaylistTracker
@Nullable private Loader initialPlaylistLoader;
@Nullable private Handler playlistRefreshHandler;
@Nullable private PrimaryPlaylistListener primaryPlaylistListener;
@Nullable private HlsMasterPlaylist masterPlaylist;
@Nullable private HlsMultivariantPlaylist multivariantPlaylist;
@Nullable private Uri primaryMediaPlaylistUrl;
@Nullable private HlsMediaPlaylist primaryMediaPlaylistSnapshot;
private boolean isLive;
......@@ -131,30 +131,33 @@ public final class DefaultHlsPlaylistTracker
this.playlistRefreshHandler = Util.createHandlerForCurrentLooper();
this.eventDispatcher = eventDispatcher;
this.primaryPlaylistListener = primaryPlaylistListener;
ParsingLoadable<HlsPlaylist> masterPlaylistLoadable =
ParsingLoadable<HlsPlaylist> multivariantPlaylistLoadable =
new ParsingLoadable<>(
dataSourceFactory.createDataSource(C.DATA_TYPE_MANIFEST),
initialPlaylistUri,
C.DATA_TYPE_MANIFEST,
playlistParserFactory.createPlaylistParser());
Assertions.checkState(initialPlaylistLoader == null);
initialPlaylistLoader = new Loader("DefaultHlsPlaylistTracker:MasterPlaylist");
initialPlaylistLoader = new Loader("DefaultHlsPlaylistTracker:MultivariantPlaylist");
long elapsedRealtime =
initialPlaylistLoader.startLoading(
masterPlaylistLoadable,
multivariantPlaylistLoadable,
this,
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(masterPlaylistLoadable.type));
loadErrorHandlingPolicy.getMinimumLoadableRetryCount(
multivariantPlaylistLoadable.type));
eventDispatcher.loadStarted(
new LoadEventInfo(
masterPlaylistLoadable.loadTaskId, masterPlaylistLoadable.dataSpec, elapsedRealtime),
masterPlaylistLoadable.type);
multivariantPlaylistLoadable.loadTaskId,
multivariantPlaylistLoadable.dataSpec,
elapsedRealtime),
multivariantPlaylistLoadable.type);
}
@Override
public void stop() {
primaryMediaPlaylistUrl = null;
primaryMediaPlaylistSnapshot = null;
masterPlaylist = null;
multivariantPlaylist = null;
initialStartTimeUs = C.TIME_UNSET;
initialPlaylistLoader.release();
initialPlaylistLoader = null;
......@@ -179,8 +182,8 @@ public final class DefaultHlsPlaylistTracker
@Override
@Nullable
public HlsMasterPlaylist getMasterPlaylist() {
return masterPlaylist;
public HlsMultivariantPlaylist getMultivariantPlaylist() {
return multivariantPlaylist;
}
@Override
......@@ -243,18 +246,19 @@ public final class DefaultHlsPlaylistTracker
public void onLoadCompleted(
ParsingLoadable<HlsPlaylist> loadable, long elapsedRealtimeMs, long loadDurationMs) {
HlsPlaylist result = loadable.getResult();
HlsMasterPlaylist masterPlaylist;
HlsMultivariantPlaylist multivariantPlaylist;
boolean isMediaPlaylist = result instanceof HlsMediaPlaylist;
if (isMediaPlaylist) {
masterPlaylist = HlsMasterPlaylist.createSingleVariantMasterPlaylist(result.baseUri);
} else /* result instanceof HlsMasterPlaylist */ {
masterPlaylist = (HlsMasterPlaylist) result;
multivariantPlaylist =
HlsMultivariantPlaylist.createSingleVariantMultivariantPlaylist(result.baseUri);
} else /* result instanceof HlsMultivariantPlaylist */ {
multivariantPlaylist = (HlsMultivariantPlaylist) result;
}
this.masterPlaylist = masterPlaylist;
primaryMediaPlaylistUrl = masterPlaylist.variants.get(0).url;
this.multivariantPlaylist = multivariantPlaylist;
primaryMediaPlaylistUrl = multivariantPlaylist.variants.get(0).url;
// Add a temporary playlist listener for loading the first primary playlist.
listeners.add(new FirstPrimaryMediaPlaylistListener());
createBundles(masterPlaylist.mediaPlaylistUrls);
createBundles(multivariantPlaylist.mediaPlaylistUrls);
LoadEventInfo loadEventInfo =
new LoadEventInfo(
loadable.loadTaskId,
......@@ -327,7 +331,7 @@ public final class DefaultHlsPlaylistTracker
// Internal methods.
private boolean maybeSelectNewPrimaryUrl() {
List<Variant> variants = masterPlaylist.variants;
List<Variant> variants = multivariantPlaylist.variants;
int variantsSize = variants.size();
long currentTimeMs = SystemClock.elapsedRealtime();
for (int i = 0; i < variantsSize; i++) {
......@@ -382,9 +386,12 @@ public final class DefaultHlsPlaylistTracker
return newPrimaryPlaylistUri;
}
/** Returns whether any of the variants in the master playlist have the specified playlist URL. */
/**
* Returns whether any of the variants in the multivariant playlist have the specified playlist
* URL.
*/
private boolean isVariantUrl(Uri playlistUrl) {
List<Variant> variants = masterPlaylist.variants;
List<Variant> variants = multivariantPlaylist.variants;
for (int i = 0; i < variants.size(); i++) {
if (playlistUrl.equals(variants.get(i).url)) {
return true;
......@@ -687,7 +694,7 @@ public final class DefaultHlsPlaylistTracker
private void loadPlaylistImmediately(Uri playlistRequestUri) {
ParsingLoadable.Parser<HlsPlaylist> mediaPlaylistParser =
playlistParserFactory.createPlaylistParser(masterPlaylist, playlistSnapshot);
playlistParserFactory.createPlaylistParser(multivariantPlaylist, playlistSnapshot);
ParsingLoadable<HlsPlaylist> mediaPlaylistLoadable =
new ParsingLoadable<>(
mediaPlaylistDataSource,
......@@ -823,7 +830,7 @@ public final class DefaultHlsPlaylistTracker
if (primaryMediaPlaylistSnapshot == null) {
long nowMs = SystemClock.elapsedRealtime();
int variantExclusionCounter = 0;
List<Variant> variants = castNonNull(masterPlaylist).variants;
List<Variant> variants = castNonNull(multivariantPlaylist).variants;
for (int i = 0; i < variants.size(); i++) {
@Nullable
MediaPlaylistBundle mediaPlaylistBundle = playlistBundles.get(variants.get(i).url);
......@@ -835,7 +842,7 @@ public final class DefaultHlsPlaylistTracker
new LoadErrorHandlingPolicy.FallbackOptions(
/* numberOfLocations= */ 1,
/* numberOfExcludedLocations= */ 0,
/* numberOfTracks= */ masterPlaylist.variants.size(),
/* numberOfTracks= */ multivariantPlaylist.variants.size(),
/* numberOfExcludedTracks= */ variantExclusionCounter);
@Nullable
LoadErrorHandlingPolicy.FallbackSelection fallbackSelection =
......
......@@ -49,9 +49,10 @@ public final class FilteringHlsPlaylistParserFactory implements HlsPlaylistParse
@Override
public ParsingLoadable.Parser<HlsPlaylist> createPlaylistParser(
HlsMasterPlaylist masterPlaylist, @Nullable HlsMediaPlaylist previousMediaPlaylist) {
HlsMultivariantPlaylist multivariantPlaylist,
@Nullable HlsMediaPlaylist previousMediaPlaylist) {
return new FilteringManifestParser<>(
hlsPlaylistParserFactory.createPlaylistParser(masterPlaylist, previousMediaPlaylist),
hlsPlaylistParserFactory.createPlaylistParser(multivariantPlaylist, previousMediaPlaylist),
streamKeys);
}
}
......@@ -32,11 +32,11 @@ import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil;
import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.source.hls.HlsTrackMetadataEntry;
import com.google.android.exoplayer2.source.hls.HlsTrackMetadataEntry.VariantInfo;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Rendition;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Part;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.RenditionReport;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
......@@ -223,28 +223,30 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
private static final Pattern REGEX_VARIABLE_REFERENCE =
Pattern.compile("\\{\\$([a-zA-Z0-9\\-_]+)\\}");
private final HlsMasterPlaylist masterPlaylist;
private final HlsMultivariantPlaylist multivariantPlaylist;
@Nullable private final HlsMediaPlaylist previousMediaPlaylist;
/**
* Creates an instance where media playlists are parsed without inheriting attributes from a
* master playlist.
* multivariant playlist.
*/
public HlsPlaylistParser() {
this(HlsMasterPlaylist.EMPTY, /* previousMediaPlaylist= */ null);
this(HlsMultivariantPlaylist.EMPTY, /* previousMediaPlaylist= */ null);
}
/**
* Creates an instance where parsed media playlists inherit attributes from the given master
* playlist.
*
* @param masterPlaylist The master playlist from which media playlists will inherit attributes.
* @param multivariantPlaylist The multivariant playlist from which media playlists will inherit
* attributes.
* @param previousMediaPlaylist The previous media playlist from which the new media playlist may
* inherit skipped segments.
*/
public HlsPlaylistParser(
HlsMasterPlaylist masterPlaylist, @Nullable HlsMediaPlaylist previousMediaPlaylist) {
this.masterPlaylist = masterPlaylist;
HlsMultivariantPlaylist multivariantPlaylist,
@Nullable HlsMediaPlaylist previousMediaPlaylist) {
this.multivariantPlaylist = multivariantPlaylist;
this.previousMediaPlaylist = previousMediaPlaylist;
}
......@@ -264,7 +266,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
// Do nothing.
} else if (line.startsWith(TAG_STREAM_INF)) {
extraLines.add(line);
return parseMasterPlaylist(new LineIterator(extraLines, reader), uri.toString());
return parseMultivariantPlaylist(new LineIterator(extraLines, reader), uri.toString());
} else if (line.startsWith(TAG_TARGET_DURATION)
|| line.startsWith(TAG_MEDIA_SEQUENCE)
|| line.startsWith(TAG_MEDIA_DURATION)
......@@ -275,7 +277,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|| line.equals(TAG_ENDLIST)) {
extraLines.add(line);
return parseMediaPlaylist(
masterPlaylist,
multivariantPlaylist,
previousMediaPlaylist,
new LineIterator(extraLines, reader),
uri.toString());
......@@ -319,8 +321,8 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
return c;
}
private static HlsMasterPlaylist parseMasterPlaylist(LineIterator iterator, String baseUri)
throws IOException {
private static HlsMultivariantPlaylist parseMultivariantPlaylist(
LineIterator iterator, String baseUri) throws IOException {
HashMap<Uri, ArrayList<VariantInfo>> urlToVariantInfos = new HashMap<>();
HashMap<String, String> variableDefinitions = new HashMap<>();
ArrayList<Variant> variants = new ArrayList<>();
......@@ -578,7 +580,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
muxedCaptionFormats = Collections.emptyList();
}
return new HlsMasterPlaylist(
return new HlsMultivariantPlaylist(
baseUri,
tags,
deduplicatedVariants,
......@@ -627,7 +629,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
}
private static HlsMediaPlaylist parseMediaPlaylist(
HlsMasterPlaylist masterPlaylist,
HlsMultivariantPlaylist multivariantPlaylist,
@Nullable HlsMediaPlaylist previousMediaPlaylist,
LineIterator iterator,
String baseUri)
......@@ -638,7 +640,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
int version = 1; // Default version == 1.
long targetDurationUs = C.TIME_UNSET;
long partTargetDurationUs = C.TIME_UNSET;
boolean hasIndependentSegmentsTag = masterPlaylist.hasIndependentSegments;
boolean hasIndependentSegmentsTag = multivariantPlaylist.hasIndependentSegments;
boolean hasEndTag = false;
@Nullable Segment initializationSegment = null;
HashMap<String, String> variableDefinitions = new HashMap<>();
......@@ -748,11 +750,11 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
} else if (line.startsWith(TAG_DEFINE)) {
String importName = parseOptionalStringAttr(line, REGEX_IMPORT, variableDefinitions);
if (importName != null) {
String value = masterPlaylist.variableDefinitions.get(importName);
String value = multivariantPlaylist.variableDefinitions.get(importName);
if (value != null) {
variableDefinitions.put(importName, value);
} else {
// The master playlist does not declare the imported variable. Ignore.
// The multivariant playlist does not declare the imported variable. Ignore.
}
} else {
variableDefinitions.put(
......
......@@ -29,14 +29,16 @@ public interface HlsPlaylistParserFactory {
/**
* Returns a playlist parser for playlists that were referenced by the given {@link
* HlsMasterPlaylist}. Returned {@link HlsMediaPlaylist} instances may inherit attributes from
* {@code masterPlaylist}.
* HlsMultivariantPlaylist}. Returned {@link HlsMediaPlaylist} instances may inherit attributes
* from {@code multivariantPlaylist}.
*
* @param masterPlaylist The master playlist that referenced any parsed media playlists.
* @param multivariantPlaylist The multivariant playlist that referenced any parsed media
* playlists.
* @param previousMediaPlaylist The previous media playlist or null if there is no previous media
* playlist.
* @return A parser for HLS playlists.
*/
ParsingLoadable.Parser<HlsPlaylist> createPlaylistParser(
HlsMasterPlaylist masterPlaylist, @Nullable HlsMediaPlaylist previousMediaPlaylist);
HlsMultivariantPlaylist multivariantPlaylist,
@Nullable HlsMediaPlaylist previousMediaPlaylist);
}
......@@ -29,8 +29,8 @@ import java.io.IOException;
* <p>The playlist tracker is responsible for exposing the seeking window, which is defined by the
* segments that one of the playlists exposes. This playlist is called primary and needs to be
* periodically refreshed in the case of live streams. Note that the primary playlist is one of the
* media playlists while the master playlist is an optional kind of playlist defined by the HLS
* specification (RFC 8216).
* media playlists while the multivariant playlist is an optional kind of playlist defined by the
* HLS specification (RFC 8216).
*
* <p>Playlist loads might encounter errors. The tracker may choose to exclude them to ensure a
* primary playlist is always available.
......@@ -120,8 +120,8 @@ public interface HlsPlaylistTracker {
* <p>Must be called from the playback thread. A tracker may be restarted after a {@link #stop()}
* call.
*
* @param initialPlaylistUri Uri of the HLS stream. Can point to a media playlist or a master
* playlist.
* @param initialPlaylistUri Uri of the HLS stream. Can point to a media playlist or a
* multivariant playlist.
* @param eventDispatcher A dispatcher to notify of events.
* @param primaryPlaylistListener A callback for the primary playlist change events.
*/
......@@ -152,15 +152,15 @@ public interface HlsPlaylistTracker {
void removeListener(PlaylistEventListener listener);
/**
* Returns the master playlist.
* Returns the multivariant playlist.
*
* <p>If the uri passed to {@link #start} points to a media playlist, an {@link HlsMasterPlaylist}
* with a single variant for said media playlist is returned.
* <p>If the uri passed to {@link #start} points to a media playlist, an {@link
* HlsMultivariantPlaylist} with a single variant for said media playlist is returned.
*
* @return The master playlist. Null if the initial playlist has yet to be loaded.
* @return The multivariant playlist. Null if the initial playlist has yet to be loaded.
*/
@Nullable
HlsMasterPlaylist getMasterPlaylist();
HlsMultivariantPlaylist getMultivariantPlaylist();
/**
* Returns the most recent snapshot available of the playlist referenced by the provided {@link
......@@ -192,8 +192,8 @@ public interface HlsPlaylistTracker {
boolean isSnapshotValid(Uri url);
/**
* If the tracker is having trouble refreshing the master playlist or the primary playlist, this
* method throws the underlying error. Otherwise, does nothing.
* If the tracker is having trouble refreshing the multivariant playlist or the primary playlist,
* this method throws the underlying error. Otherwise, does nothing.
*
* @throws IOException The underlying error.
*/
......
......@@ -28,9 +28,9 @@ import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Rendition;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Rendition;
import com.google.android.exoplayer2.source.hls.playlist.HlsMultivariantPlaylist.Variant;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.testutil.MediaPeriodAsserts;
......@@ -51,9 +51,9 @@ import org.junit.runner.RunWith;
public final class HlsMediaPeriodTest {
@Test
public void getSteamKeys_isCompatibleWithHlsMasterPlaylistFilter() {
HlsMasterPlaylist testMasterPlaylist =
createMasterPlaylist(
public void getSteamKeys_isCompatibleWithHlsMultivariantPlaylistFilter() {
HlsMultivariantPlaylist testMultivariantPlaylist =
createMultivariantPlaylist(
/* variants= */ Arrays.asList(
createAudioOnlyVariant(/* peakBitrate= */ 10000),
createMuxedVideoAudioVariant(/* peakBitrate= */ 200000),
......@@ -76,7 +76,8 @@ public final class HlsMediaPeriodTest {
HlsDataSourceFactory mockDataSourceFactory = mock(HlsDataSourceFactory.class);
when(mockDataSourceFactory.createDataSource(anyInt())).thenReturn(mock(DataSource.class));
HlsPlaylistTracker mockPlaylistTracker = mock(HlsPlaylistTracker.class);
when(mockPlaylistTracker.getMasterPlaylist()).thenReturn((HlsMasterPlaylist) playlist);
when(mockPlaylistTracker.getMultivariantPlaylist())
.thenReturn((HlsMultivariantPlaylist) playlist);
MediaPeriodId mediaPeriodId = new MediaPeriodId(/* periodUid= */ new Object());
return new HlsMediaPeriod(
mock(HlsExtractorFactory.class),
......@@ -98,16 +99,16 @@ public final class HlsMediaPeriodTest {
};
MediaPeriodAsserts.assertGetStreamKeysAndManifestFilterIntegration(
mediaPeriodFactory, testMasterPlaylist);
mediaPeriodFactory, testMultivariantPlaylist);
}
private static HlsMasterPlaylist createMasterPlaylist(
private static HlsMultivariantPlaylist createMultivariantPlaylist(
List<Variant> variants,
List<Rendition> audios,
List<Rendition> subtitles,
Format muxedAudioFormat,
List<Format> muxedCaptionFormats) {
return new HlsMasterPlaylist(
return new HlsMultivariantPlaylist(
"http://baseUri",
/* tags= */ Collections.emptyList(),
variants,
......
......@@ -20,11 +20,11 @@ import com.google.common.base.Charsets;
/** Data for HLS downloading tests. */
/* package */ interface HlsDownloadTestData {
String MASTER_PLAYLIST_URI = "test.m3u8";
int MASTER_MEDIA_PLAYLIST_1_INDEX = 0;
int MASTER_MEDIA_PLAYLIST_2_INDEX = 1;
int MASTER_MEDIA_PLAYLIST_3_INDEX = 2;
int MASTER_MEDIA_PLAYLIST_0_INDEX = 3;
String MULTIVARIANT_PLAYLIST_URI = "test.m3u8";
int MULTIVARIANT_MEDIA_PLAYLIST_1_INDEX = 0;
int MULTIVARIANT_MEDIA_PLAYLIST_2_INDEX = 1;
int MULTIVARIANT_MEDIA_PLAYLIST_3_INDEX = 2;
int MULTIVARIANT_MEDIA_PLAYLIST_0_INDEX = 3;
String MEDIA_PLAYLIST_0_DIR = "gear0/";
String MEDIA_PLAYLIST_0_URI = MEDIA_PLAYLIST_0_DIR + "prog_index.m3u8";
......@@ -35,7 +35,7 @@ import com.google.common.base.Charsets;
String MEDIA_PLAYLIST_3_DIR = "gear3/";
String MEDIA_PLAYLIST_3_URI = MEDIA_PLAYLIST_3_DIR + "prog_index.m3u8";
byte[] MASTER_PLAYLIST_DATA =
byte[] MULTIVARIANT_PLAYLIST_DATA =
("#EXTM3U\n"
+ "#EXT-X-STREAM-INF:BANDWIDTH=232370,CODECS=\"mp4a.40.2, avc1.4d4015\"\n"
+ MEDIA_PLAYLIST_1_URI
......
......@@ -17,10 +17,6 @@ package com.google.android.exoplayer2.source.hls.offline;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.ENC_MEDIA_PLAYLIST_DATA;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.ENC_MEDIA_PLAYLIST_URI;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MASTER_MEDIA_PLAYLIST_1_INDEX;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MASTER_MEDIA_PLAYLIST_2_INDEX;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MASTER_PLAYLIST_DATA;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MASTER_PLAYLIST_URI;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MEDIA_PLAYLIST_0_DIR;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MEDIA_PLAYLIST_0_URI;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MEDIA_PLAYLIST_1_DIR;
......@@ -30,6 +26,10 @@ import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestDa
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MEDIA_PLAYLIST_3_DIR;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MEDIA_PLAYLIST_3_URI;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MEDIA_PLAYLIST_DATA;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MULTIVARIANT_MEDIA_PLAYLIST_1_INDEX;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MULTIVARIANT_MEDIA_PLAYLIST_2_INDEX;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MULTIVARIANT_PLAYLIST_DATA;
import static com.google.android.exoplayer2.source.hls.offline.HlsDownloadTestData.MULTIVARIANT_PLAYLIST_URI;
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCacheEmpty;
import static com.google.android.exoplayer2.testutil.CacheAsserts.assertCachedData;
import static com.google.common.truth.Truth.assertThat;
......@@ -43,7 +43,7 @@ import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.offline.Downloader;
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.source.hls.playlist.HlsMultivariantPlaylist;
import com.google.android.exoplayer2.testutil.CacheAsserts;
import com.google.android.exoplayer2.testutil.FakeDataSet;
import com.google.android.exoplayer2.testutil.FakeDataSource;
......@@ -83,7 +83,7 @@ public class HlsDownloaderTest {
progressListener = new ProgressListener();
fakeDataSet =
new FakeDataSet()
.setData(MASTER_PLAYLIST_URI, MASTER_PLAYLIST_DATA)
.setData(MULTIVARIANT_PLAYLIST_URI, MULTIVARIANT_PLAYLIST_DATA)
.setData(MEDIA_PLAYLIST_1_URI, MEDIA_PLAYLIST_DATA)
.setRandomData(MEDIA_PLAYLIST_1_DIR + "fileSequence0.ts", 10)
.setRandomData(MEDIA_PLAYLIST_1_DIR + "fileSequence1.ts", 11)
......@@ -122,7 +122,7 @@ public class HlsDownloaderTest {
@Test
public void counterMethods() throws Exception {
HlsDownloader downloader =
getHlsDownloader(MASTER_PLAYLIST_URI, getKeys(MASTER_MEDIA_PLAYLIST_1_INDEX));
getHlsDownloader(MULTIVARIANT_PLAYLIST_URI, getKeys(MULTIVARIANT_MEDIA_PLAYLIST_1_INDEX));
downloader.download(progressListener);
progressListener.assertBytesDownloaded(MEDIA_PLAYLIST_DATA.length + 10 + 11 + 12);
......@@ -131,14 +131,14 @@ public class HlsDownloaderTest {
@Test
public void downloadRepresentation() throws Exception {
HlsDownloader downloader =
getHlsDownloader(MASTER_PLAYLIST_URI, getKeys(MASTER_MEDIA_PLAYLIST_1_INDEX));
getHlsDownloader(MULTIVARIANT_PLAYLIST_URI, getKeys(MULTIVARIANT_MEDIA_PLAYLIST_1_INDEX));
downloader.download(progressListener);
assertCachedData(
cache,
new CacheAsserts.RequestSet(fakeDataSet)
.subset(
MASTER_PLAYLIST_URI,
MULTIVARIANT_PLAYLIST_URI,
MEDIA_PLAYLIST_1_URI,
MEDIA_PLAYLIST_1_DIR + "fileSequence0.ts",
MEDIA_PLAYLIST_1_DIR + "fileSequence1.ts",
......@@ -149,8 +149,8 @@ public class HlsDownloaderTest {
public void downloadMultipleRepresentations() throws Exception {
HlsDownloader downloader =
getHlsDownloader(
MASTER_PLAYLIST_URI,
getKeys(MASTER_MEDIA_PLAYLIST_1_INDEX, MASTER_MEDIA_PLAYLIST_2_INDEX));
MULTIVARIANT_PLAYLIST_URI,
getKeys(MULTIVARIANT_MEDIA_PLAYLIST_1_INDEX, MULTIVARIANT_MEDIA_PLAYLIST_2_INDEX));
downloader.download(progressListener);
assertCachedData(cache, fakeDataSet);
......@@ -169,7 +169,7 @@ public class HlsDownloaderTest {
.setRandomData(MEDIA_PLAYLIST_3_DIR + "fileSequence1.ts", 14)
.setRandomData(MEDIA_PLAYLIST_3_DIR + "fileSequence2.ts", 15);
HlsDownloader downloader = getHlsDownloader(MASTER_PLAYLIST_URI, getKeys());
HlsDownloader downloader = getHlsDownloader(MULTIVARIANT_PLAYLIST_URI, getKeys());
downloader.download(progressListener);
assertCachedData(cache, fakeDataSet);
......@@ -179,8 +179,8 @@ public class HlsDownloaderTest {
public void remove() throws Exception {
HlsDownloader downloader =
getHlsDownloader(
MASTER_PLAYLIST_URI,
getKeys(MASTER_MEDIA_PLAYLIST_1_INDEX, MASTER_MEDIA_PLAYLIST_2_INDEX));
MULTIVARIANT_PLAYLIST_URI,
getKeys(MULTIVARIANT_MEDIA_PLAYLIST_1_INDEX, MULTIVARIANT_MEDIA_PLAYLIST_2_INDEX));
downloader.download(progressListener);
downloader.remove();
......@@ -231,7 +231,7 @@ public class HlsDownloaderTest {
private static ArrayList<StreamKey> getKeys(int... variantIndices) {
ArrayList<StreamKey> streamKeys = new ArrayList<>();
for (int variantIndex : variantIndices) {
streamKeys.add(new StreamKey(HlsMasterPlaylist.GROUP_INDEX_VARIANT, variantIndex));
streamKeys.add(new StreamKey(HlsMultivariantPlaylist.GROUP_INDEX_VARIANT, variantIndex));
}
return streamKeys;
}
......
......@@ -392,7 +392,7 @@ public class HlsMediaPlaylistParserTest {
HlsMediaPlaylist playlist =
(HlsMediaPlaylist)
new HlsPlaylistParser(HlsMasterPlaylist.EMPTY, previousPlaylist)
new HlsPlaylistParser(HlsMultivariantPlaylist.EMPTY, previousPlaylist)
.parse(playlistUri, inputStream);
assertThat(playlist.segments).hasSize(3);
......@@ -446,7 +446,7 @@ public class HlsMediaPlaylistParserTest {
HlsMediaPlaylist playlist =
(HlsMediaPlaylist)
new HlsPlaylistParser(HlsMasterPlaylist.EMPTY, previousPlaylist)
new HlsPlaylistParser(HlsMultivariantPlaylist.EMPTY, previousPlaylist)
.parse(playlistUri, inputStream);
assertThat(playlist.segments).hasSize(2);
......@@ -1363,7 +1363,7 @@ public class HlsMediaPlaylistParserTest {
}
@Test
public void masterPlaylistAttributeInheritance() throws IOException {
public void multivariantPlaylistAttributeInheritance() throws IOException {
Uri playlistUri = Uri.parse("https://example.com/test3.m3u8");
String playlistString =
"#EXTM3U\n"
......@@ -1386,8 +1386,8 @@ public class HlsMediaPlaylistParserTest {
assertThat(standalonePlaylist.hasIndependentSegments).isFalse();
inputStream.reset();
HlsMasterPlaylist masterPlaylist =
new HlsMasterPlaylist(
HlsMultivariantPlaylist multivariantPlaylist =
new HlsMultivariantPlaylist(
/* baseUri= */ "https://example.com/",
/* tags= */ Collections.emptyList(),
/* variants= */ Collections.emptyList(),
......@@ -1402,7 +1402,7 @@ public class HlsMediaPlaylistParserTest {
/* sessionKeyDrmInitData= */ Collections.emptyList());
HlsMediaPlaylist playlistWithInheritance =
(HlsMediaPlaylist)
new HlsPlaylistParser(masterPlaylist, /* previousMediaPlaylist= */ null)
new HlsPlaylistParser(multivariantPlaylist, /* previousMediaPlaylist= */ null)
.parse(playlistUri, inputStream);
assertThat(playlistWithInheritance.hasIndependentSegments).isTrue();
}
......@@ -1450,8 +1450,8 @@ public class HlsMediaPlaylistParserTest {
InputStream inputStream = new ByteArrayInputStream(Util.getUtf8Bytes(playlistString));
HashMap<String, String> variableDefinitions = new HashMap<>();
variableDefinitions.put("imported_base", "long_path");
HlsMasterPlaylist masterPlaylist =
new HlsMasterPlaylist(
HlsMultivariantPlaylist multivariantPlaylist =
new HlsMultivariantPlaylist(
/* baseUri= */ "",
/* tags= */ Collections.emptyList(),
/* variants= */ Collections.emptyList(),
......@@ -1466,7 +1466,7 @@ public class HlsMediaPlaylistParserTest {
/* sessionKeyDrmInitData= */ Collections.emptyList());
HlsMediaPlaylist playlist =
(HlsMediaPlaylist)
new HlsPlaylistParser(masterPlaylist, /* previousMediaPlaylist= */ null)
new HlsPlaylistParser(multivariantPlaylist, /* previousMediaPlaylist= */ null)
.parse(playlistUri, inputStream);
for (int i = 1; i <= 4; i++) {
assertThat(playlist.segments.get(i - 1).url).isEqualTo("long_path" + i + ".ts");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment