diff --git a/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java b/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java index 7d8b14c89..654e09a64 100644 --- a/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java +++ b/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeStreamExtractor.java @@ -720,38 +720,40 @@ public class YoutubeStreamExtractor extends StreamExtractor { } catch (IOException | ExtractionException e) { throw new SubtitlesException("Unable to download player configs", e); } - final String playerResponse = playerConfig.getObject("args").getString("player_response"); + final String playerResponse = playerConfig.getObject("args", new JsonObject()) + .getString("player_response"); final JsonObject captions; try { - if (!JsonParser.object().from(playerResponse).has("captions")) { + if (playerResponse == null || !JsonParser.object().from(playerResponse).has("captions")) { // Captions does not exist return Collections.emptyList(); } captions = JsonParser.object().from(playerResponse).getObject("captions"); } catch (JsonParserException e) { - // Failed to parse subtitles throw new SubtitlesException("Unable to parse subtitles listing", e); } - final JsonObject renderer = captions.getObject("playerCaptionsTracklistRenderer"); - final JsonArray captionsArray = renderer.getArray("captionTracks"); - + final JsonObject renderer = captions.getObject("playerCaptionsTracklistRenderer", new JsonObject()); + final JsonArray captionsArray = renderer.getArray("captionTracks", new JsonArray()); // todo: use this to apply auto translation to different language from a source language - final JsonArray autoCaptionsArray = renderer.getArray("translationLanguages"); + final JsonArray autoCaptionsArray = renderer.getArray("translationLanguages", new JsonArray()); + // This check is necessary since there may be cases where subtitles metadata do not contain caption track info + // e.g. https://www.youtube.com/watch?v=-Vpwatutnko final int captionsSize = captionsArray.size(); - // Should not happen, if there is the "captions" object, it should always has some captions in it if(captionsSize == 0) return Collections.emptyList(); - // Obtain the base url, this only needs to be done once List result = new ArrayList<>(); for (int i = 0; i < captionsSize; i++) { final String languageCode = captionsArray.getObject(i).getString("languageCode"); final String baseUrl = captionsArray.getObject(i).getString("baseUrl"); - final boolean isAutoGenerated = captionsArray.getObject(i).getString("vssId").startsWith("a."); + final String vssId = captionsArray.getObject(i).getString("vssId"); - result.add(new SubtitlesInfo(baseUrl, languageCode, isAutoGenerated)); + if (languageCode != null && baseUrl != null && vssId != null) { + final boolean isAutoGenerated = vssId.startsWith("a."); + result.add(new SubtitlesInfo(baseUrl, languageCode, isAutoGenerated)); + } } return result; diff --git a/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfo.java b/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfo.java index 27df6d331..995bfb003 100644 --- a/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfo.java +++ b/src/main/java/org/schabi/newpipe/extractor/stream/StreamInfo.java @@ -321,12 +321,6 @@ public class StreamInfo extends Info { streamInfo.addError(new ExtractionException("Couldn't get video only streams", e)); } - try { - streamInfo.setSubtitles(extractor.getSubtitlesDefault()); - } catch (Exception e) { - streamInfo.addError(new ExtractionException("Couldn't get subtitles", e)); - } - // Lists can be null if a exception was thrown during extraction if (streamInfo.getVideoStreams() == null) streamInfo.setVideoStreams(Collections.emptyList()); if (streamInfo.getVideoOnlyStreams()== null) streamInfo.setVideoOnlyStreams(Collections.emptyList()); @@ -425,7 +419,11 @@ public class StreamInfo extends Info { } catch (Exception e) { streamInfo.addError(e); } - + try { + streamInfo.setSubtitles(extractor.getSubtitlesDefault()); + } catch (Exception e) { + streamInfo.addError(e); + } streamInfo.setRelatedStreams(ExtractorHelper.getRelatedVideosOrLogError(streamInfo, extractor)); return streamInfo; }