Skip to content

Commit

Permalink
spoof android to fix throttling speed issue
Browse files Browse the repository at this point in the history
  • Loading branch information
sealedtx committed Oct 18, 2021
1 parent 70aeb61 commit b84d42f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ Include
<dependency>
<groupId>com.github.sealedtx</groupId>
<artifactId>java-youtube-downloader</artifactId>
<version>3.0.1</version>
<version>3.0.2</version>
</dependency>
```

Expand All @@ -283,7 +283,7 @@ allprojects {
```
```gradle
dependencies {
implementation 'com.github.sealedtx:java-youtube-downloader:3.0.1'
implementation 'com.github.sealedtx:java-youtube-downloader:3.0.2'
}
```
### Android
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.github.ikiulian</groupId>
<artifactId>java-youtube-downloader</artifactId>
<version>3.0.1</version>
<version>3.0.2</version>

<name>Java youtube video downloader</name>
<description>Java parser for retrieving youtube video meta info</description>
Expand Down
71 changes: 66 additions & 5 deletions src/main/java/com/github/kiulian/downloader/parser/ParserImpl.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.github.kiulian.downloader.parser;



import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
Expand Down Expand Up @@ -33,6 +32,7 @@
import java.util.concurrent.Future;

public class ParserImpl implements Parser {
private static final String ANDROID_APIKEY = "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8";

private final Config config;
private final Downloader downloader;
Expand Down Expand Up @@ -61,7 +61,65 @@ public Response<VideoInfo> parseVideo(RequestVideoInfo request) {
}
}

public VideoInfo parseVideo(String videoId, YoutubeCallback<VideoInfo> callback) throws YoutubeException {
private VideoInfo parseVideo(String videoId, YoutubeCallback<VideoInfo> callback) throws YoutubeException {
// try to spoof android
// workaround for issue https://github.com/sealedtx/java-youtube-downloader/issues/97
VideoInfo videoInfo = parseVideoAndroid(videoId);
if (videoInfo == null) {
videoInfo = parseVideoWeb(videoId, callback);
}
if (callback != null) {
callback.onFinished(videoInfo);
}
return videoInfo;
}

private VideoInfo parseVideoAndroid(String videoId) throws YoutubeException {
String url = "https://youtubei.googleapis.com/youtubei/v1/player?key=" + ANDROID_APIKEY;

String body =
"{" +
" \"videoId\": \"" + videoId + "\"," +
" \"context\": {" +
" \"client\": {" +
" \"hl\": \"en\"," +
" \"gl\": \"US\"," +
" \"clientName\": \"ANDROID\"," +
" \"clientVersion\": \"16.02\"" +
" }" +
" }" +
"}";

RequestWebpage request = new RequestWebpage(url, "POST", body)
.header("Content-Type", "application/json");

Response<String> response = downloader.downloadWebpage(request);
if (!response.ok()) {
return null;
}

JSONObject playerResponse;
try {
playerResponse = JSONObject.parseObject(response.data());
} catch (Exception ignore) {
return null;
}

VideoDetails videoDetails = parseVideoDetails(videoId, playerResponse);
if (videoDetails.isDownloadable()) {
JSONObject context = playerResponse.getJSONObject("responseContext");
String clientVersion = extractor.extractClientVersionFromContext(context);
List<Format> formats = parseFormats(playerResponse, null, clientVersion);

List<SubtitlesInfo> subtitlesInfo = parseCaptions(playerResponse);
return new VideoInfo(videoDetails, formats, subtitlesInfo);
} else {
return new VideoInfo(videoDetails, Collections.emptyList(), Collections.emptyList());
}

}

private VideoInfo parseVideoWeb(String videoId, YoutubeCallback<VideoInfo> callback) throws YoutubeException {
String htmlUrl = "https://www.youtube.com/watch?v=" + videoId;

Response<String> response = downloader.downloadWebpage(new RequestWebpage(htmlUrl));
Expand Down Expand Up @@ -198,7 +256,7 @@ private Format parseFormat(JSONObject json, String jsUrl, Itag itag, boolean isA
if (urlWithSig.contains("signature")
|| (!jsonCipher.containsKey("s") && (urlWithSig.contains("&sig=") || urlWithSig.contains("&lsig=")))) {
// do nothing, this is pre-signed videos with signature
} else {
} else if (jsUrl != null) {
String s = jsonCipher.getString("s");
try {
s = URLDecoder.decode(s, "UTF-8");
Expand All @@ -210,6 +268,8 @@ private Format parseFormat(JSONObject json, String jsUrl, Itag itag, boolean isA
String signature = cipher.getSignature(s);
String decipheredUrl = urlWithSig + "&sig=" + signature;
json.put("url", decipheredUrl);
} else {
throw new YoutubeException.BadPageException("deciphering is required but no js url");
}
}

Expand Down Expand Up @@ -403,7 +463,8 @@ private void populatePlaylist(JSONObject content, List<PlaylistVideoDetails> vid
}
}

private void loadPlaylistContinuation(String continuation, String ctp, List<PlaylistVideoDetails> videos, String clientVersion) throws YoutubeException { JSONObject content;
private void loadPlaylistContinuation(String continuation, String ctp, List<PlaylistVideoDetails> videos, String clientVersion) throws YoutubeException {
JSONObject content;
String url = "https://www.youtube.com/youtubei/v1/browse?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8";

JSONObject body = new JSONObject()
Expand Down Expand Up @@ -483,7 +544,7 @@ private PlaylistInfo parseChannelsUploads(String channelId, YoutubeCallback<Play
while (scan.hasNext()) {
String pId = scan.next();
if (pId.startsWith("UU")) {
playlistId = pId.substring(0, 24);
playlistId = pId.substring(0, 24);
break;
}
}
Expand Down

0 comments on commit b84d42f

Please sign in to comment.