From 89a77ae74a939bb6180b57266ba50f82a37caa73 Mon Sep 17 00:00:00 2001 From: Stypox Date: Wed, 4 Nov 2020 14:50:35 +0100 Subject: [PATCH] [YouTube] Fix detection of ended livestreams and parse livestream upload date --- .../extractors/YoutubeStreamExtractor.java | 37 +++++++++++-------- .../YoutubeStreamExtractorLivestreamTest.java | 4 +- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java index fb82d341..608ae47c 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java @@ -137,18 +137,27 @@ public class YoutubeStreamExtractor extends StreamExtractor { return title; } + @Nullable @Override public String getTextualUploadDate() throws ParsingException { - if (getStreamType().equals(StreamType.LIVE_STREAM)) { - return null; - } - - JsonObject micro = playerResponse.getObject("microformat").getObject("playerMicroformatRenderer"); - if (micro.isString("uploadDate") && !micro.getString("uploadDate").isEmpty()) { + final JsonObject micro = + playerResponse.getObject("microformat").getObject("playerMicroformatRenderer"); + if (!micro.getString("uploadDate", EMPTY_STRING).isEmpty()) { return micro.getString("uploadDate"); - } - if (micro.isString("publishDate") && !micro.getString("publishDate").isEmpty()) { + } else if (!micro.getString("publishDate", EMPTY_STRING).isEmpty()) { return micro.getString("publishDate"); + } else { + final JsonObject liveDetails = micro.getObject("liveBroadcastDetails"); + if (!liveDetails.getString("endTimestamp", EMPTY_STRING).isEmpty()) { + // an ended live stream + return liveDetails.getString("endTimestamp"); + } else if (!liveDetails.getString("startTimestamp", EMPTY_STRING).isEmpty()) { + // a running live stream + return liveDetails.getString("startTimestamp"); + } else if (getStreamType() == StreamType.LIVE_STREAM) { + // this should never be reached, but a live stream without upload date is valid + return null; + } } if (getTextFromObject(getVideoPrimaryInfoRenderer().getObject("dateText")).startsWith("Premiered")) { @@ -176,6 +185,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { return DateTimeFormatter.ISO_LOCAL_DATE.format(localDate); } catch (Exception ignored) { } + throw new ParsingException("Could not get upload date"); } @@ -597,16 +607,13 @@ public class YoutubeStreamExtractor extends StreamExtractor { } @Override - public StreamType getStreamType() throws ParsingException { + public StreamType getStreamType() { assertPageFetched(); - try { - return playerResponse.getObject("videoDetails").getBoolean("isLiveContent") - ? StreamType.LIVE_STREAM : StreamType.VIDEO_STREAM; - } catch (Exception e) { - throw new ParsingException("Could not get stream type", e); - } + return playerResponse.getObject("streamingData").has(FORMATS) + ? StreamType.VIDEO_STREAM : StreamType.LIVE_STREAM; } + @Nullable private StreamInfoItemExtractor getNextStream() throws ExtractionException { try { final JsonObject firstWatchNextItem = initialData.getObject("contents") diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java index c1c84ed4..5c53a69e 100644 --- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java +++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/stream/YoutubeStreamExtractorLivestreamTest.java @@ -45,8 +45,8 @@ public class YoutubeStreamExtractorLivestreamTest extends DefaultStreamExtractor @Override public long expectedLength() { return 0; } @Override public long expectedTimestamp() { return TIMESTAMP; } @Override public long expectedViewCountAtLeast() { return 0; } - @Nullable @Override public String expectedUploadDate() { return null; } - @Nullable @Override public String expectedTextualUploadDate() { return null; } + @Nullable @Override public String expectedUploadDate() { return "2020-02-22 00:00:00.000"; } + @Nullable @Override public String expectedTextualUploadDate() { return "2020-02-22"; } @Override public long expectedLikeCountAtLeast() { return 825000; } @Override public long expectedDislikeCountAtLeast() { return 15600; } @Override public boolean expectedHasSubtitles() { return false; }