forked from TeamNewPipe/NewPipe
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Deduplicate code for fetching stream info when sparse
Fixes TeamNewPipe#7941
- Loading branch information
Showing
48 changed files
with
138 additions
and
249 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 0 additions & 94 deletions
94
app/src/main/java/org/schabi/newpipe/util/SaveUploaderUrlHelper.java
This file was deleted.
Oops, something went wrong.
126 changes: 126 additions & 0 deletions
126
app/src/main/java/org/schabi/newpipe/util/SparseItemUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package org.schabi.newpipe.util; | ||
|
||
import static org.schabi.newpipe.extractor.stream.StreamType.AUDIO_LIVE_STREAM; | ||
import static org.schabi.newpipe.extractor.stream.StreamType.LIVE_STREAM; | ||
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; | ||
|
||
import android.content.Context; | ||
import android.widget.Toast; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.annotation.Nullable; | ||
|
||
import org.schabi.newpipe.NewPipeDatabase; | ||
import org.schabi.newpipe.R; | ||
import org.schabi.newpipe.database.stream.model.StreamEntity; | ||
import org.schabi.newpipe.error.ErrorInfo; | ||
import org.schabi.newpipe.error.ErrorUtil; | ||
import org.schabi.newpipe.error.UserAction; | ||
import org.schabi.newpipe.extractor.stream.StreamInfo; | ||
import org.schabi.newpipe.extractor.stream.StreamInfoItem; | ||
import org.schabi.newpipe.player.playqueue.SinglePlayQueue; | ||
|
||
import java.util.function.Consumer; | ||
|
||
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; | ||
import io.reactivex.rxjava3.core.Completable; | ||
import io.reactivex.rxjava3.schedulers.Schedulers; | ||
|
||
/** | ||
* Utility class for fetching additional data for stream items when needed. | ||
*/ | ||
public final class SparseItemUtil { | ||
private SparseItemUtil() { | ||
} | ||
|
||
/** | ||
* Use this to certainly obtain an single play queue with all of the data filled in when the | ||
* stream info item you are handling might be sparse, e.g. because it was fetched via a {@link | ||
* org.schabi.newpipe.extractor.feed.FeedExtractor}. FeedExtractors provide a fast and | ||
* lightweight method to fetch info, but the info might be incomplete (see | ||
* {@link org.schabi.newpipe.local.feed.service.FeedLoadService} for more details). | ||
* | ||
* @param context the Android context | ||
* @param item the item which is checked and eventually loaded completely | ||
* @param callback the callback to call with the single play queue built from the original item | ||
* if all info was available, otherwise from the fetched {@link | ||
* org.schabi.newpipe.extractor.stream.StreamInfo} | ||
*/ | ||
public static void fetchItemInfoIfSparse(@NonNull final Context context, | ||
@NonNull final StreamInfoItem item, | ||
@NonNull final Consumer<SinglePlayQueue> callback) { | ||
if ((!(item.getStreamType() == LIVE_STREAM || item.getStreamType() == AUDIO_LIVE_STREAM) | ||
&& item.getDuration() < 0) || isNullOrEmpty(item.getUploaderUrl())) { | ||
fetchStreamInfoAndSaveToDatabase(context, item.getServiceId(), item.getUrl(), | ||
streamInfo -> callback.accept(new SinglePlayQueue(streamInfo))); | ||
} else { | ||
// all info is already there, no need to fetch | ||
callback.accept(new SinglePlayQueue(item)); | ||
} | ||
} | ||
|
||
/** | ||
* Use this to certainly obtain an uploader url when the stream info item or play queue item you | ||
* are handling might not have the uploader url (e.g. because it was fetched with {@link | ||
* org.schabi.newpipe.extractor.feed.FeedExtractor}). A toast is shown if loading details is | ||
* required. | ||
* | ||
* @param context the Android context | ||
* @param serviceId the serviceId of the item | ||
* @param url the item url | ||
* @param uploaderUrl the uploaderUrl of the item; if null or empty will be fetched | ||
* @param callback the callback called with either the original uploaderUrl, if it was a valid | ||
* url, otherwise with the uploader url obtained by fetching the {@link | ||
* org.schabi.newpipe.extractor.stream.StreamInfo} corresponding to the item | ||
*/ | ||
public static void fetchUploaderUrlIfSparse(@NonNull final Context context, | ||
final int serviceId, | ||
@NonNull final String url, | ||
@Nullable final String uploaderUrl, | ||
@NonNull final Consumer<String> callback) { | ||
if (isNullOrEmpty(uploaderUrl)) { | ||
fetchStreamInfoAndSaveToDatabase(context, serviceId, url, | ||
streamInfo -> callback.accept(streamInfo.getUploaderUrl())); | ||
} else { | ||
callback.accept(uploaderUrl); | ||
} | ||
} | ||
|
||
/** | ||
* Loads the stream info corresponding to the given data on an I/O thread, stores the result in | ||
* the database and calls the callback on the main thread with the result. A toast will be shown | ||
* to the user about loading stream details, so this needs to be called on the main thread. | ||
* | ||
* @param context the Android context | ||
* @param serviceId the service id of the stream to load | ||
* @param url the url of the stream to load | ||
* @param callback the callback to call with the result | ||
*/ | ||
private static void fetchStreamInfoAndSaveToDatabase(final Context context, | ||
final int serviceId, | ||
@NonNull final String url, | ||
final Consumer<StreamInfo> callback) { | ||
Toast.makeText(context, R.string.loading_stream_details, Toast.LENGTH_SHORT).show(); | ||
ExtractorHelper.getStreamInfo(serviceId, url, false) | ||
.subscribeOn(Schedulers.io()) | ||
.observeOn(AndroidSchedulers.mainThread()) | ||
.subscribe(result -> { | ||
// save to database in the background (not on main thread) | ||
Completable.fromAction(() -> NewPipeDatabase.getInstance(context) | ||
.streamDAO().upsert(new StreamEntity(result))) | ||
.subscribeOn(Schedulers.io()) | ||
.observeOn(Schedulers.io()) | ||
.doOnError(throwable -> | ||
ErrorUtil.createNotification(context, | ||
new ErrorInfo(throwable, UserAction.REQUESTED_STREAM, | ||
"Saving stream info to database", result))) | ||
.subscribe(); | ||
|
||
// call callback on main thread with the obtained result | ||
callback.accept(result); | ||
}, throwable -> ErrorUtil.createNotification(context, | ||
new ErrorInfo(throwable, UserAction.REQUESTED_STREAM, | ||
"Loading stream info: " + url, serviceId) | ||
)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.