-Added more decrypt function name matching regex.
-Cleaned up decryption code generation method.
This commit is contained in:
parent
119843bfac
commit
ed73ae55f1
|
@ -560,6 +560,13 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
|
|
||||||
private static final String VERIFIED_URL_PARAMS = "&has_verified=1&bpctr=9999999999";
|
private static final String VERIFIED_URL_PARAMS = "&has_verified=1&bpctr=9999999999";
|
||||||
|
|
||||||
|
private final static String DECYRYPTION_SIGNATURE_FUNCTION_REGEX =
|
||||||
|
"(\\w+)\\s*=\\s*function\\((\\w+)\\)\\{\\s*\\2=\\s*\\2\\.split\\(\"\"\\)\\s*;";
|
||||||
|
private final static String DECRYPTION_AKAMAIZED_STRING_REGEX =
|
||||||
|
"yt\\.akamaized\\.net/\\)\\s*\\|\\|\\s*.*?\\s*c\\s*&&\\s*d\\.set\\([^,]+\\s*,\\s*([a-zA-Z0-9$]+)\\(";
|
||||||
|
private final static String DECRYPTION_AKAMAIZED_SHORT_STRING_REGEX =
|
||||||
|
"\\bc\\s*&&\\s*d\\.set\\([^,]+\\s*,\\s*([a-zA-Z0-9$]+)\\(";
|
||||||
|
|
||||||
private volatile String decryptionCode = "";
|
private volatile String decryptionCode = "";
|
||||||
|
|
||||||
private String pageHtml = null;
|
private String pageHtml = null;
|
||||||
|
@ -682,13 +689,6 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadDecryptionCode(String playerUrl) throws DecryptException {
|
private String loadDecryptionCode(String playerUrl) throws DecryptException {
|
||||||
String decryptionFuncName;
|
|
||||||
String decryptionFunc;
|
|
||||||
String helperObjectName;
|
|
||||||
String helperObject;
|
|
||||||
String callerFunc = "function " + DECRYPTION_FUNC_NAME + "(a){return %%(a);}";
|
|
||||||
String decryptionCode;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Downloader downloader = NewPipe.getDownloader();
|
Downloader downloader = NewPipe.getDownloader();
|
||||||
if (!playerUrl.contains("https://youtube.com")) {
|
if (!playerUrl.contains("https://youtube.com")) {
|
||||||
|
@ -696,35 +696,38 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
||||||
//than we have to add it by hand
|
//than we have to add it by hand
|
||||||
playerUrl = "https://youtube.com" + playerUrl;
|
playerUrl = "https://youtube.com" + playerUrl;
|
||||||
}
|
}
|
||||||
String playerCode = downloader.download(playerUrl);
|
|
||||||
|
|
||||||
decryptionFuncName = Parser.matchGroup(
|
final String playerCode = downloader.download(playerUrl);
|
||||||
// Look for a function with the first line containing pattern of: [var]=[var].split("")
|
|
||||||
"(\\w+)\\s*=\\s*function\\((\\w+)\\)\\{\\s*\\2=\\s*\\2\\.split\\(\"\"\\)\\s*;",
|
|
||||||
playerCode, 1);
|
|
||||||
|
|
||||||
String functionPattern = "("
|
final String decryptionFunctionName;
|
||||||
+ decryptionFuncName.replace("$", "\\$")
|
if (Parser.isMatch(DECRYPTION_AKAMAIZED_SHORT_STRING_REGEX, playerCode)) {
|
||||||
|
decryptionFunctionName = Parser.matchGroup1(DECRYPTION_AKAMAIZED_SHORT_STRING_REGEX, playerCode);
|
||||||
|
} else if (Parser.isMatch(DECRYPTION_AKAMAIZED_STRING_REGEX, playerCode)) {
|
||||||
|
decryptionFunctionName = Parser.matchGroup1(DECRYPTION_AKAMAIZED_STRING_REGEX, playerCode);
|
||||||
|
} else {
|
||||||
|
decryptionFunctionName = Parser.matchGroup1(DECYRYPTION_SIGNATURE_FUNCTION_REGEX, playerCode);
|
||||||
|
}
|
||||||
|
final String functionPattern = "("
|
||||||
|
+ decryptionFunctionName.replace("$", "\\$")
|
||||||
+ "=function\\([a-zA-Z0-9_]+\\)\\{.+?\\})";
|
+ "=function\\([a-zA-Z0-9_]+\\)\\{.+?\\})";
|
||||||
decryptionFunc = "var " + Parser.matchGroup1(functionPattern, playerCode) + ";";
|
final String decryptionFunction = "var " + Parser.matchGroup1(functionPattern, playerCode) + ";";
|
||||||
|
|
||||||
helperObjectName = Parser
|
final String helperObjectName =
|
||||||
.matchGroup1(";([A-Za-z0-9_\\$]{2})\\...\\(", decryptionFunc);
|
Parser.matchGroup1(";([A-Za-z0-9_\\$]{2})\\...\\(", decryptionFunction);
|
||||||
|
final String helperPattern =
|
||||||
|
"(var " + helperObjectName.replace("$", "\\$") + "=\\{.+?\\}\\};)";
|
||||||
|
final String helperObject =
|
||||||
|
Parser.matchGroup1(helperPattern, playerCode.replace("\n", ""));
|
||||||
|
|
||||||
String helperPattern = "(var "
|
final String callerFunction =
|
||||||
+ helperObjectName.replace("$", "\\$") + "=\\{.+?\\}\\};)";
|
"function " + DECRYPTION_FUNC_NAME + "(a){return " + decryptionFunctionName + "(a);}";
|
||||||
helperObject = Parser.matchGroup1(helperPattern, playerCode.replace("\n", ""));
|
|
||||||
|
|
||||||
|
return helperObject + decryptionFunction + callerFunction;
|
||||||
callerFunc = callerFunc.replace("%%", decryptionFuncName);
|
|
||||||
decryptionCode = helperObject + decryptionFunc + callerFunc;
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
throw new DecryptException("Could not load decrypt function", ioe);
|
throw new DecryptException("Could not load decrypt function", ioe);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new DecryptException("Could not parse decrypt function ", e);
|
throw new DecryptException("Could not parse decrypt function ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return decryptionCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String decryptSignature(String encryptedSig, String decryptionCode) throws DecryptException {
|
private String decryptSignature(String encryptedSig, String decryptionCode) throws DecryptException {
|
||||||
|
|
Loading…
Reference in New Issue