mirror of
https://github.com/TeamNewPipe/NewPipe
synced 2024-12-24 17:10:33 +00:00
-Refactored synchronization checks out from MediaSourceManager to ManagedMediaSource.
-Fixed null input causing potential NPE on PlayQueueItem.
This commit is contained in:
parent
bc7188c8a8
commit
5167fe078b
@ -72,7 +72,13 @@ public class FailedMediaSource implements ManagedMediaSource {
|
|||||||
public void releaseSource() {}
|
public void releaseSource() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(@NonNull final PlayQueueItem newIdentity) {
|
public boolean shouldBeReplacedWith(@NonNull final PlayQueueItem newIdentity,
|
||||||
|
final boolean isInterruptable) {
|
||||||
return newIdentity != playQueueItem || canRetry();
|
return newIdentity != playQueueItem || canRetry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStreamEqual(@NonNull PlayQueueItem stream) {
|
||||||
|
return playQueueItem == stream;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,13 @@ public class LoadedMediaSource implements ManagedMediaSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(@NonNull final PlayQueueItem newIdentity) {
|
public boolean shouldBeReplacedWith(@NonNull PlayQueueItem newIdentity,
|
||||||
return newIdentity != stream || isExpired();
|
final boolean isInterruptable) {
|
||||||
|
return newIdentity != stream || (isInterruptable && isExpired());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStreamEqual(@NonNull PlayQueueItem stream) {
|
||||||
|
return this.stream == stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,5 +7,21 @@ import com.google.android.exoplayer2.source.MediaSource;
|
|||||||
import org.schabi.newpipe.playlist.PlayQueueItem;
|
import org.schabi.newpipe.playlist.PlayQueueItem;
|
||||||
|
|
||||||
public interface ManagedMediaSource extends MediaSource {
|
public interface ManagedMediaSource extends MediaSource {
|
||||||
boolean canReplace(@NonNull final PlayQueueItem newIdentity);
|
/**
|
||||||
|
* Determines whether or not this {@link ManagedMediaSource} can be replaced.
|
||||||
|
*
|
||||||
|
* @param newIdentity a stream the {@link ManagedMediaSource} should encapsulate over, if
|
||||||
|
* it is different from the existing stream in the
|
||||||
|
* {@link ManagedMediaSource}, then it should be replaced.
|
||||||
|
* @param isInterruptable specifies if this {@link ManagedMediaSource} potentially
|
||||||
|
* being played.
|
||||||
|
* */
|
||||||
|
boolean shouldBeReplacedWith(@NonNull final PlayQueueItem newIdentity,
|
||||||
|
final boolean isInterruptable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the {@link PlayQueueItem} is the one the
|
||||||
|
* {@link ManagedMediaSource} encapsulates over.
|
||||||
|
* */
|
||||||
|
boolean isStreamEqual(@NonNull final PlayQueueItem stream);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,13 @@ public class PlaceholderMediaSource implements ManagedMediaSource {
|
|||||||
@Override public void releaseSource() {}
|
@Override public void releaseSource() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canReplace(@NonNull final PlayQueueItem newIdentity) {
|
public boolean shouldBeReplacedWith(@NonNull PlayQueueItem newIdentity,
|
||||||
|
final boolean isInterruptable) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStreamEqual(@NonNull PlayQueueItem stream) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,15 +268,10 @@ public class MediaSourceManager {
|
|||||||
private boolean isPlaybackReady() {
|
private boolean isPlaybackReady() {
|
||||||
if (sources.getSize() != playQueue.size()) return false;
|
if (sources.getSize() != playQueue.size()) return false;
|
||||||
|
|
||||||
final MediaSource mediaSource = sources.getMediaSource(playQueue.getIndex());
|
final ManagedMediaSource mediaSource =
|
||||||
|
(ManagedMediaSource) sources.getMediaSource(playQueue.getIndex());
|
||||||
final PlayQueueItem playQueueItem = playQueue.getItem();
|
final PlayQueueItem playQueueItem = playQueue.getItem();
|
||||||
|
return mediaSource.isStreamEqual(playQueueItem);
|
||||||
if (mediaSource instanceof LoadedMediaSource) {
|
|
||||||
return playQueueItem == ((LoadedMediaSource) mediaSource).getStream();
|
|
||||||
} else if (mediaSource instanceof FailedMediaSource) {
|
|
||||||
return playQueueItem == ((FailedMediaSource) mediaSource).getStream();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void maybeBlock() {
|
private void maybeBlock() {
|
||||||
@ -453,12 +448,8 @@ public class MediaSourceManager {
|
|||||||
if (index == -1 || index >= sources.getSize()) return false;
|
if (index == -1 || index >= sources.getSize()) return false;
|
||||||
|
|
||||||
final ManagedMediaSource mediaSource = (ManagedMediaSource) sources.getMediaSource(index);
|
final ManagedMediaSource mediaSource = (ManagedMediaSource) sources.getMediaSource(index);
|
||||||
|
return mediaSource.shouldBeReplacedWith(item,
|
||||||
if (index == playQueue.getIndex() && mediaSource instanceof LoadedMediaSource) {
|
/*mightBeInProgress=*/index != playQueue.getIndex());
|
||||||
return item != ((LoadedMediaSource) mediaSource).getStream();
|
|
||||||
} else {
|
|
||||||
return mediaSource.canReplace(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -479,7 +470,7 @@ public class MediaSourceManager {
|
|||||||
final ManagedMediaSource currentSource =
|
final ManagedMediaSource currentSource =
|
||||||
(ManagedMediaSource) sources.getMediaSource(currentIndex);
|
(ManagedMediaSource) sources.getMediaSource(currentIndex);
|
||||||
final PlayQueueItem currentItem = playQueue.getItem();
|
final PlayQueueItem currentItem = playQueue.getItem();
|
||||||
if (!currentSource.canReplace(currentItem)) {
|
if (!currentSource.shouldBeReplacedWith(currentItem, /*canInterruptOnRenew=*/true)) {
|
||||||
maybeSynchronizePlayer();
|
maybeSynchronizePlayer();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -11,20 +11,19 @@ import org.schabi.newpipe.util.ExtractorHelper;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
||||||
import io.reactivex.functions.Consumer;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
|
||||||
public class PlayQueueItem implements Serializable {
|
public class PlayQueueItem implements Serializable {
|
||||||
final public static long RECOVERY_UNSET = Long.MIN_VALUE;
|
public final static long RECOVERY_UNSET = Long.MIN_VALUE;
|
||||||
|
private final static String EMPTY_STRING = "";
|
||||||
|
|
||||||
final private String title;
|
@NonNull final private String title;
|
||||||
final private String url;
|
@NonNull final private String url;
|
||||||
final private int serviceId;
|
final private int serviceId;
|
||||||
final private long duration;
|
final private long duration;
|
||||||
final private String thumbnailUrl;
|
@NonNull final private String thumbnailUrl;
|
||||||
final private String uploader;
|
@NonNull final private String uploader;
|
||||||
final private StreamType streamType;
|
@NonNull final private StreamType streamType;
|
||||||
|
|
||||||
private long recoveryPosition;
|
private long recoveryPosition;
|
||||||
private Throwable error;
|
private Throwable error;
|
||||||
@ -42,15 +41,16 @@ public class PlayQueueItem implements Serializable {
|
|||||||
item.getThumbnailUrl(), item.getUploaderName(), item.getStreamType());
|
item.getThumbnailUrl(), item.getUploaderName(), item.getStreamType());
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayQueueItem(final String name, final String url, final int serviceId,
|
private PlayQueueItem(@Nullable final String name, @Nullable final String url,
|
||||||
final long duration, final String thumbnailUrl, final String uploader,
|
final int serviceId, final long duration,
|
||||||
final StreamType streamType) {
|
@Nullable final String thumbnailUrl, @Nullable final String uploader,
|
||||||
this.title = name;
|
@NonNull final StreamType streamType) {
|
||||||
this.url = url;
|
this.title = name != null ? name : EMPTY_STRING;
|
||||||
|
this.url = url != null ? url : EMPTY_STRING;
|
||||||
this.serviceId = serviceId;
|
this.serviceId = serviceId;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
this.thumbnailUrl = thumbnailUrl;
|
this.thumbnailUrl = thumbnailUrl != null ? thumbnailUrl : EMPTY_STRING;
|
||||||
this.uploader = uploader;
|
this.uploader = uploader != null ? uploader : EMPTY_STRING;
|
||||||
this.streamType = streamType;
|
this.streamType = streamType;
|
||||||
|
|
||||||
this.recoveryPosition = RECOVERY_UNSET;
|
this.recoveryPosition = RECOVERY_UNSET;
|
||||||
@ -84,6 +84,7 @@ public class PlayQueueItem implements Serializable {
|
|||||||
return uploader;
|
return uploader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
public StreamType getStreamType() {
|
public StreamType getStreamType() {
|
||||||
return streamType;
|
return streamType;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user