Skip to content

Commit 2fb1a41

Browse files
committed
Fix Checkstyle issues, revert resolution string changes for YouTube video streams and don't return the rn parameter in DASH manifests
This parameter is still used to get the initialization sequence of OTF and POST-live streams, but is not returned anymore in the manifests. It has been removed in order to avoid fingerprinting based on the number sent (e.g. when starting to play a stream close to the end and using 123 as the request number where it should be 1) and should be added dynamically by clients in their requests. The relevant test has been also updated. Checkstyle issues in YoutubeDashManifestCreator have been fixed, and the changes in the resolution string returned for video streams in YoutubeStreamExtractor have been reverted, as they create issues on NewPipe right now.
1 parent f61e209 commit 2fb1a41

4 files changed

Lines changed: 50 additions & 43 deletions

File tree

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreator.java

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,22 @@
2323
import java.io.IOException;
2424
import java.io.StringWriter;
2525
import java.nio.charset.StandardCharsets;
26-
import java.util.*;
27-
28-
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.*;
29-
import static org.schabi.newpipe.extractor.utils.Utils.*;
26+
import java.util.ArrayList;
27+
import java.util.Arrays;
28+
import java.util.Collections;
29+
import java.util.HashMap;
30+
import java.util.List;
31+
import java.util.Locale;
32+
import java.util.Map;
33+
import java.util.Objects;
34+
35+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.addClientInfoHeaders;
36+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getYoutubeAndroidAppUserAgent;
37+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isAndroidStreamingUrl;
38+
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
39+
import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING;
40+
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
41+
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
3042

