mirror of
https://github.com/samsonjs/media.git
synced 2026-06-29 05:39:31 +00:00
Prevent unnecessary consecutive playlist loads
------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=170078933
This commit is contained in:
parent
d8ceef1038
commit
e7d6f1a2ce
1 changed files with 43 additions and 26 deletions
|
|
@ -364,9 +364,8 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||
*
|
||||
* @param url The url of the playlist.
|
||||
* @param newSnapshot The new snapshot.
|
||||
* @return True if a refresh should be scheduled.
|
||||
*/
|
||||
private boolean onPlaylistUpdated(HlsUrl url, HlsMediaPlaylist newSnapshot) {
|
||||
private void onPlaylistUpdated(HlsUrl url, HlsMediaPlaylist newSnapshot) {
|
||||
if (url == primaryHlsUrl) {
|
||||
if (primaryUrlSnapshot == null) {
|
||||
// This is the first primary url snapshot.
|
||||
|
|
@ -379,8 +378,6 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||
for (int i = 0; i < listenersSize; i++) {
|
||||
listeners.get(i).onPlaylistChanged();
|
||||
}
|
||||
// If the primary playlist is not the final one, we should schedule a refresh.
|
||||
return url == primaryHlsUrl && !newSnapshot.hasEndTag;
|
||||
}
|
||||
|
||||
private void notifyPlaylistBlacklisting(HlsUrl url, long blacklistMs) {
|
||||
|
|
@ -470,8 +467,9 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||
private HlsMediaPlaylist playlistSnapshot;
|
||||
private long lastSnapshotLoadMs;
|
||||
private long lastSnapshotChangeMs;
|
||||
private long earliestNextLoadTimeMs;
|
||||
private long blacklistUntilMs;
|
||||
private boolean pendingRefresh;
|
||||
private boolean loadPending;
|
||||
private IOException playlistError;
|
||||
|
||||
public MediaPlaylistBundle(HlsUrl playlistUrl) {
|
||||
|
|
@ -505,8 +503,16 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||
|
||||
public void loadPlaylist() {
|
||||
blacklistUntilMs = 0;
|
||||
if (!pendingRefresh && !mediaPlaylistLoader.isLoading()) {
|
||||
mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount);
|
||||
if (loadPending || mediaPlaylistLoader.isLoading()) {
|
||||
// Load already pending or in progress. Do nothing.
|
||||
return;
|
||||
}
|
||||
long currentTimeMs = SystemClock.elapsedRealtime();
|
||||
if (currentTimeMs < earliestNextLoadTimeMs) {
|
||||
loadPending = true;
|
||||
playlistRefreshHandler.postDelayed(this, earliestNextLoadTimeMs - currentTimeMs);
|
||||
} else {
|
||||
loadPlaylistImmediately();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -550,8 +556,7 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||
}
|
||||
boolean shouldRetry = true;
|
||||
if (ChunkedTrackBlacklistUtil.shouldBlacklist(error)) {
|
||||
blacklistPlaylist();
|
||||
shouldRetry = primaryHlsUrl == playlistUrl && !maybeSelectNewPrimaryUrl();
|
||||
shouldRetry = blacklistPlaylist();
|
||||
}
|
||||
return shouldRetry ? Loader.RETRY : Loader.DONT_RETRY;
|
||||
}
|
||||
|
|
@ -560,48 +565,60 @@ public final class HlsPlaylistTracker implements Loader.Callback<ParsingLoadable
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
pendingRefresh = false;
|
||||
loadPlaylist();
|
||||
loadPending = false;
|
||||
loadPlaylistImmediately();
|
||||
}
|
||||
|
||||
// Internal methods.
|
||||
|
||||
private void loadPlaylistImmediately() {
|
||||
mediaPlaylistLoader.startLoading(mediaPlaylistLoadable, this, minRetryCount);
|
||||
}
|
||||
|
||||
private void processLoadedPlaylist(HlsMediaPlaylist loadedPlaylist) {
|
||||
HlsMediaPlaylist oldPlaylist = playlistSnapshot;
|
||||
long currentTimeMs = SystemClock.elapsedRealtime();
|
||||
lastSnapshotLoadMs = currentTimeMs;
|
||||
playlistSnapshot = getLatestPlaylistSnapshot(oldPlaylist, loadedPlaylist);
|
||||
long refreshDelayUs = C.TIME_UNSET;
|
||||
if (playlistSnapshot != oldPlaylist) {
|
||||
playlistError = null;
|
||||
lastSnapshotChangeMs = currentTimeMs;
|
||||
if (onPlaylistUpdated(playlistUrl, playlistSnapshot)) {
|
||||
refreshDelayUs = playlistSnapshot.targetDurationUs;
|
||||
}
|
||||
onPlaylistUpdated(playlistUrl, playlistSnapshot);
|
||||
} else if (!playlistSnapshot.hasEndTag) {
|
||||
if (currentTimeMs - lastSnapshotChangeMs
|
||||
if (loadedPlaylist.mediaSequence + loadedPlaylist.segments.size()
|
||||
< playlistSnapshot.mediaSequence) {
|
||||
// The media sequence jumped backwards. The server has probably reset.
|
||||
playlistError = new PlaylistResetException(playlistUrl.url);
|
||||
} else if (currentTimeMs - lastSnapshotChangeMs
|
||||
> C.usToMs(playlistSnapshot.targetDurationUs)
|
||||
* PLAYLIST_STUCK_TARGET_DURATION_COEFFICIENT) {
|
||||
// The playlist seems to be stuck, we blacklist it.
|
||||
// The playlist seems to be stuck. Blacklist it.
|
||||
playlistError = new PlaylistStuckException(playlistUrl.url);
|
||||
blacklistPlaylist();
|
||||
} else if (loadedPlaylist.mediaSequence + loadedPlaylist.segments.size()
|
||||
< playlistSnapshot.mediaSequence) {
|
||||
// The media sequence has jumped backwards. The server has likely reset.
|
||||
playlistError = new PlaylistResetException(playlistUrl.url);
|
||||
}
|
||||
refreshDelayUs = playlistSnapshot.targetDurationUs / 2;
|
||||
}
|
||||
if (refreshDelayUs != C.TIME_UNSET) {
|
||||
// See HLS spec v20, section 6.3.4 for more information on media playlist refreshing.
|
||||
pendingRefresh = playlistRefreshHandler.postDelayed(this, C.usToMs(refreshDelayUs));
|
||||
// Do not allow the playlist to load again within the target duration if we obtained a new
|
||||
// snapshot, or half the target duration otherwise.
|
||||
earliestNextLoadTimeMs = currentTimeMs + C.usToMs(playlistSnapshot != oldPlaylist
|
||||
? playlistSnapshot.targetDurationUs : (playlistSnapshot.targetDurationUs / 2));
|
||||
// Schedule a load if this is the primary playlist and it doesn't have an end tag. Else the
|
||||
// next load will be scheduled when refreshPlaylist is called, or when this playlist becomes
|
||||
// the primary.
|
||||
if (playlistUrl == primaryHlsUrl && !playlistSnapshot.hasEndTag) {
|
||||
loadPlaylist();
|
||||
}
|
||||
}
|
||||
|
||||
private void blacklistPlaylist() {
|
||||
/**
|
||||
* Blacklists the playlist.
|
||||
*
|
||||
* @return Whether the playlist is the primary, despite being blacklisted.
|
||||
*/
|
||||
private boolean blacklistPlaylist() {
|
||||
blacklistUntilMs = SystemClock.elapsedRealtime()
|
||||
+ ChunkedTrackBlacklistUtil.DEFAULT_TRACK_BLACKLIST_MS;
|
||||
notifyPlaylistBlacklisting(playlistUrl, ChunkedTrackBlacklistUtil.DEFAULT_TRACK_BLACKLIST_MS);
|
||||
return primaryHlsUrl == playlistUrl && !maybeSelectNewPrimaryUrl();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue