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 3e60e0265..6219937e5 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 @@ -85,8 +85,9 @@ public class YoutubeStreamExtractor extends StreamExtractor { private JsonObject playerArgs; @Nonnull private final Map videoInfoPage = new HashMap<>(); + @Nonnull - private List availableSubtitles = new ArrayList<>(); + private List subtitlesInfos = new ArrayList<>(); private boolean isAgeRestricted; @@ -432,11 +433,11 @@ public class YoutubeStreamExtractor extends StreamExtractor { @Override @Nonnull - public List getSubtitles(SubtitlesFormat format) throws IOException, ExtractionException { + public List getSubtitles(final SubtitlesFormat format) throws IOException, ExtractionException { assertPageFetched(); List subtitles = new ArrayList<>(); - for (final Subtitles subtitle : availableSubtitles) { - if (subtitle.getFileType() == format) subtitles.add(subtitle); + for (final SubtitlesInfo subtitlesInfo : subtitlesInfos) { + subtitles.add(subtitlesInfo.getSubtitle(format)); } return subtitles; } @@ -553,8 +554,8 @@ public class YoutubeStreamExtractor extends StreamExtractor { decryptionCode = loadDecryptionCode(playerUrl); } - if (availableSubtitles.isEmpty()) { - availableSubtitles.addAll(getAvailableSubtitles()); + if (subtitlesInfos.isEmpty()) { + subtitlesInfos.addAll(getAvailableSubtitlesInfo()); } } @@ -709,7 +710,7 @@ public class YoutubeStreamExtractor extends StreamExtractor { } @Nonnull - private List getAvailableSubtitles() throws SubtitlesException { + private List getAvailableSubtitlesInfo() throws SubtitlesException { // If the video is age restricted getPlayerConfig will fail if(isAgeRestricted) return Collections.emptyList(); @@ -744,17 +745,13 @@ public class YoutubeStreamExtractor extends StreamExtractor { if(captionsSize == 0) return Collections.emptyList(); // Obtain the base url, this only needs to be done once - List result = new ArrayList<>(); + 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."); - result.add(new Subtitles(SubtitlesFormat.TTML, languageCode, - getSubtitleFormatUrl(baseUrl, SubtitlesFormat.TTML), isAutoGenerated)); - result.add(new Subtitles(SubtitlesFormat.VTT, languageCode, - getSubtitleFormatUrl(baseUrl, SubtitlesFormat.VTT), isAutoGenerated)); - // todo: add transcripts, they are currently omitted since they are incompatible with ExoPlayer + result.add(new SubtitlesInfo(baseUrl, languageCode, isAutoGenerated)); } return result; @@ -773,6 +770,24 @@ public class YoutubeStreamExtractor extends StreamExtractor { } } + private class SubtitlesInfo { + final String cleanUrl; + final String languageCode; + final boolean isGenerated; + + public SubtitlesInfo(final String baseUrl, final String languageCode, final boolean isGenerated) { + this.cleanUrl = baseUrl + .replaceAll("&fmt=[^&]*", "") // Remove preexisting format if exists + .replaceAll("&tlang=[^&]*", ""); // Remove translation language + this.languageCode = languageCode; + this.isGenerated = isGenerated; + } + + public Subtitles getSubtitle(final SubtitlesFormat format) { + return new Subtitles(format, languageCode, cleanUrl + "&fmt=" + format.getExtension(), isGenerated); + } + } + /*////////////////////////////////////////////////////////////////////////// // Utils //////////////////////////////////////////////////////////////////////////*/