3143
/**
3244
* Class to generate DASH manifests from YouTube OTF, progressive and ended/post-live-DVR streams.
@@ -202,11 +214,11 @@ public static final class YoutubeDashManifestCreationException extends Exception
202214
* <p>In order to generate the DASH manifest, this method will:
203215
* <ul>
204216
* <li>request the first sequence of the stream (the base URL on which the first
205-
* sequence parameters are appended (see {@link #RN_0} and {@link #SQ_0})) with a POST
206-
* or GET request (depending of the client on which the streaming URL comes from);
217+
* sequence parameter is appended (see {@link #SQ_0})) with a POST or GET request
218+
* (depending of the client on which the streaming URL comes from);
207219
* </li>
208220
* <li>follow its redirection(s), if any;</li>
209-
* <li>save the last URL, remove the first sequence parameters;</li>
221+
* <li>save the last URL, remove the first sequence parameter;</li>
210222
* <li>use the information provided in the {@link ItagItem} to generate all
211223
* elements of the DASH manifest.</li>
212224
* </ul>
@@ -331,8 +343,8 @@ public static String createDashManifestFromOtfStreamingUrl(
331343
* <p>In order to generate the DASH manifest, this method will:
332344
* <ul>
333345
* <li>request the first sequence of the stream (the base URL on which the first
334-
* sequence parameters are appended (see {@link #RN_0} and {@link #SQ_0})) with a POST
335-
* or GET request (depending of the client on which the streaming URL comes from);
346+
* sequence parameter is appended (see {@link #SQ_0})) with a POST or GET request
347+
* (depending of the client on which the streaming URL comes from);
336348
* </li>
337349
* <li>follow its redirection(s), if any;</li>
338350
* <li>save the last URL, remove the first sequence parameters;</li>
@@ -491,7 +503,7 @@ public static String createDashManifestFromPostLiveStreamDvrStreamingUrl(
491503
*/
492504
@Nonnull
493505
public static String createDashManifestFromProgressiveStreamingUrl(
494-
@Nonnull String progressiveStreamingBaseUrl,
506+
@Nonnull final String progressiveStreamingBaseUrl,
495507
@Nonnull final ItagItem itagItem,
496508
final long durationSecondsFallback) throws YoutubeDashManifestCreationException {
497509
if (GENERATED_PROGRESSIVE_STREAMS_MANIFESTS.containsKey(progressiveStreamingBaseUrl)) {
@@ -526,12 +538,11 @@ public static String createDashManifestFromProgressiveStreamingUrl(
526538
* Get the "initialization" {@link Response response} of a stream.
527539
*
528540
* <p>
529-
* This method fetches:
541+
* This method fetches, for OTF streams and for post-live-DVR streams:
530542
* <ul>
531-
* <li>for progressive streams, the base URL of the stream with a HEAD request;</li>
532-
* <li>for OTF streams and for post-live-DVR streams, the base URL of the stream, to which
533-
* are appended {@link #SQ_0} and {@link #RN_0} params, with a GET request for streaming
534-
* URLs from the WEB client and a POST request for the ones from the Android client;</li>
543+
* <li>the base URL of the stream, to which are appended {@link #SQ_0} and {@link #RN_0}
544+
* parameters, with a GET request for streaming URLs from the WEB client and a POST request
545+
* for the ones from the Android client;</li>
535546
* <li>for streaming URLs from the WEB client, the {@link #ALR_YES} param is also added.
536547
* </li>
537548
* </ul>
@@ -545,6 +556,7 @@ public static String createDashManifestFromProgressiveStreamingUrl(
545556
* @throws YoutubeDashManifestCreationException if something goes wrong when fetching the
546557
* "initialization" response and/or its redirects
547558
*/
559+
@SuppressWarnings("checkstyle:FinalParameters")
548560
@Nonnull
549561
private static Response getInitializationResponse(@Nonnull String baseStreamingUrl,
550562
@Nonnull final ItagItem itagItem,
@@ -604,11 +616,12 @@ private static Response getInitializationResponse(@Nonnull String baseStreamingU
604616
/**
605617
* Append {@link #SQ_0} for post-live-DVR and OTF streams and {@link #RN_0} to all streams.
606618
*
607-
* @param baseStreamingUrl the base streaming URL to which the param(s) are being appended
619+
* @param baseStreamingUrl the base streaming URL to which the parameter(s) are being appended
608620
* @param deliveryType the {@link DeliveryType} of the stream
609621
* @return the base streaming URL to which the param(s) are appended, depending on the
610622
* {@link DeliveryType} of the stream
611623
*/
624+
@SuppressWarnings({"checkstyle:FinalParameters", "checkstyle:FinalLocalVariable"})
612625
@Nonnull
613626
private static String appendRnParamAndSqParamIfNeeded(
614627
@Nonnull String baseStreamingUrl,
@@ -644,6 +657,7 @@ private static String appendRnParamAndSqParamIfNeeded(
644657
* @throws YoutubeDashManifestCreationException if something goes wrong when trying to get the
645658
* response without any redirection
646659
*/
660+
@SuppressWarnings("checkstyle:FinalParameters")
647661
@Nonnull
648662
private static Response getStreamingWebUrlWithoutRedirects(
649663
@Nonnull final Downloader downloader,
@@ -1312,7 +1326,7 @@ private static void generateSegmentBaseElement(@Nonnull final Document document,
13121326
* <p>
13131327
* It generates the following element:
13141328
* <br>
1315-
* {@code <Initialization range="initStart-initEnd"></SegmentBase>}
1329+
* {@code <Initialization range="initStart-initEnd"/>}
13161330
* <br>
13171331
* (where {@code indexStart} and {@code indexEnd} are gotten from the {@link ItagItem} passed
13181332
* as the second parameter)
@@ -1380,9 +1394,9 @@ private static void generateInitializationElement(@Nonnull final Document docume
13801394
* {@code 1} for OTF streams;</li>
13811395
* <li>{@code timescale}, which is always {@code 1000};</li>
13821396
* <li>{@code media}, which is the base URL of the stream on which is appended
1383-
* {@code &sq=$Number$&rn=$Number$};</li>
1397+
* {@code &sq=$Number$};</li>
13841398
* <li>{@code initialization} (only for OTF streams), which is the base URL of the stream
1385-
* on which is appended {@link #SQ_0} and {@link #RN_0}.</li>
1399+
* on which is appended {@link #SQ_0}.</li>
13861400
* </ul>
13871401
* </p>
13881402
*
@@ -1423,12 +1437,12 @@ private static void generateSegmentTemplateElement(@Nonnull final Document docum
14231437
// Post-live-DVR/ended livestreams streams don't require an initialization sequence
14241438
if (!isDeliveryTypeLive) {
14251439
final Attr initializationAttribute = document.createAttribute("initialization");
1426-
initializationAttribute.setValue(baseUrl + SQ_0 + RN_0);
1440+
initializationAttribute.setValue(baseUrl + SQ_0);
14271441
segmentTemplateElement.setAttributeNode(initializationAttribute);
14281442
}
14291443

14301444
final Attr mediaAttribute = document.createAttribute("media");
1431-
mediaAttribute.setValue(baseUrl + "&sq=$Number$&rn=$Number$");
1445+
mediaAttribute.setValue(baseUrl + "&sq=$Number$");
14321446
segmentTemplateElement.setAttributeNode(mediaAttribute);
14331447

14341448
representationElement.appendChild(segmentTemplateElement);

extractor/src/main/java/org/schabi/newpipe/extractor/services/youtube/extractors/YoutubeStreamExtractor.java

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,21 +1292,9 @@ public VideoStream buildStream(@Nonnull final ItagInfo itagInfo) {
12921292
.setIsVideoOnly(areStreamsVideoOnly)
12931293
.setItagItem(itagItem);
12941294

1295-
final int height = itagItem.getHeight();
1296-
if (height > 0) {
1297-
final StringBuilder stringBuilder = new StringBuilder();
1298-
stringBuilder.append(height);
1299-
stringBuilder.append("p");
1300-
final int fps = itagItem.getFps();
1301-
if (fps > 30) {
1302-
stringBuilder.append(fps);
1303-
}
1304-
builder.setResolution(stringBuilder.toString());
1305-
} else {
1306-
final String resolutionString = itagItem.getResolutionString();
1307-
builder.setResolution(resolutionString != null ? resolutionString
1308-
: EMPTY_STRING);
1309-
}
1295+
final String resolutionString = itagItem.getResolutionString();
1296+
builder.setResolution(resolutionString != null ? resolutionString
1297+
: EMPTY_STRING);
13101298

13111299
if (streamType != StreamType.VIDEO_STREAM || !itagInfo.getIsUrl()) {
13121300
// For YouTube videos on OTF streams and for all streams of post-live streams

extractor/src/main/java/org/schabi/newpipe/extractor/stream/DeliveryMethod.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ public enum DeliveryMethod {
4848
*
4949
* @see <a href="https://en.wikipedia.org/wiki/BitTorrent">Wikipedia's BitTorrent's page</a>,
5050
* <a href="https://en.wikipedia.org/wiki/Torrent_file">Wikipedia's page about torrent files
51-
* </a> and <a href=""https://www.bittorrent.org/></a> for more information about the
52-
* BitTorrent protocol
51+
* </a> and <a href="https://www.bittorrent.org">Bitorrent's website</a> for more information
52+
* about the BitTorrent protocol
5353
*/
5454
TORRENT
5555
}

extractor/src/test/java/org/schabi/newpipe/extractor/services/youtube/YoutubeDashManifestCreatorTest.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,12 @@
2121
import java.util.List;
2222
import java.util.Random;
2323

24-
import static org.junit.jupiter.api.Assertions.*;
24+
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
import static org.junit.jupiter.api.Assertions.assertFalse;
26+
import static org.junit.jupiter.api.Assertions.assertNotEquals;
27+
import static org.junit.jupiter.api.Assertions.assertNotNull;
28+
import static org.junit.jupiter.api.Assertions.assertNull;
29+
import static org.junit.jupiter.api.Assertions.assertTrue;
2530
import static org.schabi.newpipe.extractor.ServiceList.YouTube;
2631
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
2732

@@ -428,8 +433,8 @@ private void testSegmentTemplateElement(@Nonnull final Document document) {
428433
throw new AssertionError("The value of the initialization attribute is not an URL",
429434
e);
430435
}
431-
assertTrue(initializationValue.endsWith("&sq=0&rn=0"),
432-
"The value of the initialization attribute doesn't end with &sq=0&rn=0");
436+
assertTrue(initializationValue.endsWith("&sq=0"),
437+
"The value of the initialization attribute doesn't end with &sq=0");
433438

434439
final String mediaValue = segmentTemplateElement.getAttribute("media");
435440
assertFalse(isBlank(mediaValue),
@@ -440,8 +445,8 @@ private void testSegmentTemplateElement(@Nonnull final Document document) {
440445
throw new AssertionError("The value of the media attribute is not an URL",
441446
e);
442447
}
443-
assertTrue(mediaValue.endsWith("&sq=$Number$&rn=$Number$"),
444-
"The value of the media attribute doesn't end with &sq=$Number$&rn=$Number$");
448+
assertTrue(mediaValue.endsWith("&sq=$Number$"),
449+
"The value of the media attribute doesn't end with &sq=$Number$");
445450

446451
final String startNumberValue = segmentTemplateElement.getAttribute("startNumber");
447452
assertFalse(isBlank(startNumberValue),

0 commit comments

Comments
 (0)