mirror of
https://github.com/TeamPiped/Piped-Backend.git
synced 2024-08-14 23:51:41 +00:00
Channel Pages and search suggestions.
This commit is contained in:
parent
f3ab50402c
commit
9527ad4133
6 changed files with 131 additions and 20 deletions
|
@ -20,8 +20,6 @@ public class Main {
|
|||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
System.setProperty("file.encoding", "UTF-8");
|
||||
|
||||
// SyndFeed feed = new SyndFeedInput().build(new XmlReader(new FileInputStream("pubsub.xml")));
|
||||
//
|
||||
// feed.getEntries().forEach(entry -> {
|
||||
|
@ -97,6 +95,35 @@ public class Main {
|
|||
|
||||
});
|
||||
|
||||
routes.get("/nextpage/channels/{channelId}", (req, res) -> {
|
||||
|
||||
QueryStringDecoder query = new QueryStringDecoder(req.uri());
|
||||
|
||||
try {
|
||||
return writeResponse(res, ResponseHelper.channelPageResponse(req.param("channelId"),
|
||||
query.parameters().get("url").get(0)), 200, "public, max-age=3600");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return writeResponse(res, ExceptionUtils.getStackTrace(e), 500, "private");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
routes.get("/suggestions", (req, res) -> {
|
||||
|
||||
QueryStringDecoder query = new QueryStringDecoder(req.uri());
|
||||
|
||||
try {
|
||||
return writeResponse(res,
|
||||
ResponseHelper.suggestionsResponse(query.parameters().get("query").get(0)), 200,
|
||||
"public, max-age=600");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return writeResponse(res, ExceptionUtils.getStackTrace(e), 500, "private");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
routes.get("/trending", (req, res) -> {
|
||||
|
||||
try {
|
||||
|
|
|
@ -11,23 +11,29 @@ import java.util.List;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage;
|
||||
import org.schabi.newpipe.extractor.Page;
|
||||
import org.schabi.newpipe.extractor.channel.ChannelInfo;
|
||||
import org.schabi.newpipe.extractor.comments.CommentsInfo;
|
||||
import org.schabi.newpipe.extractor.exceptions.ExtractionException;
|
||||
import org.schabi.newpipe.extractor.exceptions.ParsingException;
|
||||
import org.schabi.newpipe.extractor.kiosk.KioskInfo;
|
||||
import org.schabi.newpipe.extractor.stream.Stream;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfo;
|
||||
import org.schabi.newpipe.extractor.stream.StreamInfoItem;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import me.kavin.piped.consts.Constants;
|
||||
import me.kavin.piped.utils.obj.Channel;
|
||||
import me.kavin.piped.utils.obj.Stream;
|
||||
import me.kavin.piped.utils.obj.ChannelPage;
|
||||
import me.kavin.piped.utils.obj.PipedStream;
|
||||
import me.kavin.piped.utils.obj.StreamItem;
|
||||
import me.kavin.piped.utils.obj.Streams;
|
||||
import me.kavin.piped.utils.obj.Subtitle;
|
||||
|
@ -65,13 +71,13 @@ public class ResponseHelper {
|
|||
info.getSubtitles().forEach(subtitle -> subtitles
|
||||
.add(new Subtitle(rewriteURL(subtitle.getUrl()), subtitle.getFormat().getMimeType())));
|
||||
|
||||
final List<Stream> videoStreams = new ObjectArrayList<>();
|
||||
final List<Stream> audioStreams = new ObjectArrayList<>();
|
||||
final List<PipedStream> videoStreams = new ObjectArrayList<>();
|
||||
final List<PipedStream> audioStreams = new ObjectArrayList<>();
|
||||
|
||||
final String lbryURL = futureLBRY.get();
|
||||
|
||||
if (lbryURL != null)
|
||||
videoStreams.add(new Stream(lbryURL, "MP4", "LBRY", "video/mp4"));
|
||||
videoStreams.add(new PipedStream(lbryURL, "MP4", "LBRY", "video/mp4"));
|
||||
|
||||
String hls = null;
|
||||
boolean livestream = false;
|
||||
|
@ -79,13 +85,31 @@ public class ResponseHelper {
|
|||
if ((hls = info.getHlsUrl()) != null && !hls.isEmpty())
|
||||
livestream = true;
|
||||
|
||||
info.getVideoOnlyStreams().forEach(stream -> videoStreams.add(new Stream(rewriteURL(stream.getUrl()),
|
||||
long minexpire = Long.MAX_VALUE;
|
||||
|
||||
ObjectArrayList<Stream> allStreams = new ObjectArrayList<>();
|
||||
|
||||
allStreams.addAll(info.getVideoStreams());
|
||||
allStreams.addAll(info.getAudioStreams());
|
||||
allStreams.addAll(info.getVideoOnlyStreams());
|
||||
|
||||
for (Stream stream : allStreams) {
|
||||
|
||||
long expire = Long.parseLong(StringUtils.substringBetween(stream.getUrl(), "expire=", "&"));
|
||||
|
||||
if (expire < minexpire)
|
||||
minexpire = expire;
|
||||
|
||||
}
|
||||
|
||||
info.getVideoOnlyStreams().forEach(stream -> videoStreams.add(new PipedStream(rewriteURL(stream.getUrl()),
|
||||
String.valueOf(stream.getFormat()), stream.getResolution(), stream.getFormat().getMimeType())));
|
||||
info.getVideoStreams().forEach(stream -> videoStreams.add(new Stream(rewriteURL(stream.getUrl()),
|
||||
info.getVideoStreams().forEach(stream -> videoStreams.add(new PipedStream(rewriteURL(stream.getUrl()),
|
||||
String.valueOf(stream.getFormat()), stream.getResolution(), stream.getFormat().getMimeType())));
|
||||
|
||||
info.getAudioStreams().forEach(
|
||||
stream -> audioStreams.add(new Stream(rewriteURL(stream.getUrl()), String.valueOf(stream.getFormat()),
|
||||
info.getAudioStreams()
|
||||
.forEach(stream -> audioStreams
|
||||
.add(new PipedStream(rewriteURL(stream.getUrl()), String.valueOf(stream.getFormat()),
|
||||
stream.getAverageBitrate() + " kbps", stream.getFormat().getMimeType())));
|
||||
|
||||
final List<StreamItem> relatedStreams = new ObjectArrayList<>();
|
||||
|
@ -121,13 +145,38 @@ public class ResponseHelper {
|
|||
item.getDuration(), item.getViewCount()));
|
||||
});
|
||||
|
||||
String nextpage = info.hasNextPage() ? info.getNextPage().getUrl() : null;
|
||||
|
||||
final Channel channel = new Channel(info.getName(), info.getAvatarUrl(), info.getBannerUrl(),
|
||||
info.getDescription(), relatedStreams);
|
||||
info.getDescription(), nextpage, relatedStreams);
|
||||
|
||||
return Constants.mapper.writeValueAsString(channel);
|
||||
|
||||
}
|
||||
|
||||
public static final String channelPageResponse(String channelId, String url)
|
||||
throws IOException, ExtractionException, InterruptedException {
|
||||
|
||||
InfoItemsPage<StreamInfoItem> page = ChannelInfo.getMoreItems(Constants.YOUTUBE_SERVICE,
|
||||
"https://youtube.com/channel/" + channelId, new Page(url));
|
||||
|
||||
final List<StreamItem> relatedStreams = new ObjectArrayList<>();
|
||||
|
||||
page.getItems().forEach(o -> {
|
||||
StreamInfoItem item = o;
|
||||
relatedStreams.add(new StreamItem(item.getUrl().substring(23), item.getName(),
|
||||
rewriteURL(item.getThumbnailUrl()), item.getUploaderName(), item.getUploaderUrl().substring(23),
|
||||
item.getDuration(), item.getViewCount()));
|
||||
});
|
||||
|
||||
String nextpage = page.hasNextPage() ? page.getNextPage().getUrl() : null;
|
||||
|
||||
final ChannelPage channelpage = new ChannelPage(nextpage, relatedStreams);
|
||||
|
||||
return Constants.mapper.writeValueAsString(channelpage);
|
||||
|
||||
}
|
||||
|
||||
final List<StreamItem> relatedStreams = new ObjectArrayList<>();
|
||||
|
||||
public static final String trendingResponse() throws ParsingException, ExtractionException, IOException {
|
||||
|
@ -148,6 +197,14 @@ public class ResponseHelper {
|
|||
return Constants.mapper.writeValueAsString(relatedStreams);
|
||||
}
|
||||
|
||||
public static final String suggestionsResponse(String query)
|
||||
throws JsonProcessingException, IOException, ExtractionException {
|
||||
|
||||
return Constants.mapper
|
||||
.writeValueAsString(Constants.YOUTUBE_SERVICE.getSuggestionExtractor().suggestionList(query));
|
||||
|
||||
}
|
||||
|
||||
private static final String getLBRYStreamURL(String videoId) throws IOException, InterruptedException {
|
||||
|
||||
String lbryId = new JSONObject(Constants.h2client.send(HttpRequest
|
||||
|
|
|
@ -4,14 +4,15 @@ import java.util.List;
|
|||
|
||||
public class Channel {
|
||||
|
||||
private String name, avatarUrl, bannerUrl, description;
|
||||
private String name, avatarUrl, bannerUrl, description, nextpage;
|
||||
private List<StreamItem> relatedStreams;
|
||||
|
||||
public Channel(String name, String avatarUrl, String bannerUrl, String description,
|
||||
public Channel(String name, String avatarUrl, String bannerUrl, String description, String nextpage,
|
||||
List<StreamItem> relatedStreams) {
|
||||
this.name = name;
|
||||
this.avatarUrl = avatarUrl;
|
||||
this.description = description;
|
||||
this.nextpage = nextpage;
|
||||
this.relatedStreams = relatedStreams;
|
||||
}
|
||||
|
||||
|
@ -31,6 +32,10 @@ public class Channel {
|
|||
return description;
|
||||
}
|
||||
|
||||
public String getNextpage() {
|
||||
return nextpage;
|
||||
}
|
||||
|
||||
public List<StreamItem> getRelatedStreams() {
|
||||
return relatedStreams;
|
||||
}
|
||||
|
|
22
src/main/java/me/kavin/piped/utils/obj/ChannelPage.java
Normal file
22
src/main/java/me/kavin/piped/utils/obj/ChannelPage.java
Normal file
|
@ -0,0 +1,22 @@
|
|||
package me.kavin.piped.utils.obj;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ChannelPage {
|
||||
|
||||
private String nextpage;
|
||||
private List<StreamItem> relatedStreams;
|
||||
|
||||
public ChannelPage(String nextpage, List<StreamItem> relatedStreams) {
|
||||
this.nextpage = nextpage;
|
||||
this.relatedStreams = relatedStreams;
|
||||
}
|
||||
|
||||
public String getNextpage() {
|
||||
return nextpage;
|
||||
}
|
||||
|
||||
public List<StreamItem> getRelatedStreams() {
|
||||
return relatedStreams;
|
||||
}
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package me.kavin.piped.utils.obj;
|
||||
|
||||
public class Stream {
|
||||
public class PipedStream {
|
||||
|
||||
private String url, format, quality, mimeType;
|
||||
|
||||
public Stream(String url, String format, String quality, String mimeType) {
|
||||
public PipedStream(String url, String format, String quality, String mimeType) {
|
||||
this.url = url;
|
||||
this.format = format;
|
||||
this.quality = quality;
|
|
@ -8,7 +8,7 @@ public class Streams {
|
|||
|
||||
private long duration, views, likes, dislikes;
|
||||
|
||||
private List<Stream> audioStreams, videoStreams;
|
||||
private List<PipedStream> audioStreams, videoStreams;
|
||||
|
||||
private List<StreamItem> relatedStreams;
|
||||
|
||||
|
@ -18,7 +18,7 @@ public class Streams {
|
|||
|
||||
public Streams(String title, String description, String uploadDate, String uploader, String uploaderUrl,
|
||||
String uploaderAvatar, String thumbnailUrl, long duration, long views, long likes, long dislikes,
|
||||
List<Stream> audioStreams, List<Stream> videoStreams, List<StreamItem> relatedStreams,
|
||||
List<PipedStream> audioStreams, List<PipedStream> videoStreams, List<StreamItem> relatedStreams,
|
||||
List<Subtitle> subtitles, boolean livestream, String hls) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
|
@ -83,11 +83,11 @@ public class Streams {
|
|||
return dislikes;
|
||||
}
|
||||
|
||||
public List<Stream> getAudioStreams() {
|
||||
public List<PipedStream> getAudioStreams() {
|
||||
return audioStreams;
|
||||
}
|
||||
|
||||
public List<Stream> getVideoStreams() {
|
||||
public List<PipedStream> getVideoStreams() {
|
||||
return videoStreams;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue