mirror of
				https://github.com/TeamNewPipe/NewPipe
				synced 2025-11-04 09:13:00 +00:00 
			
		
		
		
	-Refactored synchronization checks out from MediaSourceManager to ManagedMediaSource.
-Fixed null input causing potential NPE on PlayQueueItem.
This commit is contained in:
		@@ -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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user