Merge branch 'master' into dev
This commit is contained in:
commit
57e66b17c6
39 changed files with 401 additions and 82 deletions
|
|
@ -17,6 +17,7 @@ import org.schabi.newpipe.database.subscription.NotificationMode
|
|||
import org.schabi.newpipe.database.subscription.SubscriptionEntity
|
||||
import org.schabi.newpipe.extractor.Info
|
||||
import org.schabi.newpipe.extractor.NewPipe
|
||||
import org.schabi.newpipe.extractor.ServiceList
|
||||
import org.schabi.newpipe.extractor.feed.FeedInfo
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem
|
||||
import org.schabi.newpipe.ktx.getStringSafe
|
||||
|
|
@ -90,6 +91,10 @@ class FeedLoadManager(private val context: Context) {
|
|||
else -> feedDatabaseManager.outdatedSubscriptionsForGroup(groupId, outdatedThreshold)
|
||||
}
|
||||
|
||||
// like `currentProgress`, but counts the number of YouTube extractions that have begun, so
|
||||
// they can be properly throttled every once in a while (see doOnNext below)
|
||||
val youtubeExtractionCount = AtomicInteger()
|
||||
|
||||
return outdatedSubscriptions
|
||||
.take(1)
|
||||
.doOnNext {
|
||||
|
|
@ -105,6 +110,15 @@ class FeedLoadManager(private val context: Context) {
|
|||
.observeOn(Schedulers.io())
|
||||
.flatMap { Flowable.fromIterable(it) }
|
||||
.takeWhile { !cancelSignal.get() }
|
||||
.doOnNext { subscriptionEntity ->
|
||||
// throttle YouTube extractions once every BATCH_SIZE to avoid being rate limited
|
||||
if (subscriptionEntity.serviceId == ServiceList.YouTube.serviceId) {
|
||||
val previousCount = youtubeExtractionCount.getAndIncrement()
|
||||
if (previousCount != 0 && previousCount % BATCH_SIZE == 0) {
|
||||
Thread.sleep(DELAY_BETWEEN_BATCHES_MILLIS.random())
|
||||
}
|
||||
}
|
||||
}
|
||||
.parallel(PARALLEL_EXTRACTIONS, PARALLEL_EXTRACTIONS * 2)
|
||||
.runOn(Schedulers.io(), PARALLEL_EXTRACTIONS * 2)
|
||||
.filter { !cancelSignal.get() }
|
||||
|
|
@ -328,7 +342,19 @@ class FeedLoadManager(private val context: Context) {
|
|||
/**
|
||||
* How many extractions will be running in parallel.
|
||||
*/
|
||||
private const val PARALLEL_EXTRACTIONS = 6
|
||||
private const val PARALLEL_EXTRACTIONS = 3
|
||||
|
||||
/**
|
||||
* How many YouTube extractions to perform before waiting [DELAY_BETWEEN_BATCHES_MILLIS]
|
||||
* to avoid being rate limited
|
||||
*/
|
||||
private const val BATCH_SIZE = 50
|
||||
|
||||
/**
|
||||
* Wait a random delay in this range once every [BATCH_SIZE] YouTube extractions to avoid
|
||||
* being rate limited
|
||||
*/
|
||||
private val DELAY_BETWEEN_BATCHES_MILLIS = (6000L..12000L)
|
||||
|
||||
/**
|
||||
* Number of items to buffer to mass-insert in the database.
|
||||
|
|
|
|||
|
|
@ -48,10 +48,12 @@ public final class ListHelper {
|
|||
private static final Set<String> HIGH_RESOLUTION_LIST = Set.of("1440p", "2160p");
|
||||
// Audio track types in order of priority. 0=lowest, n=highest
|
||||
private static final List<AudioTrackType> AUDIO_TRACK_TYPE_RANKING =
|
||||
List.of(AudioTrackType.DESCRIPTIVE, AudioTrackType.DUBBED, AudioTrackType.ORIGINAL);
|
||||
List.of(AudioTrackType.DESCRIPTIVE, AudioTrackType.SECONDARY, AudioTrackType.DUBBED,
|
||||
AudioTrackType.ORIGINAL);
|
||||
// Audio track types in order of priority when descriptive audio is preferred.
|
||||
private static final List<AudioTrackType> AUDIO_TRACK_TYPE_RANKING_DESCRIPTIVE =
|
||||
List.of(AudioTrackType.ORIGINAL, AudioTrackType.DUBBED, AudioTrackType.DESCRIPTIVE);
|
||||
List.of(AudioTrackType.SECONDARY, AudioTrackType.DUBBED, AudioTrackType.ORIGINAL,
|
||||
AudioTrackType.DESCRIPTIVE);
|
||||
|
||||
/**
|
||||
* List of supported YouTube Itag ids.
|
||||
|
|
|
|||
|
|
@ -327,25 +327,20 @@ public final class Localization {
|
|||
|
||||
if (track.getAudioTrackType() != null) {
|
||||
final String trackType = audioTrackType(context, track.getAudioTrackType());
|
||||
if (trackType != null) {
|
||||
return context.getString(R.string.audio_track_name, name, trackType);
|
||||
}
|
||||
return context.getString(R.string.audio_track_name, name, trackType);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NonNull
|
||||
private static String audioTrackType(@NonNull final Context context,
|
||||
final AudioTrackType trackType) {
|
||||
switch (trackType) {
|
||||
case ORIGINAL:
|
||||
return context.getString(R.string.audio_track_type_original);
|
||||
case DUBBED:
|
||||
return context.getString(R.string.audio_track_type_dubbed);
|
||||
case DESCRIPTIVE:
|
||||
return context.getString(R.string.audio_track_type_descriptive);
|
||||
}
|
||||
return null;
|
||||
@NonNull final AudioTrackType trackType) {
|
||||
return switch (trackType) {
|
||||
case ORIGINAL -> context.getString(R.string.audio_track_type_original);
|
||||
case DUBBED -> context.getString(R.string.audio_track_type_dubbed);
|
||||
case DESCRIPTIVE -> context.getString(R.string.audio_track_type_descriptive);
|
||||
case SECONDARY -> context.getString(R.string.audio_track_type_secondary);
|
||||
};
|
||||
}
|
||||
|
||||
/*//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue