From aa4c10e7517f60359f6c3fc911c67d2cd125b79a Mon Sep 17 00:00:00 2001 From: TiA4f8R <74829229+TiA4f8R@users.noreply.github.com> Date: Tue, 15 Mar 2022 11:19:13 +0100 Subject: [PATCH] Improve documentation and adress most of the requested changes Also fix some issues in several places, in the code and the documentation. --- .../extractors/BandcampStreamExtractor.java | 4 +- .../MediaCCCLiveStreamExtractor.java | 171 ++++++------- .../MediaCCCLiveStreamMapperDTO.java | 29 +++ .../extractors/MediaCCCStreamExtractor.java | 9 +- .../extractors/PeertubeStreamExtractor.java | 110 ++++---- .../extractors/SoundcloudStreamExtractor.java | 25 +- .../services/youtube/DashMpdParser.java | 56 ++-- .../extractor/services/youtube/ItagInfo.java | 37 --- .../extractor/services/youtube/ItagItem.java | 86 +++---- .../youtube/YoutubeDashManifestCreator.java | 218 ++++++++++------ .../youtube/YoutubeParsingHelper.java | 6 +- .../services/youtube/extractors/ItagInfo.java | 80 ++++++ .../extractors/YoutubeStreamExtractor.java | 242 ++++++++++++------ .../newpipe/extractor/stream/AudioStream.java | 27 +- .../extractor/stream/DeliveryMethod.java | 28 +- .../newpipe/extractor/stream/Stream.java | 60 +++-- .../newpipe/extractor/stream/StreamType.java | 23 +- .../extractor/stream/SubtitlesStream.java | 41 +-- .../newpipe/extractor/stream/VideoStream.java | 27 +- .../YoutubeDashManifestCreatorTest.java | 2 +- 20 files changed, 759 insertions(+), 522 deletions(-) create mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamMapperDTO.java delete mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagInfo.java create mode 100644 extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/ItagInfo.java diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java index 9bb6d5c78..4b5d9d12a 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/bandcamp/extractors/BandcampStreamExtractor.java @@ -120,9 +120,9 @@ public class BandcampStreamExtractor extends StreamExtractor { public String getThumbnailUrl() throws ParsingException { if (albumJson.isNull("art_id")) { return EMPTY_STRING; - } else { - return getImageUrl(albumJson.getLong("art_id"), true); } + + return getImageUrl(albumJson.getLong("art_id"), true); } @Nonnull diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java index 54c2d056c..09e01ce36 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/media_ccc/extractors/MediaCCCLiveStreamExtractor.java @@ -12,15 +12,16 @@ import org.schabi.newpipe.extractor.linkhandler.LinkHandler; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.DeliveryMethod; import org.schabi.newpipe.extractor.stream.Description; +import org.schabi.newpipe.extractor.stream.Stream; import org.schabi.newpipe.extractor.stream.StreamExtractor; import org.schabi.newpipe.extractor.stream.StreamType; import org.schabi.newpipe.extractor.stream.VideoStream; import java.io.IOException; -import java.util.ArrayList; import java.util.Collections; import java.util.List; -import java.util.stream.IntStream; +import java.util.function.Function; +import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -58,9 +59,9 @@ public class MediaCCCLiveStreamExtractor extends StreamExtractor { final JsonObject roomObject = rooms.getObject(r); if (getId().equals(conferenceObject.getString("slug") + "/" + roomObject.getString("slug"))) { - this.conference = conferenceObject; - this.group = groupObject; - this.room = roomObject; + conference = conferenceObject; + group = groupObject; + room = roomObject; return; } } @@ -109,122 +110,120 @@ public class MediaCCCLiveStreamExtractor extends StreamExtractor { * Get the URL of the first DASH stream found. * *
- * There can be several DASH streams, so the URL of the first found is returned by this method. + * There can be several DASH streams, so the URL of the first one found is returned by this + * method. *
* *- * You can find the other video DASH streams by using {@link #getVideoStreams()} + * You can find the other DASH video streams by using {@link #getVideoStreams()} *
*/ @Nonnull @Override public String getDashMpdUrl() throws ParsingException { - - for (int s = 0; s < room.getArray(STREAMS).size(); s++) { - final JsonObject stream = room.getArray(STREAMS).getObject(s); - final JsonObject urls = stream.getObject(URLS); - if (urls.has("dash")) { - return urls.getObject("dash").getString(URL, EMPTY_STRING); - } - } - - return EMPTY_STRING; + return getManifestOfDeliveryMethodWanted("dash"); } /** * Get the URL of the first HLS stream found. * *- * There can be several HLS streams, so the URL of the first found is returned by this method. + * There can be several HLS streams, so the URL of the first one found is returned by this + * method. *
* *- * You can find the other video HLS streams by using {@link #getVideoStreams()} + * You can find the other HLS video streams by using {@link #getVideoStreams()} *
*/ @Nonnull @Override public String getHlsUrl() { - for (int s = 0; s < room.getArray(STREAMS).size(); s++) { - final JsonObject stream = room.getArray(STREAMS).getObject(s); - final JsonObject urls = stream.getObject(URLS); - if (urls.has("hls")) { - return urls.getObject("hls").getString(URL, EMPTY_STRING); - } - } - return EMPTY_STRING; + return getManifestOfDeliveryMethodWanted("hls"); + } + + @Nonnull + private String getManifestOfDeliveryMethodWanted(@Nonnull final String deliveryMethod) { + return room.getArray(STREAMS).stream() + .filter(JsonObject.class::isInstance) + .map(JsonObject.class::cast) + .map(streamObject -> streamObject.getObject(URLS)) + .filter(urls -> urls.has(deliveryMethod)) + .map(urls -> urls.getObject(deliveryMethod).getString(URL, EMPTY_STRING)) + .findFirst() + .orElse(EMPTY_STRING); } @Override public List* A track can have the {@code downloadable} boolean set to {@code true}, but it doesn't mean - * we can download it: if the value of the {@code has_download_left} boolean is true, the track - * can be downloaded; otherwise not. + * we can download it. *
* - * @param audioStreams the audio streams to which add the downloadable file + *+ * If the value of the {@code has_download_left} boolean is {@code true}, the track can be + * downloaded, and not otherwise. + *
+ * + * @param audioStreams the audio streams to which the downloadable file is added */ public void extractDownloadableFileIfAvailable(final List- * This method downloads the provided manifest URL, find all web occurrences in the manifest, - * get the last segment URL, changes its segment range to {@code 0/track-length} and return - * this string. + * This method downloads the provided manifest URL, finds all web occurrences in the manifest, + * gets the last segment URL, changes its segment range to {@code 0/track-length}, and return + * this as a string. *
* * @param hlsManifestUrl the URL of the manifest to be parsed diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/DashMpdParser.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/DashMpdParser.java index 77cee35bb..2b5774049 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/DashMpdParser.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/DashMpdParser.java @@ -27,7 +27,6 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException; import org.schabi.newpipe.extractor.exceptions.ReCaptchaException; import org.schabi.newpipe.extractor.stream.AudioStream; import org.schabi.newpipe.extractor.stream.DeliveryMethod; -import org.schabi.newpipe.extractor.stream.StreamInfo; import org.schabi.newpipe.extractor.stream.VideoStream; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -52,10 +51,26 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +/** + * Class to extract streams from a DASH manifest. + * + *+ * Note that this class relies on the YouTube's {@link ItagItem} class and should be made generic + * in order to be used on other services. + *
+ * + *+ * This class is not used by the extractor itself, as all streams are supported by the extractor. + *
+ */ public final class DashMpdParser { private DashMpdParser() { } + /** + * Exception class which is thrown when something went wrong when using + * {@link DashMpdParser#getStreams(String)}. + */ public static class DashMpdParsingException extends ParsingException { DashMpdParsingException(final String message, final Exception e) { @@ -63,15 +78,21 @@ public final class DashMpdParser { } } + /** + * Class which represents the result of a DASH MPD file parsing by {@link DashMpdParser}. + * + *+ * The result contains video, video-only and audio streams. + *
+ */ public static class Result { private final List- * It has video, video only and audio streams. - *
- * Info about DASH MPD can be found here + * This method will try to download and parse the YouTube DASH MPD manifest URL provided to get + * supported {@link AudioStream}s and {@link VideoStream}s. * - * @param dashMpdUrl URL to the DASH MPD + *
+ * The parser supports video, video-only and audio streams. + *
+ * + * @param dashMpdUrl the URL of the DASH MPD manifest + * @return a {@link Result} which contains all video, video-only and audio streams extracted + * and supported by the extractor (so the ones for which {@link ItagItem#isSupported(int)} + * returns {@code true}). + * @throws DashMpdParsingException if something went wrong when downloading or parsing the + * manifest * @see - * www.brendanlog.com + * www.brendanlong.com's page about the structure of an MPEG-DASH MPD manifest */ @Nonnull public static Result getStreams(final String dashMpdUrl) @@ -188,7 +212,7 @@ public final class DashMpdParser { throws TransformerException { final Element mpdElement = (Element) document.getElementsByTagName("MPD").item(0); - // Clone element so we can freely modify it + // Clone the element so we can freely modify it final Element adaptationSet = (Element) representation.getParentNode(); final Element adaptationSetClone = (Element) adaptationSet.cloneNode(true); diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagInfo.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagInfo.java deleted file mode 100644 index cdb5dc2de..000000000 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.schabi.newpipe.extractor.services.youtube; - -import javax.annotation.Nonnull; -import java.io.Serializable; - -public final class ItagInfo implements Serializable { - - @Nonnull - private final String content; - @Nonnull - private final ItagItem itagItem; - private boolean isUrl; - - public ItagInfo(@Nonnull final String content, - @Nonnull final ItagItem itagItem) { - this.content = content; - this.itagItem = itagItem; - } - - public void setIsUrl(final boolean isUrl) { - this.isUrl = isUrl; - } - - @Nonnull - public String getContent() { - return content; - } - - @Nonnull - public ItagItem getItagItem() { - return itagItem; - } - - public boolean getIsUrl() { - return isUrl; - } -} diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagItem.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagItem.java index 79f44078f..9608de8ec 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagItem.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/ItagItem.java @@ -237,11 +237,15 @@ public class ItagItem implements Serializable { } /** - * Get the frame rate per second. + * Get the frame rate. * *- * It defaults to the standard value associated with this itag and is set to the {@code fps} - * value returned in the corresponding itag in the YouTube player response. + * It is set to the {@code fps} value returned in the corresponding itag in the YouTube player + * response. + *
+ * + *+ * It defaults to the standard value associated with this itag. *
* *@@ -249,28 +253,24 @@ public class ItagItem implements Serializable { * #FPS_NOT_APPLICABLE_OR_UNKNOWN} is returned for non video itags. *
* - * @return the frame rate per second or {@link #FPS_NOT_APPLICABLE_OR_UNKNOWN} + * @return the frame rate or {@link #FPS_NOT_APPLICABLE_OR_UNKNOWN} */ public int getFps() { return fps; } /** - * Set the frame rate per second. + * Set the frame rate. * ** It is only known for video itags, so {@link #FPS_NOT_APPLICABLE_OR_UNKNOWN} is set/used for * non video itags or if the sample rate value is less than or equal to 0. *
* - * @param fps the frame rate per second + * @param fps the frame rate */ public void setFps(final int fps) { - if (fps > 0) { - this.fps = fps; - } else { - this.fps = FPS_NOT_APPLICABLE_OR_UNKNOWN; - } + this.fps = fps > 0 ? fps : FPS_NOT_APPLICABLE_OR_UNKNOWN; } public int getInitStart() { @@ -314,13 +314,13 @@ public class ItagItem implements Serializable { } /** - * Get the resolution string associated to this {@code ItagItem}. + * Get the resolution string associated with this {@code ItagItem}. * ** It is only known for video itags. *
* - * @return the resolution string associated to this {@code ItagItem} or + * @return the resolution string associated with this {@code ItagItem} or * {@code null}. */ @Nullable @@ -361,7 +361,7 @@ public class ItagItem implements Serializable { * ** It is only known for audio itags, so {@link #SAMPLE_RATE_UNKNOWN} is returned for non audio - * itags or if the sample rate is unknown. + * itags, or if the sample rate is unknown. *
* * @return the sample rate or {@link #SAMPLE_RATE_UNKNOWN} @@ -374,8 +374,8 @@ public class ItagItem implements Serializable { * Set the sample rate. * *- * It is only known for audio itags, so {@link #SAMPLE_RATE_UNKNOWN} is set/used for non video - * itags or if the sample rate value is less than or equal to 0. + * It is only known for audio itags, so {@link #SAMPLE_RATE_UNKNOWN} is set/used for non audio + * itags, or if the sample rate value is less than or equal to 0. *
* * @param sampleRate the sample rate of an audio itag @@ -392,8 +392,8 @@ public class ItagItem implements Serializable { * Get the number of audio channels. * *- * It is only known for audio streams, so {@link #AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN} is - * returned for video streams or if it is unknown. + * It is only known for audio itags, so {@link #AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN} is + * returned for non audio itags, or if it is unknown. *
* * @return the number of audio channels or {@link #AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN} @@ -406,28 +406,26 @@ public class ItagItem implements Serializable { * Set the number of audio channels. * *- * It is only known for audio itag, so {@link #AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN} is - * set/used for non audio itags or if the {@code audioChannels} value is less than or equal to + * It is only known for audio itags, so {@link #AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN} is + * set/used for non audio itags, or if the {@code audioChannels} value is less than or equal to * 0. *
* * @param audioChannels the number of audio channels of an audio itag */ public void setAudioChannels(final int audioChannels) { - if (audioChannels > 0) { - this.audioChannels = audioChannels; - } else { - this.audioChannels = AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN; - } + this.audioChannels = audioChannels > 0 + ? audioChannels + : AUDIO_CHANNELS_NOT_APPLICABLE_OR_UNKNOWN; } /** * Get the {@code targetDurationSec} value. * *- * This value is an average time in seconds of sequences duration of livestreams and ended - * livestreams. It is only returned for these stream types by YouTube and makes no sense for - * videos, so {@link #TARGET_DURATION_SEC_UNKNOWN} is returned for video streams. + * This value is the average time in seconds of the duration of sequences of livestreams and + * ended livestreams. It is only returned by YouTube for these stream types, and makes no sense + * for videos, so {@link #TARGET_DURATION_SEC_UNKNOWN} is returned for those. *
* * @return the {@code targetDurationSec} value or {@link #TARGET_DURATION_SEC_UNKNOWN} @@ -440,25 +438,23 @@ public class ItagItem implements Serializable { * Set the {@code targetDurationSec} value. * *- * This value is an average time in seconds of sequences duration of livestreams and ended - * livestreams. + * This value is the average time in seconds of the duration of sequences of livestreams and + * ended livestreams. *
* *- * It is only returned for these stream types by YouTube and makes no sense for - * videos, so {@link #TARGET_DURATION_SEC_UNKNOWN} will be set/used for video streams or if - * this value is less than or equal to 0. + * It is only returned for these stream types by YouTube and makes no sense for videos, so + * {@link #TARGET_DURATION_SEC_UNKNOWN} will be set/used for video streams or if this value is + * less than or equal to 0. *
* * @param targetDurationSec the target duration of a segment of streams which are using the * live delivery method type */ public void setTargetDurationSec(final int targetDurationSec) { - if (targetDurationSec > 0) { - this.targetDurationSec = targetDurationSec; - } else { - this.targetDurationSec = TARGET_DURATION_SEC_UNKNOWN; - } + this.targetDurationSec = targetDurationSec > 0 + ? targetDurationSec + : TARGET_DURATION_SEC_UNKNOWN; } /** @@ -487,11 +483,9 @@ public class ItagItem implements Serializable { * milliseconds */ public void setApproxDurationMs(final long approxDurationMs) { - if (approxDurationMs > 0) { - this.approxDurationMs = approxDurationMs; - } else { - this.approxDurationMs = APPROX_DURATION_MS_UNKNOWN; - } + this.approxDurationMs = approxDurationMs > 0 + ? approxDurationMs + : APPROX_DURATION_MS_UNKNOWN; } /** @@ -519,10 +513,6 @@ public class ItagItem implements Serializable { * @param contentLength the content length of a DASH progressive stream */ public void setContentLength(final long contentLength) { - if (contentLength > 0) { - this.contentLength = contentLength; - } else { - this.contentLength = CONTENT_LENGTH_UNKNOWN; - } + this.contentLength = contentLength > 0 ? contentLength : CONTENT_LENGTH_UNKNOWN; } } diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreator.java b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreator.java index 62d833f51..2d7f7fe22 100644 --- a/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreator.java +++ b/extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreator.java @@ -35,7 +35,6 @@ import static org.schabi.newpipe.extractor.utils.Utils.*; * It relies on external classes from the {@link org.w3c.dom} and {@link javax.xml} packages. * */ -@SuppressWarnings({"ConstantConditions", "unused"}) public final class YoutubeDashManifestCreator { /** @@ -115,6 +114,7 @@ public final class YoutubeDashManifestCreator { * */ PROGRESSIVE, + /** * YouTube's OTF delivery method which uses a sequence parameter to get segments of * streams. @@ -124,12 +124,14 @@ public final class YoutubeDashManifestCreator { * metadata needed to build the stream source (sidx boxes, segment length, segment count, * duration, ...) * + * ** Only used for videos; mostly those with a small amount of views, or ended livestreams * which have just been re-encoded as normal videos. *
*/ OTF, + /** * YouTube's delivery method for livestreams which uses a sequence parameter to get * segments of streams. @@ -139,6 +141,7 @@ public final class YoutubeDashManifestCreator { * metadata (sidx boxes, segment length, ...), which make no need of an initialization * segment. * + * ** Only used for livestreams (ended or running). *
@@ -225,27 +228,27 @@ public final class YoutubeDashManifestCreator { */ @Nonnull public static String createDashManifestFromOtfStreamingUrl( - @Nonnull String otfBaseStreamingUrl, + @Nonnull final String otfBaseStreamingUrl, @Nonnull final ItagItem itagItem, - final long durationSecondsFallback) - throws YoutubeDashManifestCreationException { + final long durationSecondsFallback) throws YoutubeDashManifestCreationException { if (GENERATED_OTF_MANIFESTS.containsKey(otfBaseStreamingUrl)) { - return GENERATED_OTF_MANIFESTS.get(otfBaseStreamingUrl).getSecond(); + return Objects.requireNonNull(GENERATED_OTF_MANIFESTS.get(otfBaseStreamingUrl)) + .getSecond(); } - final String originalOtfBaseStreamingUrl = otfBaseStreamingUrl; + String realOtfBaseStreamingUrl = otfBaseStreamingUrl; // Try to avoid redirects when streaming the content by saving the last URL we get // from video servers. - final Response response = getInitializationResponse(otfBaseStreamingUrl, + final Response response = getInitializationResponse(realOtfBaseStreamingUrl, itagItem, DeliveryType.OTF); - otfBaseStreamingUrl = response.latestUrl().replace(SQ_0, EMPTY_STRING) + realOtfBaseStreamingUrl = response.latestUrl().replace(SQ_0, EMPTY_STRING) .replace(RN_0, EMPTY_STRING).replace(ALR_YES, EMPTY_STRING); final int responseCode = response.responseCode(); if (responseCode != 200) { throw new YoutubeDashManifestCreationException( - "Unable to create the DASH manifest: could not get the initialization URL of the OTF stream: response code " - + responseCode); + "Unable to create the DASH manifest: could not get the initialization URL of " + + "the OTF stream: response code " + responseCode); } final String[] segmentDuration; @@ -266,7 +269,8 @@ public final class YoutubeDashManifestCreator { } } catch (final Exception e) { throw new YoutubeDashManifestCreationException( - "Unable to generate the DASH manifest: could not get the duration of segments", e); + "Unable to generate the DASH manifest: could not get the duration of segments", + e); } final Document document = generateDocumentAndMpdElement(segmentDuration, DeliveryType.OTF, @@ -278,7 +282,7 @@ public final class YoutubeDashManifestCreator { if (itagItem.itagType == ItagItem.ItagType.AUDIO) { generateAudioChannelConfigurationElement(document, itagItem); } - generateSegmentTemplateElement(document, otfBaseStreamingUrl, DeliveryType.OTF); + generateSegmentTemplateElement(document, realOtfBaseStreamingUrl, DeliveryType.OTF); generateSegmentTimelineElement(document); collectSegmentsData(segmentDuration); generateSegmentElementsForOtfStreams(document); @@ -286,7 +290,7 @@ public final class YoutubeDashManifestCreator { SEGMENTS_DURATION.clear(); DURATION_REPETITIONS.clear(); - return buildResult(originalOtfBaseStreamingUrl, document, GENERATED_OTF_MANIFESTS); + return buildResult(otfBaseStreamingUrl, document, GENERATED_OTF_MANIFESTS); } /** @@ -358,36 +362,37 @@ public final class YoutubeDashManifestCreator { */ @Nonnull public static String createDashManifestFromPostLiveStreamDvrStreamingUrl( - @Nonnull String postLiveStreamDvrStreamingUrl, + @Nonnull final String postLiveStreamDvrStreamingUrl, @Nonnull final ItagItem itagItem, final int targetDurationSec, - final long durationSecondsFallback) - throws YoutubeDashManifestCreationException { + final long durationSecondsFallback) throws YoutubeDashManifestCreationException { if (GENERATED_POST_LIVE_DVR_STREAMS_MANIFESTS.containsKey(postLiveStreamDvrStreamingUrl)) { - return GENERATED_POST_LIVE_DVR_STREAMS_MANIFESTS.get(postLiveStreamDvrStreamingUrl) - .getSecond(); + return Objects.requireNonNull(GENERATED_POST_LIVE_DVR_STREAMS_MANIFESTS.get( + postLiveStreamDvrStreamingUrl)).getSecond(); } - final String originalPostLiveStreamDvrStreamingUrl = postLiveStreamDvrStreamingUrl; + String realPostLiveStreamDvrStreamingUrl = postLiveStreamDvrStreamingUrl; final String streamDuration; final String segmentCount; if (targetDurationSec <= 0) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: the targetDurationSec value is less than or equal to 0 (" + targetDurationSec + ")"); + "Could not generate the DASH manifest: the targetDurationSec value is less " + + "than or equal to 0 (" + targetDurationSec + ")"); } try { // Try to avoid redirects when streaming the content by saving the latest URL we get // from video servers. - final Response response = getInitializationResponse(postLiveStreamDvrStreamingUrl, + final Response response = getInitializationResponse(realPostLiveStreamDvrStreamingUrl, itagItem, DeliveryType.LIVE); - postLiveStreamDvrStreamingUrl = response.latestUrl().replace(SQ_0, EMPTY_STRING) + realPostLiveStreamDvrStreamingUrl = response.latestUrl().replace(SQ_0, EMPTY_STRING) .replace(RN_0, EMPTY_STRING).replace(ALR_YES, EMPTY_STRING); final int responseCode = response.responseCode(); if (responseCode != 200) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not get the initialization URL of the post-live-DVR stream: response code " + "Could not generate the DASH manifest: could not get the initialization " + + "segment of the post-live-DVR stream: response code " + responseCode); } @@ -396,15 +401,18 @@ public final class YoutubeDashManifestCreator { segmentCount = responseHeaders.get("X-Head-Seqnum").get(0); } catch (final IndexOutOfBoundsException e) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not get the value of the X-Head-Time-Millis or the X-Head-Seqnum header of the post-live-DVR streaming URL", e); + "Could not generate the DASH manifest: could not get the value of the " + + "X-Head-Time-Millis or the X-Head-Seqnum header of the post-live-DVR" + + "streaming URL", e); } if (isNullOrEmpty(segmentCount)) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not get the number of segments of the post-live-DVR stream"); + "Could not generate the DASH manifest: could not get the number of segments of" + + "the post-live-DVR stream"); } - final Document document = generateDocumentAndMpdElement(new String[]{streamDuration}, + final Document document = generateDocumentAndMpdElement(new String[] {streamDuration}, DeliveryType.LIVE, itagItem, durationSecondsFallback); generatePeriodElement(document); generateAdaptationSetElement(document, itagItem); @@ -413,11 +421,12 @@ public final class YoutubeDashManifestCreator { if (itagItem.itagType == ItagItem.ItagType.AUDIO) { generateAudioChannelConfigurationElement(document, itagItem); } - generateSegmentTemplateElement(document, postLiveStreamDvrStreamingUrl, DeliveryType.LIVE); + generateSegmentTemplateElement(document, realPostLiveStreamDvrStreamingUrl, + DeliveryType.LIVE); generateSegmentTimelineElement(document); generateSegmentElementForPostLiveDvrStreams(document, targetDurationSec, segmentCount); - return buildResult(originalPostLiveStreamDvrStreamingUrl, document, + return buildResult(postLiveStreamDvrStreamingUrl, document, GENERATED_POST_LIVE_DVR_STREAMS_MANIFESTS); } @@ -486,13 +495,14 @@ public final class YoutubeDashManifestCreator { @Nonnull final ItagItem itagItem, final long durationSecondsFallback) throws YoutubeDashManifestCreationException { if (GENERATED_PROGRESSIVE_STREAMS_MANIFESTS.containsKey(progressiveStreamingBaseUrl)) { - return GENERATED_PROGRESSIVE_STREAMS_MANIFESTS.get(progressiveStreamingBaseUrl) - .getSecond(); + return Objects.requireNonNull(GENERATED_PROGRESSIVE_STREAMS_MANIFESTS.get( + progressiveStreamingBaseUrl)).getSecond(); } if (durationSecondsFallback <= 0) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: the durationSecondsFallback value is less than or equal to 0 (" + durationSecondsFallback + ")"); + "Could not generate the DASH manifest: the durationSecondsFallback value is" + + "less than or equal to 0 (" + durationSecondsFallback + ")"); } final Document document = generateDocumentAndMpdElement(new String[]{}, @@ -508,7 +518,8 @@ public final class YoutubeDashManifestCreator { generateSegmentBaseElement(document, itagItem); generateInitializationElement(document, itagItem); - return buildResult(progressiveStreamingBaseUrl, document, GENERATED_PROGRESSIVE_STREAMS_MANIFESTS); + return buildResult(progressiveStreamingBaseUrl, document, + GENERATED_PROGRESSIVE_STREAMS_MANIFESTS); } /** @@ -564,7 +575,8 @@ public final class YoutubeDashManifestCreator { return downloader.post(baseStreamingUrl, headers, emptyBody); } catch (final IOException | ExtractionException e) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: error when trying to get the ANDROID streaming post-live-DVR URL response", e); + "Could not generate the DASH manifest: error when trying to get the " + + "ANDROID streaming post-live-DVR URL response", e); } } @@ -579,10 +591,12 @@ public final class YoutubeDashManifestCreator { } catch (final IOException | ExtractionException e) { if (isAnAndroidStreamingUrl) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: error when trying to get the ANDROID streaming URL response", e); + "Could not generate the DASH manifest: error when trying to get the " + + "ANDROID streaming URL response", e); } else { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: error when trying to get the streaming URL response", e); + "Could not generate the DASH manifest: error when trying to get the " + + "streaming URL response", e); } } } @@ -658,16 +672,18 @@ public final class YoutubeDashManifestCreator { if (responseCode != 200) { if (deliveryType == DeliveryType.LIVE) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not get the initialization URL of the post-live-DVR stream: response code " - + responseCode); + "Could not generate the DASH manifest: could not get the " + + "initialization URL of the post-live-DVR stream: " + + "response code " + responseCode); } else if (deliveryType == DeliveryType.OTF) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not get the initialization URL of the OTF stream: response code " + "Could not generate the DASH manifest: could not get the " + + "initialization URL of the OTF stream: response code " + responseCode); } else { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not fetch the URL of the progressive stream: response code " - + responseCode); + "Could not generate the DASH manifest: could not fetch the URL of " + + "the progressive stream: response code " + responseCode); } } @@ -678,7 +694,8 @@ public final class YoutubeDashManifestCreator { "Content-Type")); } catch (final NullPointerException e) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: could not get the Content-Type header from the streaming URL", e); + "Could not generate the DASH manifest: could not get the Content-Type " + + "header from the streaming URL", e); } // The response body is the redirection URL @@ -692,16 +709,19 @@ public final class YoutubeDashManifestCreator { if (redirectsCount >= MAXIMUM_REDIRECT_COUNT) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: too many redirects when trying to get the WEB streaming URL response"); + "Could not generate the DASH manifest: too many redirects when trying to " + + "get the WEB streaming URL response"); } // This should never be reached, but is required because we don't want to return null // here throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: error when trying to get the WEB streaming URL response"); + "Could not generate the DASH manifest: error when trying to get the WEB " + + "streaming URL response"); } catch (final IOException | ExtractionException e) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: error when trying to get the WEB streaming URL response", e); + "Could not generate the DASH manifest: error when trying to get the WEB " + + "streaming URL response", e); } } @@ -731,7 +751,8 @@ public final class YoutubeDashManifestCreator { } } catch (final NumberFormatException e) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: unable to get the segments of the stream", e); + "Could not generate the DASH manifest: unable to get the segments of the " + + "stream", e); } } @@ -767,7 +788,8 @@ public final class YoutubeDashManifestCreator { return streamLengthMs; } catch (final NumberFormatException e) { throw new YoutubeDashManifestCreationException( - "Could not generate the DASH manifest: unable to get the length of the stream", e); + "Could not generate the DASH manifest: unable to get the length of the stream", + e); } } @@ -778,6 +800,7 @@ public final class YoutubeDashManifestCreator { * The generated {@code
* {@code
* If the duration is an integer or a double with less than 3 digits after the decimal point,
* it will be converted into a double with 3 digits after the decimal point.
@@ -859,8 +883,10 @@ public final class YoutubeDashManifestCreator {
streamDuration = durationSecondsFallback * 1000;
} else {
throw new YoutubeDashManifestCreationException(
- "Could not generate or append the MPD element of the DASH manifest to the document: "
- + "the duration of the stream could not be determined and the durationSecondsFallback is less than or equal to 0");
+ "Could not generate or append the MPD element of the DASH "
+ + "manifest to the document: the duration of the stream "
+ + "could not be determined and the "
+ + "durationSecondsFallback is less than or equal to 0");
}
}
}
@@ -870,7 +896,8 @@ public final class YoutubeDashManifestCreator {
mpdElement.setAttributeNode(mediaPresentationDurationAttribute);
} catch (final Exception e) {
throw new YoutubeDashManifestCreationException(
- "Could not generate or append the MPD element of the DASH manifest to the document", e);
+ "Could not generate or append the MPD element of the DASH manifest to the "
+ + "document", e);
}
return document;
@@ -898,7 +925,8 @@ public final class YoutubeDashManifestCreator {
mpdElement.appendChild(periodElement);
} catch (final DOMException e) {
throw new YoutubeDashManifestCreationException(
- "Could not generate or append the Period element of the DASH manifest to the document", e);
+ "Could not generate or append the Period element of the DASH manifest to the "
+ + "document", e);
}
}
@@ -921,7 +949,8 @@ public final class YoutubeDashManifestCreator {
@Nonnull final ItagItem itagItem)
throws YoutubeDashManifestCreationException {
try {
- final Element periodElement = (Element) document.getElementsByTagName("Period").item(0);
+ final Element periodElement = (Element) document.getElementsByTagName("Period")
+ .item(0);
final Element adaptationSetElement = document.createElement("AdaptationSet");
final Attr idAttribute = document.createAttribute("id");
@@ -931,21 +960,25 @@ public final class YoutubeDashManifestCreator {
final MediaFormat mediaFormat = itagItem.getMediaFormat();
if (mediaFormat == null || isNullOrEmpty(mediaFormat.mimeType)) {
throw new YoutubeDashManifestCreationException(
- "Could not generate the AdaptationSet element of the DASH manifest to the document: the MediaFormat or the mime type of the MediaFormat of the ItagItem is null or empty");
+ "Could not generate the AdaptationSet element of the DASH manifest to the "
+ + "document: the MediaFormat or the mime type of the MediaFormat "
+ + "of the ItagItem is null or empty");
}
final Attr mimeTypeAttribute = document.createAttribute("mimeType");
mimeTypeAttribute.setValue(mediaFormat.mimeType);
adaptationSetElement.setAttributeNode(mimeTypeAttribute);
- final Attr subsegmentAlignmentAttribute = document.createAttribute("subsegmentAlignment");
+ final Attr subsegmentAlignmentAttribute = document.createAttribute(
+ "subsegmentAlignment");
subsegmentAlignmentAttribute.setValue("true");
adaptationSetElement.setAttributeNode(subsegmentAlignmentAttribute);
periodElement.appendChild(adaptationSetElement);
} catch (final DOMException e) {
throw new YoutubeDashManifestCreationException(
- "Could not generate or append the AdaptationSet element of the DASH manifest to the document", e);
+ "Could not generate or append the AdaptationSet element of the DASH manifest "
+ + "to the document", e);
}
}
@@ -956,9 +989,11 @@ public final class YoutubeDashManifestCreator {
*
* This element, with its attributes and values, is:
*
* {@code
* The {@code
* This method is only used when generating DASH manifests of audio streams.
*
* It will produce the following element:
*
* The {@code
* This method is only used when generating DASH manifests from progressive streams.
*
* The {@code
* This method is only used when generating DASH manifests from progressive streams.
*
* It generates the following element:
*
* The {@code
* This method is only used when generating DASH manifests from progressive streams.
*
* It generates the following element:
*
* The {@code
* This method is only used when generating DASH manifests from OTF and post-live-DVR streams.
*
* It will produce a {@code
* {@code
* If there is no repetition of the duration between two segments, the {@code r} attribute is
* not added to the {@code S} element.
*
* These elements will be appended as children of the {@code
* The {@code
+ * It stores, per stream:
+ *
+ * The {@code StreamBuilderHelper} will set the following attributes in the
+ * {@link AudioStream}s built:
+ *
+ * Note that the {@link ItagItem} comes from an {@link ItagInfo} instance.
+ *
+ * The {@code StreamBuilderHelper} will set the following attributes in the
+ * {@link VideoStream}s built:
+ *
+ * Note that the {@link ItagItem} comes from an {@link ItagInfo} instance.
+ *
- * It must be not null and should be non empty.
+ * It must not be null and should be non empty.
*
@@ -79,7 +79,7 @@ public final class AudioStream extends Stream {
* Stream#ID_UNKNOWN ID_UNKNOWN} of the {@link Stream} class.
*
- * It must be non null and should be non empty.
+ * It must not be null, and should be non empty.
*
* It should be one of the audio {@link MediaFormat}s ({@link MediaFormat#M4A M4A},
* {@link MediaFormat#WEBMA WEBMA}, {@link MediaFormat#MP3 MP3}, {@link MediaFormat#OPUS
- * OPUS}, {@link MediaFormat#OGG OGG}, {@link MediaFormat#WEBMA_OPUS WEBMA_OPUS}) but can
- * be {@code null} if the media format could not be determined.
+ * OPUS}, {@link MediaFormat#OGG OGG}, or {@link MediaFormat#WEBMA_OPUS WEBMA_OPUS}) but
+ * can be {@code null} if the media format could not be determined.
*
@@ -131,7 +131,7 @@ public final class AudioStream extends Stream {
* Set the {@link DeliveryMethod} of the {@link AudioStream}.
*
*
- * It must be not null.
+ * It must not be null.
*
@@ -139,7 +139,7 @@ public final class AudioStream extends Stream {
*
- * Base URLs are for instance, for non-URLs content, the DASH or HLS manifest from which
- * they have been parsed.
+ * For non-URL contents, the base URL is, for instance, a link to the DASH or HLS manifest
+ * from which the URLs have been parsed.
*
@@ -213,7 +213,7 @@ public final class AudioStream extends Stream {
*
* @return a new {@link AudioStream} using the builder's current values
* @throws IllegalStateException if {@code id}, {@code content} (and so {@code isUrl}) or
- * {@code deliveryMethod} have been not set or set as {@code null}
+ * {@code deliveryMethod} have been not set, or have been set as {@code null}
*/
@Nonnull
public AudioStream build() {
@@ -244,8 +244,8 @@ public final class AudioStream extends Stream {
/**
* Create a new audio stream.
*
- * @param id the ID which uniquely identifies the stream, e.g. for YouTube this
- * would be the itag
+ * @param id the identifier which uniquely identifies the stream, e.g. for YouTube
+ * this would be the itag
* @param content the content or the URL of the stream, depending on whether isUrl is
* true
* @param isUrl whether content is the URL or the actual content of e.g. a DASH
@@ -258,6 +258,7 @@ public final class AudioStream extends Stream {
* @param baseUrl the base URL of the stream (see {@link Stream#getBaseUrl()} for more
* information)
*/
+ @SuppressWarnings("checkstyle:ParameterNumber")
private AudioStream(@Nonnull final String id,
@Nonnull final String content,
final boolean isUrl,
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/DeliveryMethod.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/DeliveryMethod.java
index db74e91ab..444023e58 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/DeliveryMethod.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/DeliveryMethod.java
@@ -13,25 +13,43 @@ public enum DeliveryMethod {
PROGRESSIVE_HTTP,
/**
- * Enum constant which represents the use of the DASH adaptive streaming method to fetch a
- * {@link Stream stream}.
+ * Enum constant which represents the use of the DASH (Dynamic Adaptive Streaming over HTTP)
+ * adaptive streaming method to fetch a {@link Stream stream}.
+ *
+ * @see the
+ * Dynamic Adaptive Streaming over HTTP Wikipedia page and
+ * DASH Industry Forum's website for more information about the DASH delivery method
*/
DASH,
/**
- * Enum constant which represents the use of the HLS adaptive streaming method to fetch a
- * {@link Stream stream}.
+ * Enum constant which represents the use of the HLS (HTTP Live Streaming) adaptive streaming
+ * method to fetch a {@link Stream stream}.
+ *
+ * @see the HTTP Live Streaming
+ * page and Apple's developers website page
+ * about HTTP Live Streaming for more information about the HLS delivery method
*/
HLS,
/**
* Enum constant which represents the use of the SmoothStreaming adaptive streaming method to
* fetch a {@link Stream stream}.
+ *
+ * @see Wikipedia's page about adaptive bitrate streaming,
+ * section Microsoft Smooth Streaming (MSS) for more information about the
+ * SmoothStreaming delivery method
*/
SS,
/**
- * Enum constant which represents the use of a torrent to fetch a {@link Stream stream}.
+ * Enum constant which represents the use of a torrent file to fetch a {@link Stream stream}.
+ *
+ * @see Wikipedia's BitTorrent's page,
+ * Wikipedia's page about torrent files
+ * and for more information about the
+ * BitTorrent protocol
*/
TORRENT
}
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/Stream.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/Stream.java
index b76594a6f..df47afdb5 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/Stream.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/Stream.java
@@ -19,11 +19,11 @@ public abstract class Stream implements Serializable {
public static final String ID_UNKNOWN = " ";
/**
- * An integer to represent that the itag id returned is not available (only for YouTube, this
+ * An integer to represent that the itag ID returned is not available (only for YouTube; this
* should never happen) or not applicable (for other services than YouTube).
*
*
- * An itag should not have a negative value so {@code -1} is used for this constant.
+ * An itag should not have a negative value, so {@code -1} is used for this constant.
*
* If the {@link MediaFormat media format} of the stream is unknown, the streams are compared
- * by only using the {@link DeliveryMethod delivery method} and their id.
+ * by using only the {@link DeliveryMethod delivery method} and their ID.
*
- * Note: This method always returns always false if the stream passed is null.
+ * Note: This method always returns false if the stream passed is null.
*
- * It should be normally unique but {@link #ID_UNKNOWN} may be returned as the identifier if
- * one used by the stream extractor cannot be extracted, if the extractor uses a value from a
- * streaming service.
+ * It should normally be unique, but {@link #ID_UNKNOWN} may be returned as the identifier if
+ * the one used by the stream extractor cannot be extracted, which could happen if the
+ * extractor uses a value from a streaming service.
*
* If the stream is not a DASH stream or an HLS stream, this value will always be null.
- * It may be also null for these streams too.
+ * It may also be null for these streams too.
*
- * If the stream is not a YouTube stream, this value will always be null.
+ * If the stream is not from YouTube, this value will always be null.
*
- * Note that contents can contain audio streams even if they also contain
+ * Note that contents may contain audio streams even if they also contain
* video streams (video-only or video with audio, depending of the stream/the content/the
* service).
*
* Note that contents can contain audio live streams even if they also contain
- * live video streams (video-only or video with audio, depending of the stream/the content/the
- * service).
+ * live video streams (so video-only or video with audio, depending on the stream/the content/
+ * the service).
*
* Note that contents returned as live audio streams should not return live video streams.
*
- * So, in order to prevent unexpected behaviors, stream extractors which are returning this
- * stream type for a content should ensure that no live video stream is returned for this
- * content.
+ * To prevent unexpected behavior, stream extractors which are returning this stream type for a
+ * content should ensure that no live video stream is returned along with it.
*
- * Note that most of ended live video (or audio) contents may be extracted as
- * {@link #VIDEO_STREAM regular video contents} (or
- * {@link #AUDIO_STREAM regular audio contents}) later, because the service may encode them
- * again later as normal video/audio streams. That's the case for example on YouTube.
+ * Note that most of the content of an ended live video (or audio) may be extracted as {@link
+ * #VIDEO_STREAM regular video contents} (or {@link #AUDIO_STREAM regular audio contents})
+ * later, because the service may encode them again later as normal video/audio streams. That's
+ * the case on YouTube, for example.
*
diff --git a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java
index 732d822d7..ddd372343 100644
--- a/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java
+++ b/extractor/src/main/java/org/schabi/newpipe/extractor/stream/SubtitlesStream.java
@@ -35,7 +35,7 @@ public final class SubtitlesStream extends Stream {
private Boolean autoGenerated;
/**
- * Create a new {@link Builder} instance with its default values.
+ * Create a new {@link Builder} instance with default values.
*/
public Builder() {
}
@@ -43,7 +43,7 @@ public final class SubtitlesStream extends Stream {
/**
* Set the identifier of the {@link SubtitlesStream}.
*
- * @param id the identifier of the {@link SubtitlesStream}, which should be not null
+ * @param id the identifier of the {@link SubtitlesStream}, which should not be null
* (otherwise the fallback to create the identifier will be used when building
* the builder)
* @return this {@link Builder} instance
@@ -57,10 +57,10 @@ public final class SubtitlesStream extends Stream {
* Set the content of the {@link SubtitlesStream}.
*
*
- * It must be non null and should be non empty.
+ * It must not be null, and should be non empty.
*
- * It must be not null.
+ * It must not be null.
*
@@ -107,7 +107,7 @@ public final class SubtitlesStream extends Stream {
*
- * Base URLs are for instance, for non-URLs content, the DASH or HLS manifest from which
- * they have been parsed.
+ * For non-URL contents, the base URL is, for instance, a link to the DASH or HLS manifest
+ * from which the URLs have been parsed.
*
@@ -139,7 +139,7 @@ public final class SubtitlesStream extends Stream {
* Set the language code of the {@link SubtitlesStream}.
*
*
- * It must be not null and should be not an empty string.
+ * It must not be null and should not be an empty string.
*
* If no identifier has been set, an identifier will be generated using the language code
- * and the media format suffix if the media format is known
+ * and the media format suffix, if the media format is known.
*
- * It must be not null and should be non empty.
+ * It must not be null, and should be non empty.
*
@@ -89,7 +89,7 @@ public final class VideoStream extends Stream {
* Stream#ID_UNKNOWN ID_UNKNOWN} of the {@link Stream} class.
*
- * It must be non null and should be non empty.
+ * It must not be null, and should be non empty.
*
* It should be one of the video {@link MediaFormat}s ({@link MediaFormat#MPEG_4 MPEG_4},
- * {@link MediaFormat#v3GPP v3GPP}, {@link MediaFormat#WEBM WEBM}) but can be {@code null}
- * if the media format could not be determined.
+ * {@link MediaFormat#v3GPP v3GPP}, or {@link MediaFormat#WEBM WEBM}) but can be {@code
+ * null} if the media format could not be determined.
*
@@ -140,7 +140,7 @@ public final class VideoStream extends Stream {
* Set the {@link DeliveryMethod} of the {@link VideoStream}.
*
*
- * It must be not null.
+ * It must not be null.
*
@@ -148,7 +148,7 @@ public final class VideoStream extends Stream {
*
- * Base URLs are for instance, for non-URLs content, the DASH or HLS manifest from which
- * they have been parsed.
+ * For non-URL contents, the base URL is, for instance, a link to the DASH or HLS manifest
+ * from which the URLs have been parsed.
*
@@ -245,8 +245,8 @@ public final class VideoStream extends Stream {
*
* @return a new {@link VideoStream} using the builder's current values
* @throws IllegalStateException if {@code id}, {@code content} (and so {@code isUrl}),
- * {@code deliveryMethod}, {@code isVideoOnly} or {@code resolution} have been not set or
- * set as {@code null}
+ * {@code deliveryMethod}, {@code isVideoOnly} or {@code resolution} have been not set, or
+ * have been set as {@code null}
*/
@Nonnull
public VideoStream build() {
@@ -289,8 +289,8 @@ public final class VideoStream extends Stream {
/**
* Create a new video stream.
*
- * @param id the ID which uniquely identifies the stream, e.g. for YouTube this
- * would be the itag
+ * @param id the identifier which uniquely identifies the stream, e.g. for YouTube
+ * this would be the itag
* @param content the content or the URL of the stream, depending on whether isUrl is
* true
* @param isUrl whether content is the URL or the actual content of e.g. a DASH
@@ -303,6 +303,7 @@ public final class VideoStream extends Stream {
* @param baseUrl the base URL of the stream (see {@link Stream#getBaseUrl()} for more
* information)
*/
+ @SuppressWarnings("checkstyle:ParameterNumber")
private VideoStream(@Nonnull final String id,
@Nonnull final String content,
final boolean isUrl,
diff --git a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreatorTest.java b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreatorTest.java
index a644272d1..0cd23fcaf 100644
--- a/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreatorTest.java
+++ b/extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreatorTest.java
@@ -53,7 +53,7 @@ class YoutubeDashManifestCreatorTest {
// Setting a higher number may let Google video servers return a lot of 403s
private static final int MAXIMUM_NUMBER_OF_STREAMS_TO_TEST = 3;
- public static class testGenerationOfOtfAndProgressiveManifests {
+ public static class TestGenerationOfOtfAndProgressiveManifests {
private static final String url = "https://www.youtube.com/watch?v=DJ8GQUNUXGM";
private static YoutubeStreamExtractor extractor;
@@ -1108,6 +1154,7 @@ public final class YoutubeDashManifestCreator {
* (where {@code audioChannelsValue} is get from the {@link ItagItem} passed as the second
* parameter of this method)
*
@@ -1201,6 +1253,7 @@ public final class YoutubeDashManifestCreator {
* (where {@code indexStart} and {@code indexEnd} are gotten from the {@link ItagItem} passed
* as the second parameter)
*
@@ -1260,6 +1317,7 @@ public final class YoutubeDashManifestCreator {
* (where {@code indexStart} and {@code indexEnd} are gotten from the {@link ItagItem} passed
* as the second parameter)
*
@@ -1372,7 +1434,8 @@ public final class YoutubeDashManifestCreator {
representationElement.appendChild(segmentTemplateElement);
} catch (final DOMException e) {
throw new YoutubeDashManifestCreationException(
- "Could not generate or append the SegmentTemplate element of the DASH manifest to the document", e);
+ "Could not generate or append the SegmentTemplate element of the DASH "
+ + "manifest to the document", e);
}
}
@@ -1401,7 +1464,8 @@ public final class YoutubeDashManifestCreator {
segmentTemplateElement.appendChild(segmentTimelineElement);
} catch (final DOMException e) {
throw new YoutubeDashManifestCreationException(
- "Could not generate or append the SegmentTimeline element of the DASH manifest to the document", e);
+ "Could not generate or append the SegmentTimeline element of the DASH "
+ + "manifest to the document", e);
}
}
@@ -1413,16 +1477,20 @@ public final class YoutubeDashManifestCreator {
* so we just have to loop into {@link #SEGMENTS_DURATION} and {@link #DURATION_REPETITIONS}
* to generate the following element for each duration:
*
}
*
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *