Search in sources :

Example 1 with PlayQueueItem

use of org.schabi.newpipe.playlist.PlayQueueItem in project NewPipe by TeamNewPipe.

the class BasePlayerMediaSession method getQueueMetadata.

@Override
public MediaDescriptionCompat getQueueMetadata(int index) {
    if (player.getPlayQueue() == null || player.getPlayQueue().getItem(index) == null) {
        return null;
    }
    final PlayQueueItem item = player.getPlayQueue().getItem(index);
    MediaDescriptionCompat.Builder descriptionBuilder = new MediaDescriptionCompat.Builder().setMediaId(String.valueOf(index)).setTitle(item.getTitle()).setSubtitle(item.getUploader());
    final Uri thumbnailUri = Uri.parse(item.getThumbnailUrl());
    if (thumbnailUri != null)
        descriptionBuilder.setIconUri(thumbnailUri);
    return descriptionBuilder.build();
}
Also used : PlayQueueItem(org.schabi.newpipe.playlist.PlayQueueItem) Uri(android.net.Uri) MediaDescriptionCompat(android.support.v4.media.MediaDescriptionCompat)

Example 2 with PlayQueueItem

use of org.schabi.newpipe.playlist.PlayQueueItem in project NewPipe by TeamNewPipe.

the class MediaSourceManager method maybeRenewCurrentIndex.

/**
 * Checks if the current playing index contains an expired {@link ManagedMediaSource}.
 * If so, the expired source is replaced by a {@link PlaceholderMediaSource} and
 * {@link #loadImmediate()} is called to reload the current item.
 * <br><br>
 * If not, then the media source at the current index is ready for playback, and
 * {@link #maybeSynchronizePlayer()} is called.
 * <br><br>
 * Under both cases, {@link #maybeSync()} will be called to ensure the listener
 * is up-to-date.
 */
private void maybeRenewCurrentIndex() {
    final int currentIndex = playQueue.getIndex();
    if (sources.getSize() <= currentIndex)
        return;
    final ManagedMediaSource currentSource = (ManagedMediaSource) sources.getMediaSource(currentIndex);
    final PlayQueueItem currentItem = playQueue.getItem();
    if (!currentSource.shouldBeReplacedWith(currentItem, /*canInterruptOnRenew=*/
    true)) {
        maybeSynchronizePlayer();
        return;
    }
    if (DEBUG)
        Log.d(TAG, "MediaSource - Reloading currently playing, " + "index=[" + currentIndex + "], item=[" + currentItem.getTitle() + "]");
    update(currentIndex, new PlaceholderMediaSource(), this::loadImmediate);
}
Also used : PlayQueueItem(org.schabi.newpipe.playlist.PlayQueueItem) PlaceholderMediaSource(org.schabi.newpipe.player.mediasource.PlaceholderMediaSource) ManagedMediaSource(org.schabi.newpipe.player.mediasource.ManagedMediaSource)

Example 3 with PlayQueueItem

use of org.schabi.newpipe.playlist.PlayQueueItem in project NewPipe by TeamNewPipe.

the class MediaSourceManager method maybeSync.

/*//////////////////////////////////////////////////////////////////////////
    // Metadata Synchronization
    //////////////////////////////////////////////////////////////////////////*/
