Merge pull request #3318 from natez0r/pass-playlist-parser

Allow passing of HlsPlaylistParser to HlsMediaSource.
This commit is contained in:
ojw28 2017-10-13 20:29:55 +01:00 committed by GitHub
commit e6d8e5b096
4 changed files with 79 additions and 5 deletions

View File

@ -16,16 +16,20 @@
package com.google.android.exoplayer2.source.hls.playlist; package com.google.android.exoplayer2.source.hls.playlist;
import android.net.Uri; import android.net.Uri;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.ParserException; import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import junit.framework.TestCase;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
import junit.framework.TestCase;
/** /**
* Test for {@link HlsMasterPlaylistParserTest} * Test for {@link HlsMasterPlaylistParserTest}
@ -147,6 +151,44 @@ public class HlsMasterPlaylistParserTest extends TestCase {
assertEquals(Collections.emptyList(), playlist.muxedCaptionFormats); assertEquals(Collections.emptyList(), playlist.muxedCaptionFormats);
} }
public void testReorderedVariantCopy() throws IOException {
HlsMasterPlaylist playlist = parseMasterPlaylist(PLAYLIST_URI, MASTER_PLAYLIST);
HlsMasterPlaylist nonReorderedPlaylist =
playlist.copyWithReorderedVariants(new Comparator<HlsMasterPlaylist.HlsUrl>() {
@Override
public int compare(HlsMasterPlaylist.HlsUrl url1, HlsMasterPlaylist.HlsUrl url2) {
return 0;
}
});
assertEquals(playlist.variants, nonReorderedPlaylist.variants);
HlsMasterPlaylist.HlsUrl preferred = null;
for (HlsMasterPlaylist.HlsUrl url : playlist.variants) {
if (preferred == null || url.format.bitrate > preferred.format.bitrate) {
preferred = url;
}
}
assertNotNull(preferred);
final Comparator comparator = Collections.reverseOrder(new Comparator<HlsMasterPlaylist.HlsUrl>() {
@Override
public int compare(HlsMasterPlaylist.HlsUrl url1, HlsMasterPlaylist.HlsUrl url2) {
if (url1.format.bitrate > url2.format.bitrate) {
return 1;
}
if (url2.format.bitrate > url1.format.bitrate) {
return -1;
}
return 0;
}
});
HlsMasterPlaylist reorderedPlaylist = playlist.copyWithReorderedVariants(comparator);
assertEquals(reorderedPlaylist.variants.get(0), preferred);
}
private static HlsMasterPlaylist parseMasterPlaylist(String uri, String playlistString) private static HlsMasterPlaylist parseMasterPlaylist(String uri, String playlistString)
throws IOException { throws IOException {
Uri playlistUri = Uri.parse(uri); Uri playlistUri = Uri.parse(uri);

View File

@ -26,9 +26,12 @@ import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource; import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.SinglePeriodTimeline; import com.google.android.exoplayer2.source.SinglePeriodTimeline;
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.HlsPlaylistParser;
import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker; import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.upstream.Allocator; import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
@ -52,6 +55,7 @@ public final class HlsMediaSource implements MediaSource,
private final HlsDataSourceFactory dataSourceFactory; private final HlsDataSourceFactory dataSourceFactory;
private final int minLoadableRetryCount; private final int minLoadableRetryCount;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final ParsingLoadable.Parser<HlsPlaylist> playlistParser;
private HlsPlaylistTracker playlistTracker; private HlsPlaylistTracker playlistTracker;
private Listener sourceListener; private Listener sourceListener;
@ -72,9 +76,17 @@ public final class HlsMediaSource implements MediaSource,
public HlsMediaSource(Uri manifestUri, HlsDataSourceFactory dataSourceFactory, public HlsMediaSource(Uri manifestUri, HlsDataSourceFactory dataSourceFactory,
int minLoadableRetryCount, Handler eventHandler, int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener) { AdaptiveMediaSourceEventListener eventListener) {
this(manifestUri, dataSourceFactory, minLoadableRetryCount, eventHandler, eventListener, new HlsPlaylistParser());
}
public HlsMediaSource(Uri manifestUri, HlsDataSourceFactory dataSourceFactory,
int minLoadableRetryCount, Handler eventHandler,
AdaptiveMediaSourceEventListener eventListener,
ParsingLoadable.Parser<HlsPlaylist> playlistParser) {
this.manifestUri = manifestUri; this.manifestUri = manifestUri;
this.dataSourceFactory = dataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.minLoadableRetryCount = minLoadableRetryCount; this.minLoadableRetryCount = minLoadableRetryCount;
this.playlistParser = playlistParser;
eventDispatcher = new EventDispatcher(eventHandler, eventListener); eventDispatcher = new EventDispatcher(eventHandler, eventListener);
} }
@ -82,7 +94,7 @@ public final class HlsMediaSource implements MediaSource,
public void prepareSource(ExoPlayer player, boolean isTopLevelSource, Listener listener) { public void prepareSource(ExoPlayer player, boolean isTopLevelSource, Listener listener) {
Assertions.checkState(playlistTracker == null); Assertions.checkState(playlistTracker == null);
playlistTracker = new HlsPlaylistTracker(manifestUri, dataSourceFactory, eventDispatcher, playlistTracker = new HlsPlaylistTracker(manifestUri, dataSourceFactory, eventDispatcher,
minLoadableRetryCount, this); minLoadableRetryCount, this, playlistParser);
sourceListener = listener; sourceListener = listener;
playlistTracker.start(); playlistTracker.start();
} }

View File

@ -19,6 +19,7 @@ import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
/** /**
@ -123,6 +124,25 @@ public final class HlsMasterPlaylist extends HlsPlaylist {
muxedAudioFormat, muxedCaptionFormats); muxedAudioFormat, muxedCaptionFormats);
} }
/**
* Returns a copy of this playlist which includes the variants sorted using the passed comparator. NOTE: the variants
* will be sorted in ascending order by default. If you wish to use descending order, you can wrap your comparator in
* {@link Collections#reverseOrder(Comparator)}.
*
* @param variantComparator the comparator to use to sort the variant list.
* @return a copy of this playlist which includes the variants sorted using the passed comparator.
*/
public HlsMasterPlaylist copyWithReorderedVariants(Comparator<HlsUrl> variantComparator) {
return new HlsMasterPlaylist(baseUri, tags, filterVariants(variants, variantComparator), audios,
subtitles, muxedAudioFormat, muxedCaptionFormats);
}
private List<HlsUrl> filterVariants(List<HlsUrl> variants, Comparator<HlsUrl> variantComparator) {
List<HlsUrl> reorderedList = new ArrayList<>(variants);
Collections.sort(reorderedList, variantComparator);
return reorderedList;
}
/** /**
* Creates a playlist with a single variant. * Creates a playlist with a single variant.
* *

View File

@ -115,7 +115,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
private final Uri initialPlaylistUri; private final Uri initialPlaylistUri;
private final HlsDataSourceFactory dataSourceFactory; private final HlsDataSourceFactory dataSourceFactory;
private final HlsPlaylistParser playlistParser; private final ParsingLoadable.Parser<HlsPlaylist> playlistParser;
private final int minRetryCount; private final int minRetryCount;
private final IdentityHashMap<HlsUrl, MediaPlaylistBundle> playlistBundles; private final IdentityHashMap<HlsUrl, MediaPlaylistBundle> playlistBundles;
private final Handler playlistRefreshHandler; private final Handler playlistRefreshHandler;
@ -140,7 +140,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
*/ */
public HlsPlaylistTracker(Uri initialPlaylistUri, HlsDataSourceFactory dataSourceFactory, public HlsPlaylistTracker(Uri initialPlaylistUri, HlsDataSourceFactory dataSourceFactory,
EventDispatcher eventDispatcher, int minRetryCount, EventDispatcher eventDispatcher, int minRetryCount,
PrimaryPlaylistListener primaryPlaylistListener) { PrimaryPlaylistListener primaryPlaylistListener, ParsingLoadable.Parser<HlsPlaylist> playlistParser) {
this.initialPlaylistUri = initialPlaylistUri; this.initialPlaylistUri = initialPlaylistUri;
this.dataSourceFactory = dataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.eventDispatcher = eventDispatcher; this.eventDispatcher = eventDispatcher;
@ -148,7 +148,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
this.primaryPlaylistListener = primaryPlaylistListener; this.primaryPlaylistListener = primaryPlaylistListener;
listeners = new ArrayList<>(); listeners = new ArrayList<>();
initialPlaylistLoader = new Loader("HlsPlaylistTracker:MasterPlaylist"); initialPlaylistLoader = new Loader("HlsPlaylistTracker:MasterPlaylist");
playlistParser = new HlsPlaylistParser(); this.playlistParser = playlistParser;
playlistBundles = new IdentityHashMap<>(); playlistBundles = new IdentityHashMap<>();
playlistRefreshHandler = new Handler(); playlistRefreshHandler = new Handler();
} }