-Fixed potential NPE when obtaining broadcast receiver.
-Extracted expiration time in media source manager. -Re-enabled long click on live stream info items. -Fixed dash source building to use mpd instead of extractor.
This commit is contained in:
parent
ac431e3ece
commit
1444fe5468
|
@ -59,23 +59,20 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
|||
itemBuilder.getImageLoader()
|
||||
.displayImage(item.thumbnail_url, itemThumbnailView, StreamInfoItemHolder.DISPLAY_THUMBNAIL_OPTIONS);
|
||||
|
||||
itemView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if (itemBuilder.getOnStreamSelectedListener() != null) {
|
||||
itemBuilder.getOnStreamSelectedListener().selected(item);
|
||||
}
|
||||
itemView.setOnClickListener(view -> {
|
||||
if (itemBuilder.getOnStreamSelectedListener() != null) {
|
||||
itemBuilder.getOnStreamSelectedListener().selected(item);
|
||||
}
|
||||
});
|
||||
|
||||
switch (item.stream_type) {
|
||||
case AUDIO_STREAM:
|
||||
case VIDEO_STREAM:
|
||||
case FILE:
|
||||
enableLongClick(item);
|
||||
break;
|
||||
case LIVE_STREAM:
|
||||
case AUDIO_LIVE_STREAM:
|
||||
enableLongClick(item);
|
||||
break;
|
||||
case FILE:
|
||||
case NONE:
|
||||
default:
|
||||
disableLongClick();
|
||||
|
@ -85,14 +82,11 @@ public class StreamMiniInfoItemHolder extends InfoItemHolder {
|
|||
|
||||
private void enableLongClick(final StreamInfoItem item) {
|
||||
itemView.setLongClickable(true);
|
||||
itemView.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View view) {
|
||||
if (itemBuilder.getOnStreamSelectedListener() != null) {
|
||||
itemBuilder.getOnStreamSelectedListener().held(item);
|
||||
}
|
||||
return true;
|
||||
itemView.setOnLongClickListener(view -> {
|
||||
if (itemBuilder.getOnStreamSelectedListener() != null) {
|
||||
itemBuilder.getOnStreamSelectedListener().held(item);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -319,35 +319,27 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
|||
recordManager = null;
|
||||
}
|
||||
|
||||
public MediaSource buildMediaSource(String url) {
|
||||
return buildMediaSource(url, "");
|
||||
}
|
||||
|
||||
public MediaSource buildMediaSource(String url, String overrideExtension) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "buildMediaSource() called with: url = [" + url + "], overrideExtension = [" + overrideExtension + "]");
|
||||
Log.d(TAG, "buildMediaSource() called with: url = [" + url +
|
||||
"], overrideExtension = [" + overrideExtension + "]");
|
||||
}
|
||||
Uri uri = Uri.parse(url);
|
||||
int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(uri) : Util.inferContentType("." + overrideExtension);
|
||||
MediaSource mediaSource;
|
||||
int type = TextUtils.isEmpty(overrideExtension) ? Util.inferContentType(uri) :
|
||||
Util.inferContentType("." + overrideExtension);
|
||||
switch (type) {
|
||||
case C.TYPE_SS:
|
||||
mediaSource = ssMediaSourceFactory.createMediaSource(uri);
|
||||
break;
|
||||
return ssMediaSourceFactory.createMediaSource(uri);
|
||||
case C.TYPE_DASH:
|
||||
mediaSource = dashMediaSourceFactory.createMediaSource(uri);
|
||||
break;
|
||||
return dashMediaSourceFactory.createMediaSource(uri);
|
||||
case C.TYPE_HLS:
|
||||
mediaSource = hlsMediaSourceFactory.createMediaSource(uri);
|
||||
break;
|
||||
return hlsMediaSourceFactory.createMediaSource(uri);
|
||||
case C.TYPE_OTHER:
|
||||
mediaSource = extractorMediaSourceFactory.createMediaSource(uri);
|
||||
break;
|
||||
return extractorMediaSourceFactory.createMediaSource(uri);
|
||||
default: {
|
||||
throw new IllegalStateException("Unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
return mediaSource;
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -514,8 +506,13 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
|||
public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {
|
||||
if (DEBUG) Log.d(TAG, "onTimelineChanged(), timeline size = " + timeline.getWindowCount());
|
||||
|
||||
if (playbackManager != null) {
|
||||
playbackManager.load();
|
||||
switch (reason) {
|
||||
case Player.TIMELINE_CHANGE_REASON_PREPARED:
|
||||
case Player.TIMELINE_CHANGE_REASON_RESET:
|
||||
case Player.TIMELINE_CHANGE_REASON_DYNAMIC:
|
||||
default:
|
||||
if (playbackManager != null) playbackManager.load();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -526,7 +523,8 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
|||
|
||||
@Override
|
||||
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
|
||||
if (DEBUG) Log.d(TAG, "playbackParameters(), speed: " + playbackParameters.speed + ", pitch: " + playbackParameters.pitch);
|
||||
if (DEBUG) Log.d(TAG, "playbackParameters(), speed: " + playbackParameters.speed +
|
||||
", pitch: " + playbackParameters.pitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -732,9 +730,9 @@ public abstract class BasePlayer implements Player.EventListener, PlaybackListen
|
|||
@Override
|
||||
public MediaSource sourceOf(PlayQueueItem item, StreamInfo info) {
|
||||
if (!info.getHlsUrl().isEmpty()) {
|
||||
return buildMediaSource(info.getHlsUrl());
|
||||
return buildMediaSource(info.getHlsUrl(), "m3u8");
|
||||
} else if (!info.getDashMpdUrl().isEmpty()) {
|
||||
return buildMediaSource(info.getDashMpdUrl());
|
||||
return buildMediaSource(info.getDashMpdUrl(), "mpd");
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -25,6 +25,10 @@ public class FailedMediaSource implements ManagedMediaSource {
|
|||
this.retryTimestamp = retryTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permanently fail the play queue item associated with this source, with no hope of retrying.
|
||||
* The error will always be propagated to ExoPlayer.
|
||||
* */
|
||||
public FailedMediaSource(@NonNull final PlayQueueItem playQueueItem,
|
||||
@NonNull final Throwable error) {
|
||||
this.playQueueItem = playQueueItem;
|
||||
|
|
|
@ -40,6 +40,8 @@ public class MediaSourceManager {
|
|||
private final int windowSize;
|
||||
private final PlaybackListener playbackListener;
|
||||
private final PlayQueue playQueue;
|
||||
private final long expirationTimeMillis;
|
||||
private final TimeUnit expirationTimeUnit;
|
||||
|
||||
// Process only the last load order when receiving a stream of load orders (lessens I/O)
|
||||
// The higher it is, the less loading occurs during rapid noncritical timeline changes
|
||||
|
@ -61,13 +63,15 @@ public class MediaSourceManager {
|
|||
|
||||
public MediaSourceManager(@NonNull final PlaybackListener listener,
|
||||
@NonNull final PlayQueue playQueue) {
|
||||
this(listener, playQueue, 1, 400L);
|
||||
this(listener, playQueue, 1, 400L, 2, TimeUnit.HOURS);
|
||||
}
|
||||
|
||||
private MediaSourceManager(@NonNull final PlaybackListener listener,
|
||||
@NonNull final PlayQueue playQueue,
|
||||
final int windowSize,
|
||||
final long loadDebounceMillis) {
|
||||
final long loadDebounceMillis,
|
||||
final long expirationTimeMillis,
|
||||
@NonNull final TimeUnit expirationTimeUnit) {
|
||||
if (windowSize <= 0) {
|
||||
throw new UnsupportedOperationException(
|
||||
"MediaSourceManager window size must be greater than 0");
|
||||
|
@ -77,6 +81,8 @@ public class MediaSourceManager {
|
|||
this.playQueue = playQueue;
|
||||
this.windowSize = windowSize;
|
||||
this.loadDebounceMillis = loadDebounceMillis;
|
||||
this.expirationTimeMillis = expirationTimeMillis;
|
||||
this.expirationTimeUnit = expirationTimeUnit;
|
||||
|
||||
this.loaderReactor = new CompositeDisposable();
|
||||
this.debouncedLoadSignal = PublishSubject.create();
|
||||
|
@ -87,9 +93,11 @@ public class MediaSourceManager {
|
|||
this.syncReactor = new SerialDisposable();
|
||||
this.loadingItems = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
playQueue.getBroadcastReceiver()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getReactor());
|
||||
if (playQueue.getBroadcastReceiver() != null) {
|
||||
playQueue.getBroadcastReceiver()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(getReactor());
|
||||
}
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -225,7 +233,7 @@ public class MediaSourceManager {
|
|||
return playQueue.isComplete() || isWindowLoaded;
|
||||
}
|
||||
|
||||
// Checks if the current playback media source is a placeholder, if so, then it is not ready
|
||||
// Checks if the current playback media source is a placeholder, if so, then it is not ready.
|
||||
private boolean isPlaybackReady() {
|
||||
return sources != null && playQueue != null && sources.getSize() > playQueue.getIndex() &&
|
||||
!(sources.getMediaSource(playQueue.getIndex()) instanceof PlaceholderMediaSource);
|
||||
|
@ -351,11 +359,11 @@ public class MediaSourceManager {
|
|||
final MediaSource source = playbackListener.sourceOf(stream, streamInfo);
|
||||
if (source == null) {
|
||||
return new FailedMediaSource(stream, new IllegalStateException(
|
||||
"MediaSource resolution is null"));
|
||||
"MediaSource cannot be resolved"));
|
||||
}
|
||||
|
||||
final long expiration = System.currentTimeMillis() +
|
||||
TimeUnit.MILLISECONDS.convert(2, TimeUnit.HOURS);
|
||||
TimeUnit.MILLISECONDS.convert(expirationTimeMillis, expirationTimeUnit);
|
||||
return new LoadedMediaSource(source, expiration);
|
||||
}).onErrorReturn(throwable -> new FailedMediaSource(stream, throwable));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package org.schabi.newpipe.playlist;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
@ -170,7 +171,7 @@ public abstract class PlayQueue implements Serializable {
|
|||
* Returns the play queue's update broadcast.
|
||||
* May be null if the play queue message bus is not initialized.
|
||||
* */
|
||||
@NonNull
|
||||
@Nullable
|
||||
public Flowable<PlayQueueEvent> getBroadcastReceiver() {
|
||||
return broadcastReceiver;
|
||||
}
|
||||
|
|
|
@ -99,7 +99,9 @@ public class PlayQueueAdapter extends RecyclerView.Adapter<RecyclerView.ViewHold
|
|||
}
|
||||
};
|
||||
|
||||
playQueue.getBroadcastReceiver().toObservable().subscribe(observer);
|
||||
if (playQueue.getBroadcastReceiver() != null) {
|
||||
playQueue.getBroadcastReceiver().toObservable().subscribe(observer);
|
||||
}
|
||||
}
|
||||
|
||||
private void onPlayQueueChanged(final PlayQueueEvent message) {
|
||||
|
|
Loading…
Reference in New Issue