private void maybeSync() {
    if (DEBUG)
        Log.d(TAG, "onPlaybackSynchronize() called.");
    final PlayQueueItem currentItem = playQueue.getItem();
    if (isBlocked.get() || !isPlaybackReady() || currentItem == null)
        return;
    final Consumer<StreamInfo> onSuccess = info -> syncInternal(currentItem, info);
    final Consumer<Throwable> onError = throwable -> syncInternal(currentItem, null);
    final Disposable sync = currentItem.getStream().observeOn(AndroidSchedulers.mainThread()).subscribe(onSuccess, onError);
    syncReactor.set(sync);
}
Also used : DynamicConcatenatingMediaSource(com.google.android.exoplayer2.source.DynamicConcatenatingMediaSource) ManagedMediaSource(org.schabi.newpipe.player.mediasource.ManagedMediaSource) ServiceHelper(org.schabi.newpipe.util.ServiceHelper) SerialDisposable(io.reactivex.disposables.SerialDisposable) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) NonNull(android.support.annotation.NonNull) Single(io.reactivex.Single) AndroidSchedulers(io.reactivex.android.schedulers.AndroidSchedulers) LoadedMediaSource(org.schabi.newpipe.player.mediasource.LoadedMediaSource) StreamInfo(org.schabi.newpipe.extractor.stream.StreamInfo) HashSet(java.util.HashSet) PlaceholderMediaSource(org.schabi.newpipe.player.mediasource.PlaceholderMediaSource) DEBUG(org.schabi.newpipe.playlist.PlayQueue.DEBUG) ShuffleOrder(com.google.android.exoplayer2.source.ShuffleOrder) MoveEvent(org.schabi.newpipe.playlist.events.MoveEvent) Observable(io.reactivex.Observable) PlayQueueItem(org.schabi.newpipe.playlist.PlayQueueItem) Subscriber(org.reactivestreams.Subscriber) Log(android.util.Log) MediaSource(com.google.android.exoplayer2.source.MediaSource) RemoveEvent(org.schabi.newpipe.playlist.events.RemoveEvent) Set(java.util.Set) FailedMediaSource(org.schabi.newpipe.player.mediasource.FailedMediaSource) Consumer(io.reactivex.functions.Consumer) TimeUnit(java.util.concurrent.TimeUnit) ReorderEvent(org.schabi.newpipe.playlist.events.ReorderEvent) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Disposable(io.reactivex.disposables.Disposable) PublishSubject(io.reactivex.subjects.PublishSubject) PlayQueueEvent(org.schabi.newpipe.playlist.events.PlayQueueEvent) Subscription(org.reactivestreams.Subscription) PlayQueue(org.schabi.newpipe.playlist.PlayQueue) Nullable(android.support.annotation.Nullable) Collections(java.util.Collections) EmptySubscription(io.reactivex.internal.subscriptions.EmptySubscription) SerialDisposable(io.reactivex.disposables.SerialDisposable) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Disposable(io.reactivex.disposables.Disposable) PlayQueueItem(org.schabi.newpipe.playlist.PlayQueueItem) StreamInfo(org.schabi.newpipe.extractor.stream.StreamInfo)

Example 4 with PlayQueueItem

use of org.schabi.newpipe.playlist.PlayQueueItem in project NewPipe by TeamNewPipe.

the class PlayerHelper method autoQueueOf.

/**
 * Given a {@link StreamInfo} and the existing queue items, provide the
 * {@link SinglePlayQueue} consisting of the next video for auto queuing.
 * <br><br>
 * This method detects and prevents cycle by naively checking if a
 * candidate next video's url already exists in the existing items.
 * <br><br>
 * To select the next video, {@link StreamInfo#getNextVideo()} is first
 * checked. If it is nonnull and is not part of the existing items, then
 * it will be used as the next video. Otherwise, an random item with
 * non-repeating url will be selected from the {@link StreamInfo#getRelatedStreams()}.
 */
@Nullable
public static PlayQueue autoQueueOf(@NonNull final StreamInfo info, @NonNull final List<PlayQueueItem> existingItems) {
    Set<String> urls = new HashSet<>(existingItems.size());
    for (final PlayQueueItem item : existingItems) {
        urls.add(item.getUrl());
    }
    final StreamInfoItem nextVideo = info.getNextVideo();
    if (nextVideo != null && !urls.contains(nextVideo.getUrl())) {
        return new SinglePlayQueue(nextVideo);
    }
    final List<InfoItem> relatedItems = info.getRelatedStreams();
    if (relatedItems == null)
        return null;
    List<StreamInfoItem> autoQueueItems = new ArrayList<>();
    for (final InfoItem item : info.getRelatedStreams()) {
        if (item instanceof StreamInfoItem && !urls.contains(item.getUrl())) {
            autoQueueItems.add((StreamInfoItem) item);
        }
    }
    Collections.shuffle(autoQueueItems);
    return autoQueueItems.isEmpty() ? null : new SinglePlayQueue(autoQueueItems.get(0));
}
Also used : PlayQueueItem(org.schabi.newpipe.playlist.PlayQueueItem) InfoItem(org.schabi.newpipe.extractor.InfoItem) StreamInfoItem(org.schabi.newpipe.extractor.stream.StreamInfoItem) StreamInfoItem(org.schabi.newpipe.extractor.stream.StreamInfoItem) ArrayList(java.util.ArrayList) SinglePlayQueue(org.schabi.newpipe.playlist.SinglePlayQueue) HashSet(java.util.HashSet) Nullable(android.support.annotation.Nullable)

