diff --git a/src/main/java/me/kavin/piped/utils/ResponseHelper.java b/src/main/java/me/kavin/piped/utils/ResponseHelper.java index 7dd0b42..3d2ea3a 100644 --- a/src/main/java/me/kavin/piped/utils/ResponseHelper.java +++ b/src/main/java/me/kavin/piped/utils/ResponseHelper.java @@ -8,8 +8,10 @@ import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse.BodyHandlers; import java.util.List; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.json.JSONObject; import org.schabi.newpipe.extractor.channel.ChannelInfo; import org.schabi.newpipe.extractor.comments.CommentsInfo; @@ -36,24 +38,47 @@ public class ResponseHelper { .expireAfterWrite(1, TimeUnit.HOURS).maximumSize(1000) .build(key -> CommentsInfo.getInfo("https://www.youtube.com/watch?v=" + key)); - public static final String streamsResponse(String videoId) - throws IOException, ExtractionException, InterruptedException { + public static final String streamsResponse(String videoId) throws Exception { - final StreamInfo info = StreamInfo.getInfo("https://www.youtube.com/watch?v=" + videoId); + CompletableFuture futureStream = CompletableFuture.supplyAsync(() -> { + try { + return StreamInfo.getInfo("https://www.youtube.com/watch?v=" + videoId); + } catch (Exception e) { + ExceptionUtils.rethrow(e); + } + return null; + }); + + CompletableFuture futureLBRY = CompletableFuture.supplyAsync(() -> { + try { + return getLBRYStreamURL(videoId); + } catch (Exception e) { + ExceptionUtils.rethrow(e); + } + return null; + }); final List subtitles = new ObjectArrayList<>(); + final StreamInfo info = futureStream.get(); + info.getSubtitles().forEach(subtitle -> subtitles .add(new Subtitle(rewriteURL(subtitle.getUrl()), subtitle.getFormat().getMimeType()))); final List videoStreams = new ObjectArrayList<>(); final List audioStreams = new ObjectArrayList<>(); - String lbryURL = getLBRYStreamURL(videoId); + final String lbryURL = futureLBRY.get(); if (lbryURL != null) videoStreams.add(new Stream(lbryURL, "MP4", "LBRY", "video/mp4")); + String hls = null; + boolean livestream = false; + + if ((hls = info.getHlsUrl()) != null && !hls.isEmpty()) + livestream = true; + info.getVideoOnlyStreams().forEach(stream -> videoStreams.add(new Stream(rewriteURL(stream.getUrl()), String.valueOf(stream.getFormat()), stream.getResolution(), stream.getFormat().getMimeType()))); info.getVideoStreams().forEach(stream -> videoStreams.add(new Stream(rewriteURL(stream.getUrl()), @@ -76,7 +101,7 @@ public class ResponseHelper { info.getTextualUploadDate(), info.getUploaderName(), info.getUploaderUrl().substring(23), rewriteURL(info.getUploaderAvatarUrl()), rewriteURL(info.getThumbnailUrl()), info.getDuration(), info.getViewCount(), info.getLikeCount(), info.getDislikeCount(), audioStreams, videoStreams, - relatedStreams, subtitles); + relatedStreams, subtitles, livestream, hls); return Constants.mapper.writeValueAsString(streams); diff --git a/src/main/java/me/kavin/piped/utils/obj/Streams.java b/src/main/java/me/kavin/piped/utils/obj/Streams.java index 1fecda4..941e92b 100644 --- a/src/main/java/me/kavin/piped/utils/obj/Streams.java +++ b/src/main/java/me/kavin/piped/utils/obj/Streams.java @@ -4,7 +4,7 @@ import java.util.List; public class Streams { - private String title, description, uploadDate, uploader, uploaderUrl, uploaderAvatar, thumbnailUrl; + private String title, description, uploadDate, uploader, uploaderUrl, uploaderAvatar, thumbnailUrl, hls; private long duration, views, likes, dislikes; @@ -14,10 +14,12 @@ public class Streams { private List subtitles; + private boolean livestream; + 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 audioStreams, List videoStreams, List relatedStreams, - List subtitles) { + List subtitles, boolean livestream, String hls) { this.title = title; this.description = description; this.uploadDate = uploadDate; @@ -33,6 +35,8 @@ public class Streams { this.videoStreams = videoStreams; this.relatedStreams = relatedStreams; this.subtitles = subtitles; + this.livestream = livestream; + this.hls = hls; } public String getTitle() { @@ -94,4 +98,12 @@ public class Streams { public List getSubtitles() { return subtitles; } + + public boolean isLivestream() { + return livestream; + } + + public String getHls() { + return hls; + } }