Commit 99f89132 by olly Committed by Toni

Remove HlsUrl and introduce HlsMasterPlaylist.mediaPlaylistUrls

- This removes the need for Variant and Rendition to have a common
  base class, allowing the url field to be marked as @Nullable in
  Rendition but not in Variant.
- The addition of mediaPlaylistUrls is needed for the new StreamKey
  indexing for HLS. It's also convenient in a couple of places (e.g.
  HlsDownloader), where a list of all media playlist URLs is needed.
- Lots of places where HlsUrl was passed only needed the actual
  URL (not the Format, which is the other piece of HlsUrl). Passing
  just the URL is a little simpler, and resolves some of the naming
  confusion.

Issue: #5596
Issue: #2600
PiperOrigin-RevId: 240970466
parent 2623b4b3
...@@ -27,7 +27,6 @@ import com.google.android.exoplayer2.metadata.Metadata; ...@@ -27,7 +27,6 @@ import com.google.android.exoplayer2.metadata.Metadata;
import com.google.android.exoplayer2.metadata.id3.Id3Decoder; import com.google.android.exoplayer2.metadata.id3.Id3Decoder;
import com.google.android.exoplayer2.metadata.id3.PrivFrame; import com.google.android.exoplayer2.metadata.id3.PrivFrame;
import com.google.android.exoplayer2.source.chunk.MediaChunk; import com.google.android.exoplayer2.source.chunk.MediaChunk;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec; import com.google.android.exoplayer2.upstream.DataSpec;
...@@ -52,9 +51,10 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -52,9 +51,10 @@ import java.util.concurrent.atomic.AtomicInteger;
* @param extractorFactory A {@link HlsExtractorFactory} from which the HLS media chunk extractor * @param extractorFactory A {@link HlsExtractorFactory} from which the HLS media chunk extractor
* is obtained. * is obtained.
* @param dataSource The source from which the data should be loaded. * @param dataSource The source from which the data should be loaded.
* @param format The chunk format.
* @param startOfPlaylistInPeriodUs The position of the playlist in the period in microseconds. * @param startOfPlaylistInPeriodUs The position of the playlist in the period in microseconds.
* @param mediaPlaylist The media playlist from which this chunk was obtained. * @param mediaPlaylist The media playlist from which this chunk was obtained.
* @param hlsUrl The url of the playlist from which this chunk was obtained. * @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 * @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 master playlist.
* @param trackSelectionReason See {@link #trackSelectionReason}. * @param trackSelectionReason See {@link #trackSelectionReason}.
...@@ -70,10 +70,11 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -70,10 +70,11 @@ import java.util.concurrent.atomic.AtomicInteger;
public static HlsMediaChunk createInstance( public static HlsMediaChunk createInstance(
HlsExtractorFactory extractorFactory, HlsExtractorFactory extractorFactory,
DataSource dataSource, DataSource dataSource,
Format format,
long startOfPlaylistInPeriodUs, long startOfPlaylistInPeriodUs,
HlsMediaPlaylist mediaPlaylist, HlsMediaPlaylist mediaPlaylist,
int segmentIndexInPlaylist, int segmentIndexInPlaylist,
HlsUrl hlsUrl, Uri playlistUrl,
@Nullable List<Format> muxedCaptionFormats, @Nullable List<Format> muxedCaptionFormats,
int trackSelectionReason, int trackSelectionReason,
@Nullable Object trackSelectionData, @Nullable Object trackSelectionData,
...@@ -126,7 +127,8 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -126,7 +127,8 @@ import java.util.concurrent.atomic.AtomicInteger;
if (previousChunk != null) { if (previousChunk != null) {
id3Decoder = previousChunk.id3Decoder; id3Decoder = previousChunk.id3Decoder;
scratchId3Data = previousChunk.scratchId3Data; scratchId3Data = previousChunk.scratchId3Data;
shouldSpliceIn = previousChunk.hlsUrl != hlsUrl || !previousChunk.loadCompleted; shouldSpliceIn =
!playlistUrl.equals(previousChunk.playlistUrl) || !previousChunk.loadCompleted;
previousExtractor = previousExtractor =
previousChunk.isExtractorReusable previousChunk.isExtractorReusable
&& previousChunk.discontinuitySequenceNumber == discontinuitySequenceNumber && previousChunk.discontinuitySequenceNumber == discontinuitySequenceNumber
...@@ -143,11 +145,12 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -143,11 +145,12 @@ import java.util.concurrent.atomic.AtomicInteger;
extractorFactory, extractorFactory,
mediaDataSource, mediaDataSource,
dataSpec, dataSpec,
format,
mediaSegmentEncrypted, mediaSegmentEncrypted,
initDataSource, initDataSource,
initDataSpec, initDataSpec,
initSegmentEncrypted, initSegmentEncrypted,
hlsUrl, playlistUrl,
muxedCaptionFormats, muxedCaptionFormats,
trackSelectionReason, trackSelectionReason,
trackSelectionData, trackSelectionData,
...@@ -180,10 +183,8 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -180,10 +183,8 @@ import java.util.concurrent.atomic.AtomicInteger;
*/ */
public final int discontinuitySequenceNumber; public final int discontinuitySequenceNumber;
/** /** The url of the playlist from which this chunk was obtained. */
* The url of the playlist from which this chunk was obtained. public final Uri playlistUrl;
*/
public final HlsUrl hlsUrl;
@Nullable private final DataSource initDataSource; @Nullable private final DataSource initDataSource;
@Nullable private final DataSpec initDataSpec; @Nullable private final DataSpec initDataSpec;
...@@ -214,11 +215,12 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -214,11 +215,12 @@ import java.util.concurrent.atomic.AtomicInteger;
HlsExtractorFactory extractorFactory, HlsExtractorFactory extractorFactory,
DataSource mediaDataSource, DataSource mediaDataSource,
DataSpec dataSpec, DataSpec dataSpec,
Format format,
boolean mediaSegmentEncrypted, boolean mediaSegmentEncrypted,
DataSource initDataSource, DataSource initDataSource,
@Nullable DataSpec initDataSpec, @Nullable DataSpec initDataSpec,
boolean initSegmentEncrypted, boolean initSegmentEncrypted,
HlsUrl hlsUrl, Uri playlistUrl,
@Nullable List<Format> muxedCaptionFormats, @Nullable List<Format> muxedCaptionFormats,
int trackSelectionReason, int trackSelectionReason,
Object trackSelectionData, Object trackSelectionData,
...@@ -237,7 +239,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -237,7 +239,7 @@ import java.util.concurrent.atomic.AtomicInteger;
super( super(
mediaDataSource, mediaDataSource,
dataSpec, dataSpec,
hlsUrl.format, format,
trackSelectionReason, trackSelectionReason,
trackSelectionData, trackSelectionData,
startTimeUs, startTimeUs,
...@@ -248,7 +250,7 @@ import java.util.concurrent.atomic.AtomicInteger; ...@@ -248,7 +250,7 @@ import java.util.concurrent.atomic.AtomicInteger;
this.initDataSource = initDataSource; this.initDataSource = initDataSource;
this.initDataSpec = initDataSpec; this.initDataSpec = initDataSpec;
this.initSegmentEncrypted = initSegmentEncrypted; this.initSegmentEncrypted = initSegmentEncrypted;
this.hlsUrl = hlsUrl; this.playlistUrl = playlistUrl;
this.isMasterTimestampSource = isMasterTimestampSource; this.isMasterTimestampSource = isMasterTimestampSource;
this.timestampAdjuster = timestampAdjuster; this.timestampAdjuster = timestampAdjuster;
this.hasGapTag = hasGapTag; this.hasGapTag = hasGapTag;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.source.hls; package com.google.android.exoplayer2.source.hls;
import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -37,8 +38,6 @@ import com.google.android.exoplayer2.source.TrackGroup; ...@@ -37,8 +38,6 @@ import com.google.android.exoplayer2.source.TrackGroup;
import com.google.android.exoplayer2.source.TrackGroupArray; import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.chunk.Chunk; import com.google.android.exoplayer2.source.chunk.Chunk;
import com.google.android.exoplayer2.source.chunk.MediaChunkIterator; import com.google.android.exoplayer2.source.chunk.MediaChunkIterator;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
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.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
...@@ -79,8 +78,7 @@ import java.util.Map; ...@@ -79,8 +78,7 @@ import java.util.Map;
* Called to schedule a {@link #continueLoading(long)} call when the playlist referred by the * Called to schedule a {@link #continueLoading(long)} call when the playlist referred by the
* given url changes. * given url changes.
*/ */
void onPlaylistRefreshRequired(HlsMasterPlaylist.HlsUrl playlistUrl); void onPlaylistRefreshRequired(Uri playlistUrl);
} }
private static final String TAG = "HlsSampleStreamWrapper"; private static final String TAG = "HlsSampleStreamWrapper";
...@@ -451,8 +449,8 @@ import java.util.Map; ...@@ -451,8 +449,8 @@ import java.util.Map;
chunkSource.setIsTimestampMaster(isTimestampMaster); chunkSource.setIsTimestampMaster(isTimestampMaster);
} }
public boolean onPlaylistError(HlsUrl url, long blacklistDurationMs) { public boolean onPlaylistError(Uri playlistUrl, long blacklistDurationMs) {
return chunkSource.onPlaylistError(url, blacklistDurationMs); return chunkSource.onPlaylistError(playlistUrl, blacklistDurationMs);
} }
// SampleStream implementation. // SampleStream implementation.
...@@ -590,7 +588,7 @@ import java.util.Map; ...@@ -590,7 +588,7 @@ import java.util.Map;
chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder); chunkSource.getNextChunk(positionUs, loadPositionUs, chunkQueue, nextChunkHolder);
boolean endOfStream = nextChunkHolder.endOfStream; boolean endOfStream = nextChunkHolder.endOfStream;
Chunk loadable = nextChunkHolder.chunk; Chunk loadable = nextChunkHolder.chunk;
HlsMasterPlaylist.HlsUrl playlistToLoad = nextChunkHolder.playlist; Uri playlistUrlToLoad = nextChunkHolder.playlistUrl;
nextChunkHolder.clear(); nextChunkHolder.clear();
if (endOfStream) { if (endOfStream) {
...@@ -600,8 +598,8 @@ import java.util.Map; ...@@ -600,8 +598,8 @@ import java.util.Map;
} }
if (loadable == null) { if (loadable == null) {
if (playlistToLoad != null) { if (playlistUrlToLoad != null) {
callback.onPlaylistRefreshRequired(playlistToLoad); callback.onPlaylistRefreshRequired(playlistUrlToLoad);
} }
return false; return false;
} }
......
...@@ -21,7 +21,6 @@ import com.google.android.exoplayer2.offline.DownloaderConstructorHelper; ...@@ -21,7 +21,6 @@ import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloader; import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.offline.StreamKey; import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylist;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistParser;
...@@ -81,9 +80,7 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> { ...@@ -81,9 +80,7 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
ArrayList<DataSpec> mediaPlaylistDataSpecs = new ArrayList<>(); ArrayList<DataSpec> mediaPlaylistDataSpecs = new ArrayList<>();
if (playlist instanceof HlsMasterPlaylist) { if (playlist instanceof HlsMasterPlaylist) {
HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist; HlsMasterPlaylist masterPlaylist = (HlsMasterPlaylist) playlist;
addMediaPlaylistDataSpecs(masterPlaylist.variants, mediaPlaylistDataSpecs); addMediaPlaylistDataSpecs(masterPlaylist.mediaPlaylistUrls, mediaPlaylistDataSpecs);
addMediaPlaylistDataSpecs(masterPlaylist.audios, mediaPlaylistDataSpecs);
addMediaPlaylistDataSpecs(masterPlaylist.subtitles, mediaPlaylistDataSpecs);
} else { } else {
mediaPlaylistDataSpecs.add( mediaPlaylistDataSpecs.add(
SegmentDownloader.getCompressibleDataSpec(Uri.parse(playlist.baseUri))); SegmentDownloader.getCompressibleDataSpec(Uri.parse(playlist.baseUri)));
...@@ -118,9 +115,9 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> { ...@@ -118,9 +115,9 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
return segments; return segments;
} }
private void addMediaPlaylistDataSpecs(List<? extends HlsUrl> urls, List<DataSpec> out) { private void addMediaPlaylistDataSpecs(List<Uri> mediaPlaylistUrls, List<DataSpec> out) {
for (int i = 0; i < urls.size(); i++) { for (int i = 0; i < mediaPlaylistUrls.size(); i++) {
out.add(SegmentDownloader.getCompressibleDataSpec(urls.get(i).url)); out.add(SegmentDownloader.getCompressibleDataSpec(mediaPlaylistUrls.get(i)));
} }
} }
......
...@@ -50,28 +50,14 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -50,28 +50,14 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
public static final int GROUP_INDEX_AUDIO = 1; public static final int GROUP_INDEX_AUDIO = 1;
public static final int GROUP_INDEX_SUBTITLE = 2; public static final int GROUP_INDEX_SUBTITLE = 2;
/** Represents a url in an HLS master playlist. */ /** A variant (i.e. an #EXT-X-STREAM-INF tag) in a master playlist. */
public abstract static class HlsUrl { public static final class Variant {
/** The http url from which the media playlist can be obtained. */ /** The variant's url. */
public final Uri url; public final Uri url;
/**
* Format information associated with the HLS url.
*/
public final Format format;
/**
* @param url See {@link #url}.
* @param format See {@link #format}.
*/
public HlsUrl(Uri url, Format format) {
this.url = url;
this.format = format;
}
}
/** A variant in a master playlist. */ /** Format information associated with this variant. */
public static final class Variant extends HlsUrl { public final Format format;
/** The video rendition group referenced by this variant, or {@code null}. */ /** The video rendition group referenced by this variant, or {@code null}. */
@Nullable public final String videoGroupId; @Nullable public final String videoGroupId;
...@@ -100,7 +86,8 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -100,7 +86,8 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
@Nullable String audioGroupId, @Nullable String audioGroupId,
@Nullable String subtitleGroupId, @Nullable String subtitleGroupId,
@Nullable String captionGroupId) { @Nullable String captionGroupId) {
super(url, format); this.url = url;
this.format = format;
this.videoGroupId = videoGroupId; this.videoGroupId = videoGroupId;
this.audioGroupId = audioGroupId; this.audioGroupId = audioGroupId;
this.subtitleGroupId = subtitleGroupId; this.subtitleGroupId = subtitleGroupId;
...@@ -135,8 +122,14 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -135,8 +122,14 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
} }
} }
/** A rendition in a master playlist. */ /** A rendition (i.e. an #EXT-X-MEDIA tag) in a master playlist. */
public static final class Rendition extends HlsUrl { public static final class Rendition {
/** The rendition's url, or null if the tag does not have a URI attribute. */
@Nullable public final Uri url;
/** Format information associated with this rendition. */
public final Format format;
/** The group to which this rendition belongs. */ /** The group to which this rendition belongs. */
public final String groupId; public final String groupId;
...@@ -150,14 +143,17 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -150,14 +143,17 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
* @param groupId See {@link #groupId}. * @param groupId See {@link #groupId}.
* @param name See {@link #name}. * @param name See {@link #name}.
*/ */
public Rendition(Uri url, Format format, String groupId, String name) { public Rendition(@Nullable Uri url, Format format, String groupId, String name) {
super(url, format); this.url = url;
this.format = format;
this.groupId = groupId; this.groupId = groupId;
this.name = name; this.name = name;
} }
} }
/** All of the media playlist URLs referenced by the playlist. */
public final List<Uri> mediaPlaylistUrls;
/** The variants declared by the playlist. */ /** The variants declared by the playlist. */
public final List<Variant> variants; public final List<Variant> variants;
/** The video renditions declared by the playlist. */ /** The video renditions declared by the playlist. */
...@@ -213,6 +209,9 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -213,6 +209,9 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
Map<String, String> variableDefinitions, Map<String, String> variableDefinitions,
List<DrmInitData> sessionKeyDrmInitData) { List<DrmInitData> sessionKeyDrmInitData) {
super(baseUri, tags, hasIndependentSegments); super(baseUri, tags, hasIndependentSegments);
this.mediaPlaylistUrls =
Collections.unmodifiableList(
getMediaPlaylistUrls(variants, videos, audios, subtitles, closedCaptions));
this.variants = Collections.unmodifiableList(variants); this.variants = Collections.unmodifiableList(variants);
this.videos = Collections.unmodifiableList(videos); this.videos = Collections.unmodifiableList(videos);
this.audios = Collections.unmodifiableList(audios); this.audios = Collections.unmodifiableList(audios);
...@@ -268,7 +267,36 @@ public final class HlsMasterPlaylist extends HlsPlaylist { ...@@ -268,7 +267,36 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
/* sessionKeyDrmInitData= */ Collections.emptyList()); /* sessionKeyDrmInitData= */ Collections.emptyList());
} }
private static <T extends HlsUrl> List<T> copyStreams( private static List<Uri> getMediaPlaylistUrls(
List<Variant> variants,
List<Rendition> videos,
List<Rendition> audios,
List<Rendition> subtitles,
List<Rendition> closedCaptions) {
ArrayList<Uri> mediaPlaylistUrls = new ArrayList<>();
for (int i = 0; i < variants.size(); i++) {
Uri uri = variants.get(i).url;
if (!mediaPlaylistUrls.contains(uri)) {
mediaPlaylistUrls.add(uri);
}
}
addMediaPlaylistUrls(videos, mediaPlaylistUrls);
addMediaPlaylistUrls(audios, mediaPlaylistUrls);
addMediaPlaylistUrls(subtitles, mediaPlaylistUrls);
addMediaPlaylistUrls(closedCaptions, mediaPlaylistUrls);
return mediaPlaylistUrls;
}
private static void addMediaPlaylistUrls(List<Rendition> renditions, List<Uri> out) {
for (int i = 0; i < renditions.size(); i++) {
Uri uri = renditions.get(i).url;
if (uri != null && !out.contains(uri)) {
out.add(uri);
}
}
}
private static <T> List<T> copyStreams(
List<T> streams, int groupIndex, List<StreamKey> streamKeys) { List<T> streams, int groupIndex, List<StreamKey> streamKeys) {
List<T> copiedStreams = new ArrayList<>(streamKeys.size()); List<T> copiedStreams = new ArrayList<>(streamKeys.size());
// TODO: // TODO:
......
...@@ -20,7 +20,6 @@ import androidx.annotation.Nullable; ...@@ -20,7 +20,6 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher; import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory; import com.google.android.exoplayer2.source.hls.HlsDataSourceFactory;
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.HlsUrl;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy; import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import java.io.IOException; import java.io.IOException;
...@@ -81,7 +80,7 @@ public interface HlsPlaylistTracker { ...@@ -81,7 +80,7 @@ public interface HlsPlaylistTracker {
* {@link C#TIME_UNSET} if the playlist should not be blacklisted. * {@link C#TIME_UNSET} if the playlist should not be blacklisted.
* @return True if blacklisting did not encounter errors. False otherwise. * @return True if blacklisting did not encounter errors. False otherwise.
*/ */
boolean onPlaylistError(HlsUrl url, long blacklistDurationMs); boolean onPlaylistError(Uri url, long blacklistDurationMs);
} }
/** Thrown when a playlist is considered to be stuck due to a server side error. */ /** Thrown when a playlist is considered to be stuck due to a server side error. */
...@@ -164,16 +163,16 @@ public interface HlsPlaylistTracker { ...@@ -164,16 +163,16 @@ public interface HlsPlaylistTracker {
/** /**
* Returns the most recent snapshot available of the playlist referenced by the provided {@link * Returns the most recent snapshot available of the playlist referenced by the provided {@link
* HlsUrl}. * Uri}.
* *
* @param url The {@link HlsUrl} corresponding to the requested media playlist. * @param url The {@link Uri} corresponding to the requested media playlist.
* @param isForPlayback Whether the caller might use the snapshot to request media segments for * @param isForPlayback Whether the caller might use the snapshot to request media segments for
* playback. If true, the primary playlist may be updated to the one requested. * playback. If true, the primary playlist may be updated to the one requested.
* @return The most recent snapshot of the playlist referenced by the provided {@link HlsUrl}. May * @return The most recent snapshot of the playlist referenced by the provided {@link Uri}. May be
* be null if no snapshot has been loaded yet. * null if no snapshot has been loaded yet.
*/ */
@Nullable @Nullable
HlsMediaPlaylist getPlaylistSnapshot(HlsUrl url, boolean isForPlayback); HlsMediaPlaylist getPlaylistSnapshot(Uri url, boolean isForPlayback);
/** /**
* Returns the start time of the first loaded primary playlist, or {@link C#TIME_UNSET} if no * Returns the start time of the first loaded primary playlist, or {@link C#TIME_UNSET} if no
...@@ -182,15 +181,14 @@ public interface HlsPlaylistTracker { ...@@ -182,15 +181,14 @@ public interface HlsPlaylistTracker {
long getInitialStartTimeUs(); long getInitialStartTimeUs();
/** /**
* Returns whether the snapshot of the playlist referenced by the provided {@link HlsUrl} is * Returns whether the snapshot of the playlist referenced by the provided {@link Uri} is valid,
* valid, meaning all the segments referenced by the playlist are expected to be available. If the * meaning all the segments referenced by the playlist are expected to be available. If the
* playlist is not valid then some of the segments may no longer be available. * playlist is not valid then some of the segments may no longer be available.
* *
* @param url The {@link HlsUrl}. * @param url The {@link Uri}.
* @return Whether the snapshot of the playlist referenced by the provided {@link HlsUrl} is * @return Whether the snapshot of the playlist referenced by the provided {@link Uri} is valid.
* valid.
*/ */
boolean isSnapshotValid(HlsUrl url); boolean isSnapshotValid(Uri url);
/** /**
* If the tracker is having trouble refreshing the master playlist or the primary playlist, this * If the tracker is having trouble refreshing the master playlist or the primary playlist, this
...@@ -201,13 +199,13 @@ public interface HlsPlaylistTracker { ...@@ -201,13 +199,13 @@ public interface HlsPlaylistTracker {
void maybeThrowPrimaryPlaylistRefreshError() throws IOException; void maybeThrowPrimaryPlaylistRefreshError() throws IOException;
/** /**
* If the playlist is having trouble refreshing the playlist referenced by the given {@link * If the playlist is having trouble refreshing the playlist referenced by the given {@link Uri},
* HlsUrl}, this method throws the underlying error. * this method throws the underlying error.
* *
* @param url The {@link HlsUrl}. * @param url The {@link Uri}.
* @throws IOException The underyling error. * @throws IOException The underyling error.
*/ */
void maybeThrowPlaylistRefreshError(HlsUrl url) throws IOException; void maybeThrowPlaylistRefreshError(Uri url) throws IOException;
/** /**
* Requests a playlist refresh and whitelists it. * Requests a playlist refresh and whitelists it.
...@@ -215,9 +213,9 @@ public interface HlsPlaylistTracker { ...@@ -215,9 +213,9 @@ public interface HlsPlaylistTracker {
* <p>The playlist tracker may choose the delay the playlist refresh. The request is discarded if * <p>The playlist tracker may choose the delay the playlist refresh. The request is discarded if
* a refresh was already pending. * a refresh was already pending.
* *
* @param url The {@link HlsUrl} of the playlist to be refreshed. * @param url The {@link Uri} of the playlist to be refreshed.
*/ */
void refreshPlaylist(HlsUrl url); void refreshPlaylist(Uri url);
/** /**
* Returns whether the tracked playlists describe a live stream. * Returns whether the tracked playlists describe a live stream.
......
...@@ -290,7 +290,7 @@ public class HlsMasterPlaylistParserTest { ...@@ -290,7 +290,7 @@ public class HlsMasterPlaylistParserTest {
public void testVariableSubstitution() throws IOException { public void testVariableSubstitution() throws IOException {
HlsMasterPlaylist playlistWithSubstitutions = HlsMasterPlaylist playlistWithSubstitutions =
parseMasterPlaylist(PLAYLIST_URI, PLAYLIST_WITH_VARIABLE_SUBSTITUTION); parseMasterPlaylist(PLAYLIST_URI, PLAYLIST_WITH_VARIABLE_SUBSTITUTION);
HlsMasterPlaylist.HlsUrl variant = playlistWithSubstitutions.variants.get(0); HlsMasterPlaylist.Variant variant = playlistWithSubstitutions.variants.get(0);
assertThat(variant.format.codecs).isEqualTo("mp4a.40.5"); assertThat(variant.format.codecs).isEqualTo("mp4a.40.5");
assertThat(variant.url) assertThat(variant.url)
.isEqualTo(Uri.parse("http://example.com/This/{$nested}/reference/shouldnt/work")); .isEqualTo(Uri.parse("http://example.com/This/{$nested}/reference/shouldnt/work"));
......
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