mirror of
https://github.com/samsonjs/media.git
synced 2026-04-01 10:35:48 +00:00
More faithfully parse content of HLS master playlists
- Split HlsUrl into Rendition and Variant - Add Rendition/Variant specific information to the new types Issue: #5596 PiperOrigin-RevId: 240419763
This commit is contained in:
parent
ae5e5f7efc
commit
e3a8429ee2
7 changed files with 170 additions and 91 deletions
|
|
@ -32,6 +32,7 @@ import com.google.android.exoplayer2.source.TrackGroup;
|
|||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
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.HlsMasterPlaylist.Rendition;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelection;
|
||||
import com.google.android.exoplayer2.upstream.Allocator;
|
||||
|
|
@ -442,8 +443,8 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||
: Collections.emptyMap();
|
||||
|
||||
boolean hasVariants = !masterPlaylist.variants.isEmpty();
|
||||
List<HlsUrl> audioRenditions = masterPlaylist.audios;
|
||||
List<HlsUrl> subtitleRenditions = masterPlaylist.subtitles;
|
||||
List<Rendition> audioRenditions = masterPlaylist.audios;
|
||||
List<Rendition> subtitleRenditions = masterPlaylist.subtitles;
|
||||
|
||||
pendingPrepareCount = 0;
|
||||
ArrayList<HlsSampleStreamWrapper> sampleStreamWrappers = new ArrayList<>();
|
||||
|
|
@ -644,7 +645,7 @@ public final class HlsMediaPeriod implements MediaPeriod, HlsSampleStreamWrapper
|
|||
|
||||
private void buildAndPrepareAudioSampleStreamWrappers(
|
||||
long positionUs,
|
||||
List<HlsUrl> audioRenditions,
|
||||
List<Rendition> audioRenditions,
|
||||
List<HlsSampleStreamWrapper> sampleStreamWrappers,
|
||||
List<int[]> manifestUrlsIndicesPerWrapper,
|
||||
Map<String, DrmInitData> overridingDrmInitData) {
|
||||
|
|
|
|||
|
|
@ -119,7 +119,8 @@ public final class HlsDownloader extends SegmentDownloader<HlsPlaylist> {
|
|||
return segments;
|
||||
}
|
||||
|
||||
private void addMediaPlaylistDataSpecs(String baseUri, List<HlsUrl> urls, List<DataSpec> out) {
|
||||
private void addMediaPlaylistDataSpecs(
|
||||
String baseUri, List<? extends HlsUrl> urls, List<DataSpec> out) {
|
||||
for (int i = 0; i < urls.size(); i++) {
|
||||
Uri playlistUri = UriUtil.resolveToUri(baseUri, urls.get(i).url);
|
||||
out.add(SegmentDownloader.getCompressibleDataSpec(playlistUri));
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import com.google.android.exoplayer2.ParserException;
|
|||
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.HlsUrl;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.Variant;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMediaPlaylist.Segment;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
|
||||
|
|
@ -298,7 +299,7 @@ public final class DefaultHlsPlaylistTracker
|
|||
// Internal methods.
|
||||
|
||||
private boolean maybeSelectNewPrimaryUrl() {
|
||||
List<HlsUrl> variants = masterPlaylist.variants;
|
||||
List<Variant> variants = masterPlaylist.variants;
|
||||
int variantsSize = variants.size();
|
||||
long currentTimeMs = SystemClock.elapsedRealtime();
|
||||
for (int i = 0; i < variantsSize; i++) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
package com.google.android.exoplayer2.source.hls.playlist;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.Format;
|
||||
import com.google.android.exoplayer2.drm.DrmInitData;
|
||||
import com.google.android.exoplayer2.offline.StreamKey;
|
||||
|
|
@ -45,10 +46,8 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||
public static final int GROUP_INDEX_AUDIO = 1;
|
||||
public static final int GROUP_INDEX_SUBTITLE = 2;
|
||||
|
||||
/**
|
||||
* Represents a url in an HLS master playlist.
|
||||
*/
|
||||
public static final class HlsUrl {
|
||||
/** Represents a url in an HLS master playlist. */
|
||||
public abstract static class HlsUrl {
|
||||
|
||||
/**
|
||||
* The http url from which the media playlist can be obtained.
|
||||
|
|
@ -58,19 +57,61 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||
* Format information associated with the HLS url.
|
||||
*/
|
||||
public final Format format;
|
||||
/**
|
||||
* Value of the NAME attribute as defined by the #EXT-X-MEDIA tag, or empty if the HLS url is
|
||||
* not associated with any name.
|
||||
*/
|
||||
public final String name;
|
||||
|
||||
/**
|
||||
* Creates an HLS url from a given http url.
|
||||
*
|
||||
* @param url The url.
|
||||
* @return An HLS url.
|
||||
* @param url See {@link #url}.
|
||||
* @param format See {@link #format}.
|
||||
*/
|
||||
public static HlsUrl createMediaPlaylistHlsUrl(String url) {
|
||||
public HlsUrl(String url, Format format) {
|
||||
this.url = url;
|
||||
this.format = format;
|
||||
}
|
||||
}
|
||||
|
||||
/** A variant in a master playlist. */
|
||||
public static final class Variant extends HlsUrl {
|
||||
|
||||
/** The video rendition group referenced by this variant, or {@code null}. */
|
||||
@Nullable public final String videoGroupId;
|
||||
|
||||
/** The audio rendition group referenced by this variant, or {@code null}. */
|
||||
@Nullable public final String audioGroupId;
|
||||
|
||||
/** The subtitle rendition group referenced by this variant, or {@code null}. */
|
||||
@Nullable public final String subtitleGroupId;
|
||||
|
||||
/** The caption rendition group referenced by this variant, or {@code null}. */
|
||||
@Nullable public final String captionGroupId;
|
||||
|
||||
/**
|
||||
* @param url See {@link #url}.
|
||||
* @param format See {@link #format}.
|
||||
* @param videoGroupId See {@link #videoGroupId}.
|
||||
* @param audioGroupId See {@link #audioGroupId}.
|
||||
* @param subtitleGroupId See {@link #subtitleGroupId}.
|
||||
* @param captionGroupId See {@link #captionGroupId}.
|
||||
*/
|
||||
public Variant(
|
||||
String url,
|
||||
Format format,
|
||||
@Nullable String videoGroupId,
|
||||
@Nullable String audioGroupId,
|
||||
@Nullable String subtitleGroupId,
|
||||
@Nullable String captionGroupId) {
|
||||
super(url, format);
|
||||
this.videoGroupId = videoGroupId;
|
||||
this.audioGroupId = audioGroupId;
|
||||
this.subtitleGroupId = subtitleGroupId;
|
||||
this.captionGroupId = captionGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a variant for a given media playlist url.
|
||||
*
|
||||
* @param url The media playlist url.
|
||||
* @return The variant instance.
|
||||
*/
|
||||
public static Variant createMediaPlaylistVariantUrl(String url) {
|
||||
Format format =
|
||||
Format.createContainerFormat(
|
||||
"0",
|
||||
|
|
@ -82,34 +123,45 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0,
|
||||
/* language= */ null);
|
||||
return new HlsUrl(url, format, /* name= */ "");
|
||||
return new Variant(
|
||||
url,
|
||||
format,
|
||||
/* videoGroupId= */ null,
|
||||
/* audioGroupId= */ null,
|
||||
/* subtitleGroupId= */ null,
|
||||
/* captionGroupId= */ null);
|
||||
}
|
||||
}
|
||||
|
||||
/** A rendition in a master playlist. */
|
||||
public static final class Rendition extends HlsUrl {
|
||||
|
||||
/** The group to which this rendition belongs. */
|
||||
public final String groupId;
|
||||
|
||||
/** The name of the rendition. */
|
||||
public final String name;
|
||||
|
||||
/**
|
||||
* @param url See {@link #url}.
|
||||
* @param format See {@link #format}.
|
||||
* @param groupId See {@link #groupId}.
|
||||
* @param name See {@link #name}.
|
||||
*/
|
||||
public HlsUrl(String url, Format format, String name) {
|
||||
this.url = url;
|
||||
this.format = format;
|
||||
public Rendition(String url, Format format, String groupId, String name) {
|
||||
super(url, format);
|
||||
this.groupId = groupId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of variants declared by the playlist.
|
||||
*/
|
||||
public final List<HlsUrl> variants;
|
||||
/**
|
||||
* The list of demuxed audios declared by the playlist.
|
||||
*/
|
||||
public final List<HlsUrl> audios;
|
||||
/**
|
||||
* The list of subtitles declared by the playlist.
|
||||
*/
|
||||
public final List<HlsUrl> subtitles;
|
||||
/** The list of variants declared by the playlist. */
|
||||
public final List<Variant> variants;
|
||||
/** The list of demuxed audios declared by the playlist. */
|
||||
public final List<Rendition> audios;
|
||||
/** The list of subtitles declared by the playlist. */
|
||||
public final List<Rendition> subtitles;
|
||||
|
||||
/**
|
||||
* The format of the audio muxed in the variants. May be null if the playlist does not declare any
|
||||
|
|
@ -142,9 +194,9 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||
public HlsMasterPlaylist(
|
||||
String baseUri,
|
||||
List<String> tags,
|
||||
List<HlsUrl> variants,
|
||||
List<HlsUrl> audios,
|
||||
List<HlsUrl> subtitles,
|
||||
List<Variant> variants,
|
||||
List<Rendition> audios,
|
||||
List<Rendition> subtitles,
|
||||
Format muxedAudioFormat,
|
||||
List<Format> muxedCaptionFormats,
|
||||
boolean hasIndependentSegments,
|
||||
|
|
@ -183,14 +235,14 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||
* @return A master playlist with a single variant for the provided url.
|
||||
*/
|
||||
public static HlsMasterPlaylist createSingleVariantMasterPlaylist(String variantUrl) {
|
||||
List<HlsUrl> variant = Collections.singletonList(HlsUrl.createMediaPlaylistHlsUrl(variantUrl));
|
||||
List<HlsUrl> emptyList = Collections.emptyList();
|
||||
List<Variant> variant =
|
||||
Collections.singletonList(Variant.createMediaPlaylistVariantUrl(variantUrl));
|
||||
return new HlsMasterPlaylist(
|
||||
null,
|
||||
Collections.emptyList(),
|
||||
variant,
|
||||
emptyList,
|
||||
emptyList,
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
/* muxedAudioFormat= */ null,
|
||||
/* muxedCaptionFormats= */ null,
|
||||
/* hasIndependentSegments= */ false,
|
||||
|
|
@ -198,11 +250,11 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
|
|||
/* sessionKeyDrmInitData= */ Collections.emptyList());
|
||||
}
|
||||
|
||||
private static List<HlsUrl> copyRenditionsList(
|
||||
List<HlsUrl> renditions, int groupIndex, List<StreamKey> streamKeys) {
|
||||
List<HlsUrl> copiedRenditions = new ArrayList<>(streamKeys.size());
|
||||
private static <T extends HlsUrl> List<T> copyRenditionsList(
|
||||
List<T> renditions, int groupIndex, List<StreamKey> streamKeys) {
|
||||
List<T> copiedRenditions = new ArrayList<>(streamKeys.size());
|
||||
for (int i = 0; i < renditions.size(); i++) {
|
||||
HlsUrl rendition = renditions.get(i);
|
||||
T rendition = renditions.get(i);
|
||||
for (int j = 0; j < streamKeys.size(); j++) {
|
||||
StreamKey streamKey = streamKeys.get(j);
|
||||
if (streamKey.groupIndex == groupIndex && streamKey.trackIndex == i) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import com.google.android.exoplayer2.drm.DrmInitData;
|
|||
import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
|
||||
import com.google.android.exoplayer2.extractor.mp4.PsshAtomUtil;
|
||||
import com.google.android.exoplayer2.source.UnrecognizedInputFormatException;
|
||||
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.Segment;
|
||||
import com.google.android.exoplayer2.upstream.ParsingLoadable;
|
||||
import com.google.android.exoplayer2.util.MimeTypes;
|
||||
|
|
@ -100,7 +102,10 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
|
||||
private static final Pattern REGEX_AVERAGE_BANDWIDTH =
|
||||
Pattern.compile("AVERAGE-BANDWIDTH=(\\d+)\\b");
|
||||
private static final Pattern REGEX_VIDEO = Pattern.compile("VIDEO=\"(.+?)\"");
|
||||
private static final Pattern REGEX_AUDIO = Pattern.compile("AUDIO=\"(.+?)\"");
|
||||
private static final Pattern REGEX_SUBTITLES = Pattern.compile("SUBTITLES=\"(.+?)\"");
|
||||
private static final Pattern REGEX_CLOSED_CAPTIONS = Pattern.compile("CLOSED-CAPTIONS=\"(.+?)\"");
|
||||
private static final Pattern REGEX_BANDWIDTH = Pattern.compile("[^-]BANDWIDTH=(\\d+)\\b");
|
||||
private static final Pattern REGEX_CHANNELS = Pattern.compile("CHANNELS=\"(.+?)\"");
|
||||
private static final Pattern REGEX_CODECS = Pattern.compile("CODECS=\"(.+?)\"");
|
||||
|
|
@ -249,9 +254,9 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
HashSet<String> variantUrls = new HashSet<>();
|
||||
HashMap<String, String> audioGroupIdToCodecs = new HashMap<>();
|
||||
HashMap<String, String> variableDefinitions = new HashMap<>();
|
||||
ArrayList<HlsMasterPlaylist.HlsUrl> variants = new ArrayList<>();
|
||||
ArrayList<HlsMasterPlaylist.HlsUrl> audios = new ArrayList<>();
|
||||
ArrayList<HlsMasterPlaylist.HlsUrl> subtitles = new ArrayList<>();
|
||||
ArrayList<Variant> variants = new ArrayList<>();
|
||||
ArrayList<Rendition> audios = new ArrayList<>();
|
||||
ArrayList<Rendition> subtitles = new ArrayList<>();
|
||||
ArrayList<String> mediaTags = new ArrayList<>();
|
||||
ArrayList<DrmInitData> sessionKeyDrmInitData = new ArrayList<>();
|
||||
ArrayList<String> tags = new ArrayList<>();
|
||||
|
|
@ -321,7 +326,12 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
if (frameRateString != null) {
|
||||
frameRate = Float.parseFloat(frameRateString);
|
||||
}
|
||||
String videoGroupId = parseOptionalStringAttr(line, REGEX_VIDEO, variableDefinitions);
|
||||
String audioGroupId = parseOptionalStringAttr(line, REGEX_AUDIO, variableDefinitions);
|
||||
String subtitlesGroupId =
|
||||
parseOptionalStringAttr(line, REGEX_SUBTITLES, variableDefinitions);
|
||||
String closedCaptionsGroupId =
|
||||
parseOptionalStringAttr(line, REGEX_CLOSED_CAPTIONS, variableDefinitions);
|
||||
if (audioGroupId != null && codecs != null) {
|
||||
audioGroupIdToCodecs.put(audioGroupId, Util.getCodecsOfType(codecs, C.TRACK_TYPE_AUDIO));
|
||||
}
|
||||
|
|
@ -343,20 +353,27 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
/* initializationData= */ null,
|
||||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0);
|
||||
variants.add(new HlsMasterPlaylist.HlsUrl(line, format, /* name= */ ""));
|
||||
variants.add(
|
||||
new Variant(
|
||||
line,
|
||||
format,
|
||||
videoGroupId,
|
||||
audioGroupId,
|
||||
subtitlesGroupId,
|
||||
closedCaptionsGroupId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mediaTags.size(); i++) {
|
||||
line = mediaTags.get(i);
|
||||
String groupId = parseStringAttr(line, REGEX_GROUP_ID, variableDefinitions);
|
||||
String name = parseStringAttr(line, REGEX_NAME, variableDefinitions);
|
||||
String uri = parseOptionalStringAttr(line, REGEX_URI, variableDefinitions);
|
||||
String language = parseOptionalStringAttr(line, REGEX_LANGUAGE, variableDefinitions);
|
||||
@C.SelectionFlags int selectionFlags = parseSelectionFlags(line);
|
||||
@C.RoleFlags int roleFlags = parseRoleFlags(line, variableDefinitions);
|
||||
String uri = parseOptionalStringAttr(line, REGEX_URI, variableDefinitions);
|
||||
String name = parseStringAttr(line, REGEX_NAME, variableDefinitions);
|
||||
String language = parseOptionalStringAttr(line, REGEX_LANGUAGE, variableDefinitions);
|
||||
String groupId = parseOptionalStringAttr(line, REGEX_GROUP_ID, variableDefinitions);
|
||||
String id = groupId + ":" + name;
|
||||
String formatId = groupId + ":" + name;
|
||||
Format format;
|
||||
switch (parseStringAttr(line, REGEX_TYPE, variableDefinitions)) {
|
||||
case TYPE_AUDIO:
|
||||
|
|
@ -365,7 +382,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
String sampleMimeType = codecs != null ? MimeTypes.getMediaMimeType(codecs) : null;
|
||||
format =
|
||||
Format.createAudioContainerFormat(
|
||||
/* id= */ id,
|
||||
/* id= */ formatId,
|
||||
/* label= */ name,
|
||||
/* containerMimeType= */ MimeTypes.APPLICATION_M3U8,
|
||||
sampleMimeType,
|
||||
|
|
@ -380,13 +397,13 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
if (uri == null) {
|
||||
muxedAudioFormat = format;
|
||||
} else {
|
||||
audios.add(new HlsMasterPlaylist.HlsUrl(uri, format, name));
|
||||
audios.add(new Rendition(uri, format, groupId, name));
|
||||
}
|
||||
break;
|
||||
case TYPE_SUBTITLES:
|
||||
format =
|
||||
Format.createTextContainerFormat(
|
||||
/* id= */ id,
|
||||
/* id= */ formatId,
|
||||
/* label= */ name,
|
||||
/* containerMimeType= */ MimeTypes.APPLICATION_M3U8,
|
||||
/* sampleMimeType= */ MimeTypes.TEXT_VTT,
|
||||
|
|
@ -395,7 +412,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
selectionFlags,
|
||||
roleFlags,
|
||||
language);
|
||||
subtitles.add(new HlsMasterPlaylist.HlsUrl(uri, format, name));
|
||||
subtitles.add(new Rendition(uri, format, groupId, name));
|
||||
break;
|
||||
case TYPE_CLOSED_CAPTIONS:
|
||||
String instreamId = parseStringAttr(line, REGEX_INSTREAM_ID, variableDefinitions);
|
||||
|
|
@ -413,7 +430,7 @@ public final class HlsPlaylistParser implements ParsingLoadable.Parser<HlsPlayli
|
|||
}
|
||||
muxedCaptionFormats.add(
|
||||
Format.createTextContainerFormat(
|
||||
/* id= */ id,
|
||||
/* id= */ formatId,
|
||||
/* label= */ name,
|
||||
/* containerMimeType= */ null,
|
||||
/* sampleMimeType= */ mimeType,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@ import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
|
|||
import com.google.android.exoplayer2.source.MediaSource.MediaPeriodId;
|
||||
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
|
||||
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.HlsMasterPlaylist.Rendition;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.HlsMasterPlaylist.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;
|
||||
|
|
@ -53,19 +54,19 @@ public final class HlsMediaPeriodTest {
|
|||
HlsMasterPlaylist testMasterPlaylist =
|
||||
createMasterPlaylist(
|
||||
/* variants= */ Arrays.asList(
|
||||
createAudioOnlyVariantHlsUrl(/* bitrate= */ 10000),
|
||||
createMuxedVideoAudioVariantHlsUrl(/* bitrate= */ 200000),
|
||||
createAudioOnlyVariantHlsUrl(/* bitrate= */ 300000),
|
||||
createMuxedVideoAudioVariantHlsUrl(/* bitrate= */ 400000),
|
||||
createMuxedVideoAudioVariantHlsUrl(/* bitrate= */ 600000)),
|
||||
createAudioOnlyVariant(/* bitrate= */ 10000),
|
||||
createMuxedVideoAudioVariant(/* bitrate= */ 200000),
|
||||
createAudioOnlyVariant(/* bitrate= */ 300000),
|
||||
createMuxedVideoAudioVariant(/* bitrate= */ 400000),
|
||||
createMuxedVideoAudioVariant(/* bitrate= */ 600000)),
|
||||
/* audios= */ Arrays.asList(
|
||||
createAudioHlsUrl(/* language= */ "spa"),
|
||||
createAudioHlsUrl(/* language= */ "ger"),
|
||||
createAudioHlsUrl(/* language= */ "tur")),
|
||||
createAudioRendition(/* language= */ "spa"),
|
||||
createAudioRendition(/* language= */ "ger"),
|
||||
createAudioRendition(/* language= */ "tur")),
|
||||
/* subtitles= */ Arrays.asList(
|
||||
createSubtitleHlsUrl(/* language= */ "spa"),
|
||||
createSubtitleHlsUrl(/* language= */ "ger"),
|
||||
createSubtitleHlsUrl(/* language= */ "tur")),
|
||||
createSubtitleRendition(/* language= */ "spa"),
|
||||
createSubtitleRendition(/* language= */ "ger"),
|
||||
createSubtitleRendition(/* language= */ "tur")),
|
||||
/* muxedAudioFormat= */ createAudioFormat("eng"),
|
||||
/* muxedCaptionFormats= */ Arrays.asList(
|
||||
createSubtitleFormat("eng"), createSubtitleFormat("gsw")));
|
||||
|
|
@ -97,9 +98,9 @@ public final class HlsMediaPeriodTest {
|
|||
}
|
||||
|
||||
private static HlsMasterPlaylist createMasterPlaylist(
|
||||
List<HlsUrl> variants,
|
||||
List<HlsUrl> audios,
|
||||
List<HlsUrl> subtitles,
|
||||
List<Variant> variants,
|
||||
List<Rendition> audios,
|
||||
List<Rendition> subtitles,
|
||||
Format muxedAudioFormat,
|
||||
List<Format> muxedCaptionFormats) {
|
||||
return new HlsMasterPlaylist(
|
||||
|
|
@ -115,8 +116,8 @@ public final class HlsMediaPeriodTest {
|
|||
/* sessionKeyDrmInitData= */ Collections.emptyList());
|
||||
}
|
||||
|
||||
private static HlsUrl createMuxedVideoAudioVariantHlsUrl(int bitrate) {
|
||||
return new HlsUrl(
|
||||
private static Variant createMuxedVideoAudioVariant(int bitrate) {
|
||||
return createVariant(
|
||||
"http://url",
|
||||
Format.createVideoContainerFormat(
|
||||
/* id= */ null,
|
||||
|
|
@ -130,12 +131,11 @@ public final class HlsMediaPeriodTest {
|
|||
/* frameRate= */ Format.NO_VALUE,
|
||||
/* initializationData= */ null,
|
||||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0),
|
||||
/* name= */ "");
|
||||
/* roleFlags= */ 0));
|
||||
}
|
||||
|
||||
private static HlsUrl createAudioOnlyVariantHlsUrl(int bitrate) {
|
||||
return new HlsUrl(
|
||||
private static Variant createAudioOnlyVariant(int bitrate) {
|
||||
return createVariant(
|
||||
"http://url",
|
||||
Format.createVideoContainerFormat(
|
||||
/* id= */ null,
|
||||
|
|
@ -149,16 +149,23 @@ public final class HlsMediaPeriodTest {
|
|||
/* frameRate= */ Format.NO_VALUE,
|
||||
/* initializationData= */ null,
|
||||
/* selectionFlags= */ 0,
|
||||
/* roleFlags= */ 0),
|
||||
/* name= */ "");
|
||||
/* roleFlags= */ 0));
|
||||
}
|
||||
|
||||
private static HlsUrl createAudioHlsUrl(String language) {
|
||||
return new HlsUrl("http://url", createAudioFormat(language), /* name= */ "");
|
||||
private static Rendition createAudioRendition(String language) {
|
||||
return createRendition("http://url", createAudioFormat(language), "", "");
|
||||
}
|
||||
|
||||
private static HlsUrl createSubtitleHlsUrl(String language) {
|
||||
return new HlsUrl("http://url", createSubtitleFormat(language), /* name= */ "");
|
||||
private static Rendition createSubtitleRendition(String language) {
|
||||
return createRendition("http://url", createSubtitleFormat(language), "", "");
|
||||
}
|
||||
|
||||
private static Variant createVariant(String url, Format format) {
|
||||
return new Variant(url, format, null, null, null, null);
|
||||
}
|
||||
|
||||
private static Rendition createRendition(String url, Format format, String groupId, String name) {
|
||||
return new Rendition(url, format, groupId, name);
|
||||
}
|
||||
|
||||
private static Format createAudioFormat(String language) {
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public class HlsMasterPlaylistParserTest {
|
|||
|
||||
private static final String PLAYLIST_WITHOUT_CC =
|
||||
" #EXTM3U \n"
|
||||
+ "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,"
|
||||
+ "#EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID=\"cc1\","
|
||||
+ "LANGUAGE=\"es\",NAME=\"Eng\",INSTREAM-ID=\"SERVICE4\"\n"
|
||||
+ "#EXT-X-STREAM-INF:BANDWIDTH=1280000,"
|
||||
+ "CODECS=\"mp4a.40.2,avc1.66.30\",RESOLUTION=304x128,"
|
||||
|
|
@ -150,7 +150,7 @@ public class HlsMasterPlaylistParserTest {
|
|||
public void testParseMasterPlaylist() throws IOException {
|
||||
HlsMasterPlaylist masterPlaylist = parseMasterPlaylist(PLAYLIST_URI, PLAYLIST_SIMPLE);
|
||||
|
||||
List<HlsMasterPlaylist.HlsUrl> variants = masterPlaylist.variants;
|
||||
List<HlsMasterPlaylist.Variant> variants = masterPlaylist.variants;
|
||||
assertThat(variants).hasSize(5);
|
||||
assertThat(masterPlaylist.muxedCaptionFormats).isNull();
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ public class HlsMasterPlaylistParserTest {
|
|||
HlsMasterPlaylist masterPlaylist =
|
||||
parseMasterPlaylist(PLAYLIST_URI, PLAYLIST_WITH_AVG_BANDWIDTH);
|
||||
|
||||
List<HlsMasterPlaylist.HlsUrl> variants = masterPlaylist.variants;
|
||||
List<HlsMasterPlaylist.Variant> variants = masterPlaylist.variants;
|
||||
|
||||
assertThat(variants.get(0).format.bitrate).isEqualTo(1280000);
|
||||
assertThat(variants.get(1).format.bitrate).isEqualTo(1270000);
|
||||
|
|
@ -221,7 +221,7 @@ public class HlsMasterPlaylistParserTest {
|
|||
public void testPlaylistWithChannelsAttribute() throws IOException {
|
||||
HlsMasterPlaylist playlist =
|
||||
parseMasterPlaylist(PLAYLIST_URI, PLAYLIST_WITH_CHANNELS_ATTRIBUTE);
|
||||
List<HlsMasterPlaylist.HlsUrl> audios = playlist.audios;
|
||||
List<HlsMasterPlaylist.Rendition> audios = playlist.audios;
|
||||
assertThat(audios).hasSize(3);
|
||||
assertThat(audios.get(0).format.channelCount).isEqualTo(6);
|
||||
assertThat(audios.get(1).format.channelCount).isEqualTo(2);
|
||||
|
|
|
|||
Loading…
Reference in a new issue