Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/main/java/YouTubeSearchApi/YoutubeClient.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package YouTubeSearchApi;

import YouTubeSearchApi.entity.YoutubePlaylist;
import YouTubeSearchApi.entity.YoutubeVideo;
import YouTubeSearchApi.exception.NoResultFoundException;
import YouTubeSearchApi.utility.Utils;
Expand All @@ -13,6 +14,8 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class YoutubeClient {

Expand All @@ -39,7 +42,7 @@ public List<YoutubeVideo> search(String keywords, int maxResults) throws IOExcep
}

if (!foundFeatureFlag) {
throw new NoResultFoundException("what you searched was unfortunately not found or doesn't exist. keywords: " + keywords);
throw new NoResultFoundException("What you searched was unfortunately not found or doesn't exist. keywords: " + keywords);
}


Expand Down Expand Up @@ -112,4 +115,36 @@ public YoutubeVideo getInfoByVideoUrl(String videoUrl) throws IOException {

return YoutubeVideo.getParsedOEmbedObject(videoObject);
}

public YoutubePlaylist getRecommendation(String videoId) throws IOException, NoResultFoundException {
String requestUrl = this.YOUTUBE_BASE_URL + "watch?v=" + videoId;

String pageContent = Utils.httpRequest(requestUrl);

Pattern pattern = Pattern.compile(
"\"compactRadioRenderer\"(.+?)\"compactVideoRenderer\"",
Pattern.CASE_INSENSITIVE
);
Matcher matcher = pattern.matcher(pageContent);

if (matcher.find()) {
String compactRadioRenderer = matcher.group();
compactRadioRenderer = "{" + compactRadioRenderer.substring(0,
compactRadioRenderer.length() - ",{\"compactVideoRenderer\"".length());

System.out.println(compactRadioRenderer);

Gson gson = new Gson();

JsonObject compactRadioRendererObject = gson.fromJson(compactRadioRenderer, JsonObject.class)
.get("compactRadioRenderer")
.getAsJsonObject();
YoutubePlaylist youtubePlaylist = YoutubePlaylist.parseCompactRadioRenderer(compactRadioRendererObject);

return youtubePlaylist;
}
else {
throw new NoResultFoundException("Cannot find any recommendation for videoId: " + videoId);
}
}
}
94 changes: 94 additions & 0 deletions src/main/java/YouTubeSearchApi/entity/YoutubePlaylist.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package YouTubeSearchApi.entity;

import com.google.gson.JsonObject;

public class YoutubePlaylist {

private String id;
private String url;
private String title;
private String thumbnailUrl;
private String metadataUrl;

public YoutubePlaylist(String id, String url, String title, String thumbnailUrl, String metaDataUrl) {
this.id = id;
this.url = url;
this.title = title;
this.thumbnailUrl = thumbnailUrl;
this.metadataUrl = metaDataUrl;
}

public static YoutubePlaylist parseCompactRadioRenderer(JsonObject compactRadioRendererObject) {
String playlistId = compactRadioRendererObject.get("playlistId").getAsString();

String thumbnailUrl = compactRadioRendererObject.get("thumbnail").getAsJsonObject()
.get("thumbnails").getAsJsonArray()
.get(0).getAsJsonObject()
.get("url").getAsString();

String title = compactRadioRendererObject.get("title").getAsJsonObject()
.get("simpleText").getAsString();

String playlistUrl = compactRadioRendererObject.get("shareUrl").getAsString()
.replace("\\u0026", "&");

String metaDataUrl = compactRadioRendererObject.get("navigationEndpoint").getAsJsonObject()
.get("commandMetadata").getAsJsonObject()
.get("webCommandMetadata").getAsJsonObject()
.get("url").getAsString()
.replace("\\u0026", "&");

return new YoutubePlaylist(playlistId, playlistUrl, title, thumbnailUrl, metaDataUrl);
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getUrl() {
return url;
}

public void setUrl(String url) {
this.url = url;
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getThumbnailUrl() {
return thumbnailUrl;
}

public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}

public String getMetadataUrl() {
return metadataUrl;
}

public void setMetadataUrl(String metadataUrl) {
this.metadataUrl = metadataUrl;
}

@Override
public String toString() {
return "YoutubePlaylist{" +
"id='" + id + '\'' +
", url='" + url + '\'' +
", title='" + title + '\'' +
", thumbnailUrl='" + thumbnailUrl + '\'' +
", metadataUrl='" + metadataUrl + '\'' +
'}';
}
}
7 changes: 7 additions & 0 deletions src/main/java/YouTubeSearchApi/utility/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;

public class Utils {

Expand Down Expand Up @@ -42,4 +44,9 @@ public static String httpRequest(String url) throws IOException {

return stringBuilder.toString();
}

public static String readFile(String path, Charset encoding) throws IOException {
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package YouTubeSearchApi;

import YouTubeSearchApi.entity.YoutubePlaylist;
import YouTubeSearchApi.exception.NoResultFoundException;

import java.io.IOException;

public class TestYoutubeClientGetRecommendation {
public static void main(String[] args) {
YoutubeClient client = new YoutubeClient();
try {
YoutubePlaylist youtubePlaylist = client.getRecommendation("oCrwzN6eb4Q");
System.out.println(youtubePlaylist);
} catch (IOException | NoResultFoundException e) {
e.printStackTrace();
}
}
}