2017-08-29 02:38:37 +02:00
|
|
|
package org.schabi.newpipe.playlist;
|
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
import android.util.Log;
|
|
|
|
|
2017-08-29 02:38:37 +02:00
|
|
|
import org.schabi.newpipe.extractor.InfoItem;
|
2017-09-05 00:38:58 +02:00
|
|
|
import org.schabi.newpipe.extractor.ListExtractor;
|
2017-09-04 19:23:56 +02:00
|
|
|
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
|
|
|
import org.schabi.newpipe.util.ExtractorHelper;
|
2017-08-29 02:38:37 +02:00
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2017-08-31 19:07:18 +02:00
|
|
|
import java.util.Collections;
|
2017-08-29 02:38:37 +02:00
|
|
|
import java.util.List;
|
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
import io.reactivex.SingleObserver;
|
2017-08-29 02:38:37 +02:00
|
|
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
2017-09-04 19:23:56 +02:00
|
|
|
import io.reactivex.annotations.NonNull;
|
2017-08-31 19:07:18 +02:00
|
|
|
import io.reactivex.disposables.Disposable;
|
2017-08-29 02:38:37 +02:00
|
|
|
import io.reactivex.schedulers.Schedulers;
|
|
|
|
|
2017-09-05 21:27:12 +02:00
|
|
|
public final class ExternalPlayQueue extends PlayQueue {
|
2017-08-31 19:07:18 +02:00
|
|
|
private final String TAG = "ExternalPlayQueue@" + Integer.toHexString(hashCode());
|
2017-09-05 21:27:12 +02:00
|
|
|
|
2017-09-04 20:05:13 +02:00
|
|
|
private static final int RETRY_COUNT = 2;
|
2017-08-29 17:00:11 +02:00
|
|
|
|
|
|
|
private boolean isComplete;
|
2017-08-29 02:38:37 +02:00
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
private int serviceId;
|
2017-09-15 05:16:09 +02:00
|
|
|
private String baseUrl;
|
|
|
|
private String nextUrl;
|
2017-08-29 02:38:37 +02:00
|
|
|
|
2017-09-05 21:27:12 +02:00
|
|
|
private transient Disposable fetchReactor;
|
2017-08-31 19:07:18 +02:00
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
public ExternalPlayQueue(final int serviceId,
|
2017-09-15 05:16:09 +02:00
|
|
|
final String url,
|
2017-09-04 19:23:56 +02:00
|
|
|
final String nextPageUrl,
|
|
|
|
final List<InfoItem> streams,
|
2017-08-31 19:07:18 +02:00
|
|
|
final int index) {
|
2017-09-04 19:23:56 +02:00
|
|
|
super(index, extractPlaylistItems(streams));
|
2017-09-04 04:15:11 +02:00
|
|
|
|
2017-09-15 05:16:09 +02:00
|
|
|
this.baseUrl = url;
|
|
|
|
this.nextUrl = nextPageUrl;
|
2017-09-04 19:23:56 +02:00
|
|
|
this.serviceId = serviceId;
|
2017-09-04 04:15:11 +02:00
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
this.isComplete = nextPageUrl == null || nextPageUrl.isEmpty();
|
2017-08-29 17:00:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isComplete() {
|
|
|
|
return isComplete;
|
|
|
|
}
|
|
|
|
|
2017-08-31 19:07:18 +02:00
|
|
|
@Override
|
|
|
|
public void fetch() {
|
2017-09-15 05:16:09 +02:00
|
|
|
ExtractorHelper.getMorePlaylistItems(this.serviceId, this.baseUrl, this.nextUrl)
|
2017-09-04 19:23:56 +02:00
|
|
|
.subscribeOn(Schedulers.io())
|
|
|
|
.observeOn(AndroidSchedulers.mainThread())
|
2017-09-04 20:05:13 +02:00
|
|
|
.retry(RETRY_COUNT)
|
2017-09-04 19:23:56 +02:00
|
|
|
.subscribe(getPlaylistObserver());
|
|
|
|
}
|
2017-08-29 02:38:37 +02:00
|
|
|
|
2017-09-05 00:38:58 +02:00
|
|
|
private SingleObserver<ListExtractor.NextItemsResult> getPlaylistObserver() {
|
|
|
|
return new SingleObserver<ListExtractor.NextItemsResult>() {
|
2017-08-29 02:38:37 +02:00
|
|
|
@Override
|
2017-09-04 19:23:56 +02:00
|
|
|
public void onSubscribe(@NonNull Disposable d) {
|
|
|
|
if (isComplete || (fetchReactor != null && !fetchReactor.isDisposed())) {
|
|
|
|
d.dispose();
|
|
|
|
} else {
|
|
|
|
fetchReactor = d;
|
|
|
|
}
|
2017-08-29 02:38:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-09-05 00:38:58 +02:00
|
|
|
public void onSuccess(@NonNull ListExtractor.NextItemsResult result) {
|
|
|
|
if (!result.hasMoreStreams()) isComplete = true;
|
2017-09-15 05:16:09 +02:00
|
|
|
nextUrl = result.nextItemsUrl;
|
2017-08-29 17:00:11 +02:00
|
|
|
|
2017-09-05 00:38:58 +02:00
|
|
|
append(extractPlaylistItems(result.nextItemsList));
|
2017-08-29 02:38:37 +02:00
|
|
|
}
|
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
@Override
|
|
|
|
public void onError(@NonNull Throwable e) {
|
|
|
|
Log.e(TAG, "Error fetching more playlist, marking playlist as complete.", e);
|
|
|
|
isComplete = true;
|
2017-09-29 04:37:04 +02:00
|
|
|
append(); // Notify change
|
2017-09-04 19:23:56 +02:00
|
|
|
}
|
|
|
|
};
|
2017-08-29 02:38:37 +02:00
|
|
|
}
|
|
|
|
|
2017-08-31 19:07:18 +02:00
|
|
|
@Override
|
|
|
|
public void dispose() {
|
2017-09-02 20:06:36 +02:00
|
|
|
super.dispose();
|
2017-08-31 19:07:18 +02:00
|
|
|
if (fetchReactor != null) fetchReactor.dispose();
|
|
|
|
}
|
|
|
|
|
2017-09-04 19:23:56 +02:00
|
|
|
private static List<PlayQueueItem> extractPlaylistItems(final List<InfoItem> infos) {
|
2017-08-29 17:00:11 +02:00
|
|
|
List<PlayQueueItem> result = new ArrayList<>();
|
2017-09-04 19:23:56 +02:00
|
|
|
for (final InfoItem stream : infos) {
|
2017-08-29 02:38:37 +02:00
|
|
|
if (stream instanceof StreamInfoItem) {
|
2017-08-29 17:00:11 +02:00
|
|
|
result.add(new PlayQueueItem((StreamInfoItem) stream));
|
2017-08-29 02:38:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|