Search in sources :

Example 1 with InfoItem

use of org.schabi.newpipe.extractor.InfoItem 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 2 with InfoItem

use of org.schabi.newpipe.extractor.InfoItem in project NewPipe by TeamNewPipe.

the class FeedFragment method getChannelInfoObserver.

/**
 * On each request, a subscription item from the updated table is transformed
 * into a ChannelInfo, containing the latest streams from the channel.
 * <p>
 * Currently, the feed uses the first into from the list of streams.
 * <p>
 * If chosen feed already displayed, then we request another feed from another
 * subscription, until the subscription table runs out of new items.
 * <p>
 * This Observer is self-contained and will dispose itself when complete. However, this
 * does not obey the fragment lifecycle and may continue running in the background
 * until it is complete. This is done due to RxJava2 no longer propagate errors once
 * an observer is unsubscribed while the thread process is still running.
 * <p>
 * To solve the above issue, we can either set a global RxJava Error Handler, or
 * manage exceptions case by case. This should be done if the current implementation is
 * too costly when dealing with larger subscription sets.
 *
 * @param url + serviceId to put in {@link #allItemsLoaded} to signal that this specific entity has been loaded.
 */
private MaybeObserver<ChannelInfo> getChannelInfoObserver(final int serviceId, final String url) {
    return new MaybeObserver<ChannelInfo>() {

        private Disposable observer;

        @Override
        public void onSubscribe(Disposable d) {
            observer = d;
            compositeDisposable.add(d);
            isLoading.set(true);
        }

        // Called only when response is non-empty
        @Override
        public void onSuccess(final ChannelInfo channelInfo) {
            if (infoListAdapter == null || channelInfo.getRelatedItems().isEmpty()) {
                onDone();
                return;
            }
            final InfoItem item = channelInfo.getRelatedItems().get(0);
            // Keep requesting new items if the current one already exists
            boolean itemExists = doesItemExist(infoListAdapter.getItemsList(), item);
            if (!itemExists) {
                infoListAdapter.addInfoItem(item);
            // updateSubscription(channelInfo);
            } else {
                requestFeed(1);
            }
            onDone();
        }

        @Override
        public void onError(Throwable exception) {
            showSnackBarError(exception, UserAction.SUBSCRIPTION, NewPipe.getNameOfService(serviceId), url, 0);
            requestFeed(1);
            onDone();
        }

        // Called only when response is empty
        @Override
        public void onComplete() {
            onDone();
        }

        private void onDone() {
            if (observer.isDisposed()) {
                return;
            }
            itemsLoaded.add(serviceId + url);
            compositeDisposable.remove(observer);
            int loaded = requestLoadedAtomic.incrementAndGet();
            if (loaded >= Math.min(FEED_LOAD_COUNT, subscriptionPoolSize)) {
                requestLoadedAtomic.set(0);
                isLoading.set(false);
            }
            if (itemsLoaded.size() == subscriptionPoolSize) {
                if (DEBUG)
                    Log.d(TAG, "getChannelInfoObserver > All Items Loaded");
                allItemsLoaded.set(true);
                showListFooter(false);
                isLoading.set(false);
                hideLoading();
                if (infoListAdapter.getItemsList().size() == 0) {
                    showEmptyState();
                }
            }
        }
    };
}
Also used : CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Disposable(io.reactivex.disposables.Disposable) MaybeObserver(io.reactivex.MaybeObserver) InfoItem(org.schabi.newpipe.extractor.InfoItem) ChannelInfo(org.schabi.newpipe.extractor.channel.ChannelInfo)

Example 3 with InfoItem

use of org.schabi.newpipe.extractor.InfoItem in project NewPipe by TeamNewPipe.

the class SubscriptionFragment method getSubscriptionItems.

private List<InfoItem> getSubscriptionItems(List<SubscriptionEntity> subscriptions) {
    List<InfoItem> items = new ArrayList<>();
    for (final SubscriptionEntity subscription : subscriptions) items.add(subscription.toChannelInfoItem());
    Collections.sort(items, (InfoItem o1, InfoItem o2) -> o1.getName().compareToIgnoreCase(o2.getName()));
    return items;
}
Also used : ChannelInfoItem(org.schabi.newpipe.extractor.channel.ChannelInfoItem) InfoItem(org.schabi.newpipe.extractor.InfoItem) ArrayList(java.util.ArrayList) SubscriptionEntity(org.schabi.newpipe.database.subscription.SubscriptionEntity)

