use newpipe extractor to get stream

This commit is contained in:
oSumAtrIX 2024-05-04 21:41:40 +02:00
parent bc07c0b29b
commit b7513134f1
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
5 changed files with 120 additions and 24 deletions

View File

@ -49,6 +49,7 @@ dependencies {
compileOnly(libs.annotation)
compileOnly(libs.okhttp)
compileOnly(libs.retrofit)
implementation("com.github.TeamNewPipe:NewPipeExtractor:0.24.0")
compileOnly(project(":stub"))
}

View File

@ -1,47 +1,139 @@
package app.revanced;
import android.net.Uri;
import androidx.annotation.Nullable;
import app.revanced.integrations.shared.Logger;
import app.revanced.integrations.youtube.patches.spoof.requests.StoryboardRendererRequester;
import app.revanced.integrations.shared.Utils;
import app.revanced.integrations.youtube.requests.Requester;
import org.schabi.newpipe.extractor.NewPipe;
import org.schabi.newpipe.extractor.downloader.Downloader;
import org.schabi.newpipe.extractor.downloader.Request;
import org.schabi.newpipe.extractor.downloader.Response;
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
import org.schabi.newpipe.extractor.services.youtube.YoutubeService;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.AudioStream;
import org.schabi.newpipe.extractor.stream.VideoStream;
import java.util.Map;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
public class Test {
private static Map<Integer, String> formats;
private static Map<Integer, String> formats = new HashMap<>();
public static String hook(String s) {
if (!s.contains("googlevideo")) return s;
if (true) {
var c2 = new Throwable().getStackTrace()[2].toString();
var c = new Throwable().getStackTrace()[1].toString();
var itag = Uri.parse(s).getQueryParameter("itag");
Logger.printInfo(() -> "Hooked " + c2 + ": itag: " + itag);
Logger.printInfo(() -> "Hooked " + c + ": itag: " + itag);
@Nullable
public static HttpURLConnection makeRequest(final Request request) {
try {
Utils.verifyOffMainThread();
//Objects.requireNonNull(request.dataToSend());
return s;
HttpURLConnection connection = (HttpURLConnection) new URL(request.url()).openConnection();
connection.setRequestMethod(request.httpMethod());
String agentString = "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0";
connection.setRequestProperty("User-Agent", agentString);
for (final Map.Entry<String, List<String>> pair : request.headers().entrySet()) {
final String headerName = pair.getKey();
final List<String> headerValueList = pair.getValue();
if (headerValueList.size() > 1) {
for (final String headerValue : headerValueList) {
connection.addRequestProperty(headerName, headerValue);
}
} else if (headerValueList.size() == 1) {
connection.addRequestProperty(headerName, headerValueList.get(0));
}
}
final byte[] innerTubeBody = request.dataToSend();
if (innerTubeBody != null) {
connection.getOutputStream().write(innerTubeBody, 0, innerTubeBody.length);
}
final int responseCode = connection.getResponseCode();
if (responseCode == 200) return connection;
else if (responseCode == 429) {
throw new Exception("reCaptcha Challenge requested");
} else {
throw new Exception("Error making request: " + responseCode);
}
} catch (Exception ignored) {
Logger.printInfo(() -> "Hooked Error making request: " + ignored.getMessage(), ignored);
}
if (formats == null)
formats = StoryboardRendererRequester.getFormats("piKJAUwCYTo");
return null;
}
public static String hook(String s) {
if (!s.contains("googlevideo")) return s;
if (formats.isEmpty()) {
try {
NewPipe.init(new Downloader() {
@Override
public Response execute(Request request) throws IOException {
var c = makeRequest(request);
var r = new Response(
c.getResponseCode(),
c.getResponseMessage(),
c.getHeaderFields(),
Requester.parseString(c),
c.getURL().toString()
);
c.disconnect();;
return r;
}
});
var extractor = new YoutubeService(1).getStreamExtractor(YoutubeStreamLinkHandlerFactory.getInstance().fromId("piKJAUwCYTo"));
extractor.fetchPage();
for (AudioStream audioStream : extractor.getAudioStreams()) {
formats.put(audioStream.getItag(), audioStream.getContent());
}
for (VideoStream videoOnlyStream : extractor.getVideoOnlyStreams()) {
formats.put(videoOnlyStream.getItag(), videoOnlyStream.getContent());
}
for (VideoStream videoStream : extractor.getVideoStreams()) {
formats.put(videoStream.getItag(), videoStream.getContent());
}
} catch (ExtractionException | IOException ignored) {
Logger.printInfo(() -> "Hooked Error making request: " + ignored.getMessage(), ignored);
}
//formats = StoryboardRendererRequester.getFormats("piKJAUwCYTo");
}
var itag = Uri.parse(s).getQueryParameter("itag");
Logger.printInfo(() -> "Hooked itag: " + itag);
if (itag == null) return s;
String m;
// find nearest key to itag
var availableTags = formats.keySet();
Integer nearest;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
m = formats.values().stream().findFirst().get();
nearest = availableTags.stream().min(Comparator.comparingInt(a -> Math.abs(Integer.parseInt(itag) - a))).orElse(null);
} else {
m = null;
nearest = null;
}
Logger.printInfo(() -> "Hooked format: " + m);
if (m == null) return s;
var c = new Throwable().getStackTrace()[1].toString();
Logger.printInfo(() -> "Hooked " + c + ": From " + s + " to " + m);
Logger.printInfo(() -> "Hooked count: " + formats.size());
Logger.printInfo(() -> "Hooked nearest " + nearest);
String m = formats.get(nearest);
Logger.printInfo(() -> String.valueOf(("Hooked format " + m == null)));
if (m == null) {
Logger.printInfo(() -> "Hooked format null");
return s;
}
Logger.printInfo(() -> "Hooked");
return m;
}
}

View File

@ -10,7 +10,7 @@ import java.io.IOException;
import java.net.HttpURLConnection;
@Deprecated
final class PlayerRoutes {
public final class PlayerRoutes {
private static final String YT_API_URL = "https://www.youtube.com/youtubei/v1/";
static final Route.CompiledRoute GET_STORYBOARD_SPEC_RENDERER = new Route(
Route.Method.POST,
@ -84,10 +84,11 @@ final class PlayerRoutes {
}
/** @noinspection SameParameterValue*/
static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRoute route) throws IOException {
public static HttpURLConnection getPlayerResponseConnectionFromRoute(Route.CompiledRoute route) throws IOException {
var connection = Requester.getConnectionFromCompiledRoute(YT_API_URL, route);
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0");
connection.setUseCaches(false);
connection.setDoOutput(true);

View File

@ -49,6 +49,7 @@ public class StoryboardRendererRequester {
Logger.printInfo(() -> toastMessage, ex);
}
@Nullable
private static JSONObject fetchPlayerResponse(@NonNull String requestBody, boolean showToastOnIOException) {
final long startTime = System.currentTimeMillis();

View File

@ -13,6 +13,7 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://jitpack.io") }
}
}