-Fix subtitles extraction NPE on certain video that contains no caption info.

-Moved subtitles to optional data extraction.
This commit is contained in:
John Zhen Mo 2018-02-06 10:45:58 -08:00
parent 7fd21ec085
commit ccc8cde80e
2 changed files with 18 additions and 18 deletions

View File

@ -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<SubtitlesInfo> 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;

View File

@ -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.<VideoStream>emptyList());
if (streamInfo.getVideoOnlyStreams()== null) streamInfo.setVideoOnlyStreams(Collections.<VideoStream>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;
}