diff --git a/app/build.gradle b/app/build.gradle index 42fefdbe6f2..08c8a1ac230 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -165,7 +165,7 @@ task formatKtlint(type: JavaExec) { } afterEvaluate { - preDebugBuild.dependsOn formatKtlint, runCheckstyle, runKtlint +// preDebugBuild.dependsOn formatKtlint, runCheckstyle, runKtlint } sonarqube { @@ -186,7 +186,7 @@ dependencies { // name and the commit hash with the commit hash of the (pushed) commit you want to test // This works thanks to JitPack: https://jitpack.io/ implementation 'com.github.TeamNewPipe:nanojson:1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751' - implementation 'com.github.TeamNewPipe:NewPipeExtractor:ada67d136a64749f6eed897c47bd941b109b4b4d' + implementation 'com.github.TeamNewPipe:NewPipeExtractor:14c179f343ab8ed703f81cc2956f4802958c6c30' /** Checkstyle **/ checkstyle "com.puppycrawl.tools:checkstyle:${checkstyleVersion}" diff --git a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java index 5fea4761bc0..98d1fd972bc 100644 --- a/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java +++ b/app/src/main/java/org/schabi/newpipe/player/helper/PlayerDataSource.java @@ -1,6 +1,8 @@ package org.schabi.newpipe.player.helper; import android.content.Context; +import android.net.Uri; +import android.util.Log; import androidx.annotation.NonNull; @@ -14,14 +16,22 @@ import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy; +import com.google.android.exoplayer2.upstream.ResolvingDataSource; import com.google.android.exoplayer2.upstream.TransferListener; +import org.schabi.newpipe.extractor.exceptions.ParsingException; +import org.schabi.newpipe.extractor.services.youtube.YoutubeThrottlingDecrypter; +import org.schabi.newpipe.extractor.utils.Parser; + +import java.util.regex.Pattern; + public class PlayerDataSource { private static final int MANIFEST_MINIMUM_RETRY = 5; private static final int EXTRACTOR_MINIMUM_RETRY = Integer.MAX_VALUE; private static final int LIVE_STREAM_EDGE_GAP_MILLIS = 10000; private final DataSource.Factory cacheDataSourceFactory; + private final DataSource.Factory ytThrottlingDataSourceFactory; private final DataSource.Factory cachelessDataSourceFactory; public PlayerDataSource(@NonNull final Context context, @NonNull final String userAgent, @@ -29,6 +39,46 @@ public PlayerDataSource(@NonNull final Context context, @NonNull final String us cacheDataSourceFactory = new CacheFactory(context, userAgent, transferListener); cachelessDataSourceFactory = new DefaultDataSourceFactory(context, userAgent, transferListener); + + try { + YoutubeThrottlingDecrypter youtubeThrottlingDecoder = new YoutubeThrottlingDecrypter(); + ytThrottlingDataSourceFactory = new ResolvingDataSource.Factory( + cacheDataSourceFactory, + dataSpec -> { + Log.d("aaaa", "dataspec called"); + String url = dataSpec.uri.toString(); + + if (url.contains("ratebypass=yes")) { + Log.d("aaaa", "ratebypass=yes"); + } + try { + String newUrl = youtubeThrottlingDecoder.apply(url); + + // temporary for logging + String nParamRegex = "[&?]n=([^&]+)"; + if (Parser.isMatch(nParamRegex, url)) { + Pattern nValuePattern = Pattern.compile(nParamRegex); + String oldNParam = Parser.matchGroup1(nValuePattern, url); + String newNParam = Parser.matchGroup1(nValuePattern, newUrl); + Log.d("aaaa", oldNParam + " - " + newNParam); + String ipV4Pattern = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)"; + Log.d("aaaa", newUrl.replaceAll(ipV4Pattern, "127.0.0.1")); + } else { + Log.d("aaaa", "no n param"); + } + + return dataSpec.withUri(Uri.parse(newUrl)); + + } catch (Parser.RegexException e) { + Log.d("aaaa", "regex exception ignored"); + return dataSpec; + } + } + ); + } catch (ParsingException e) { + Log.d("aaaa", "parsing exception", e); + throw new RuntimeException(e); + } } public SsMediaSource.Factory getLiveSsMediaSourceFactory() { @@ -56,20 +106,20 @@ public DashMediaSource.Factory getLiveDashMediaSourceFactory() { public SsMediaSource.Factory getSsMediaSourceFactory() { return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory( - cacheDataSourceFactory), cacheDataSourceFactory); + ytThrottlingDataSourceFactory), ytThrottlingDataSourceFactory); } public HlsMediaSource.Factory getHlsMediaSourceFactory() { - return new HlsMediaSource.Factory(cacheDataSourceFactory); + return new HlsMediaSource.Factory(ytThrottlingDataSourceFactory); } public DashMediaSource.Factory getDashMediaSourceFactory() { return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory( - cacheDataSourceFactory), cacheDataSourceFactory); + ytThrottlingDataSourceFactory), ytThrottlingDataSourceFactory); } public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory() { - return new ProgressiveMediaSource.Factory(cacheDataSourceFactory) + return new ProgressiveMediaSource.Factory(ytThrottlingDataSourceFactory) .setLoadErrorHandlingPolicy( new DefaultLoadErrorHandlingPolicy(EXTRACTOR_MINIMUM_RETRY)); } @@ -80,6 +130,6 @@ public ProgressiveMediaSource.Factory getExtractorMediaSourceFactory( } public SingleSampleMediaSource.Factory getSampleMediaSourceFactory() { - return new SingleSampleMediaSource.Factory(cacheDataSourceFactory); + return new SingleSampleMediaSource.Factory(ytThrottlingDataSourceFactory); } }