Example 4 with InfoItem

use of org.schabi.newpipe.extractor.InfoItem in project NewPipe by TeamNewPipe.

the class VideoItemDetailFragment method initSimilarVideos.

private void initSimilarVideos(final StreamInfo info) {
    LinearLayout similarLayout = (LinearLayout) activity.findViewById(R.id.similar_streams_view);
    for (final InfoItem item : info.related_streams) {
        similarLayout.addView(infoItemBuilder.buildView(similarLayout, item));
    }
    infoItemBuilder.setOnStreamInfoItemSelectedListener(new InfoItemBuilder.OnInfoItemSelectedListener() {

        @Override
        public void selected(String url, int serviceId) {
            NavStack.getInstance().openDetailActivity(getContext(), url, serviceId);
        }
    });
}
Also used : InfoItem(org.schabi.newpipe.extractor.InfoItem) InfoItemBuilder(org.schabi.newpipe.info_list.InfoItemBuilder) LinearLayout(android.widget.LinearLayout) Point(android.graphics.Point)

Example 5 with InfoItem

use of org.schabi.newpipe.extractor.InfoItem in project NewPipe by TeamNewPipe.

the class VideoDetailFragment method initRelatedVideos.

private void initRelatedVideos(StreamInfo info) {
    if (relatedStreamsView.getChildCount() > 0)
        relatedStreamsView.removeAllViews();
    if (info.getNextVideo() != null && showRelatedStreams) {
        nextStreamTitle.setVisibility(View.VISIBLE);
        relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, info.getNextVideo()));
        relatedStreamsView.addView(getSeparatorView());
        relatedStreamRootLayout.setVisibility(View.VISIBLE);
    } else
        nextStreamTitle.setVisibility(View.GONE);
    if (info.getRelatedStreams() != null && !info.getRelatedStreams().isEmpty() && showRelatedStreams) {
        // long first = System.nanoTime(), each;
        int to = info.getRelatedStreams().size() >= INITIAL_RELATED_VIDEOS ? INITIAL_RELATED_VIDEOS : info.getRelatedStreams().size();
        for (int i = 0; i < to; i++) {
            InfoItem item = info.getRelatedStreams().get(i);
            // each = System.nanoTime();
            relatedStreamsView.addView(infoItemBuilder.buildView(relatedStreamsView, item));
        // if (DEBUG) Log.d(TAG, "each took " + ((System.nanoTime() - each) / 1000000L) + "ms");
        }
        // if (DEBUG) Log.d(TAG, "Total time " + ((System.nanoTime() - first) / 1000000L) + "ms");
        relatedStreamRootLayout.setVisibility(View.VISIBLE);
        relatedStreamExpandButton.setVisibility(View.VISIBLE);
        relatedStreamExpandButton.setImageDrawable(ContextCompat.getDrawable(activity, ThemeHelper.resolveResourceIdFromAttr(activity, R.attr.expand)));
    } else {
        if (info.getNextVideo() == null)
            relatedStreamRootLayout.setVisibility(View.GONE);
        relatedStreamExpandButton.setVisibility(View.GONE);
    }
}
Also used : InfoItem(org.schabi.newpipe.extractor.InfoItem) StreamInfoItem(org.schabi.newpipe.extractor.stream.StreamInfoItem)

Aggregations

InfoItem (org.schabi.newpipe.extractor.InfoItem)6 StreamInfoItem (org.schabi.newpipe.extractor.stream.StreamInfoItem)3 ArrayList (java.util.ArrayList)2 Point (android.graphics.Point)1 Nullable (android.support.annotation.Nullable)1 LinearLayout (android.widget.LinearLayout)1 MaybeObserver (io.reactivex.MaybeObserver)1 CompositeDisposable (io.reactivex.disposables.CompositeDisposable)1 Disposable (io.reactivex.disposables.Disposable)1 HashSet (java.util.HashSet)1 SubscriptionEntity (org.schabi.newpipe.database.subscription.SubscriptionEntity)1 ChannelInfo (org.schabi.newpipe.extractor.channel.ChannelInfo)1 ChannelInfoItem (org.schabi.newpipe.extractor.channel.ChannelInfoItem)1 InfoItemBuilder (org.schabi.newpipe.info_list.InfoItemBuilder)1 PlayQueueItem (org.schabi.newpipe.playlist.PlayQueueItem)1 SinglePlayQueue (org.schabi.newpipe.playlist.SinglePlayQueue)1