Example 5 with PlayQueueItem

use of org.schabi.newpipe.playlist.PlayQueueItem in project NewPipe by TeamNewPipe.

the class BasePlayer method maybeCorrectSeekPosition.

private void maybeCorrectSeekPosition() {
    if (playQueue == null || simpleExoPlayer == null || currentInfo == null)
        return;
    final int currentSourceIndex = playQueue.getIndex();
    final PlayQueueItem currentSourceItem = playQueue.getItem();
    if (currentSourceItem == null)
        return;
    final long recoveryPositionMillis = currentSourceItem.getRecoveryPosition();
    final boolean isCurrentWindowCorrect = simpleExoPlayer.getCurrentPeriodIndex() == currentSourceIndex;
    final long presetStartPositionMillis = currentInfo.getStartPosition() * 1000;
    if (recoveryPositionMillis != PlayQueueItem.RECOVERY_UNSET && isCurrentWindowCorrect) {
        // Is recovering previous playback?
        if (DEBUG)
            Log.d(TAG, "Playback - Rewinding to recovery time=" + "[" + getTimeString((int) recoveryPositionMillis) + "]");
        seekTo(recoveryPositionMillis);
        playQueue.unsetRecovery(currentSourceIndex);
    } else if (isSynchronizing && simpleExoPlayer.isCurrentWindowDynamic()) {
        if (DEBUG)
            Log.d(TAG, "Playback - Synchronizing livestream to default time");
        // Is still synchronizing?
        seekToDefault();
    } else if (isSynchronizing && presetStartPositionMillis != 0L) {
        if (DEBUG)
            Log.d(TAG, "Playback - Seeking to preset start " + "position=[" + presetStartPositionMillis + "]");
        // Has another start position?
        seekTo(presetStartPositionMillis);
        currentInfo.setStartPosition(0);
    }
    isSynchronizing = false;
}
Also used : PlayQueueItem(org.schabi.newpipe.playlist.PlayQueueItem)

Aggregations

PlayQueueItem (org.schabi.newpipe.playlist.PlayQueueItem)8 HashSet (java.util.HashSet)3 ManagedMediaSource (org.schabi.newpipe.player.mediasource.ManagedMediaSource)3 Nullable (android.support.annotation.Nullable)2 ArrayList (java.util.ArrayList)2 PlaceholderMediaSource (org.schabi.newpipe.player.mediasource.PlaceholderMediaSource)2 Uri (android.net.Uri)1 NonNull (android.support.annotation.NonNull)1 MediaDescriptionCompat (android.support.v4.media.MediaDescriptionCompat)1 Log (android.util.Log)1 DynamicConcatenatingMediaSource (com.google.android.exoplayer2.source.DynamicConcatenatingMediaSource)1 MediaSource (com.google.android.exoplayer2.source.MediaSource)1 ShuffleOrder (com.google.android.exoplayer2.source.ShuffleOrder)1 Observable (io.reactivex.Observable)1 Single (io.reactivex.Single)1 AndroidSchedulers (io.reactivex.android.schedulers.AndroidSchedulers)1 CompositeDisposable (io.reactivex.disposables.CompositeDisposable)1 Disposable (io.reactivex.disposables.Disposable)1 SerialDisposable (io.reactivex.disposables.SerialDisposable)1 Consumer (io.reactivex.functions.Consumer)1