[YouTube] Support the iOS client in YoutubeDashManifestCreator and decrypt again the n parameter, if present, for all clients

This commits reverts a new behavior introduced in this branch, which only applied the decryption if needed on streams from the WEB client.
Also fix rebase issues and documentations style in YoutubeDashManifestCreator.
This commit is contained in:
TiA4f8R 2022-04-11 19:35:57 +02:00
parent 436ddde29f
commit 07b045f20d
No known key found for this signature in database
GPG key ID: E6D3E7F5949450DD
2 changed files with 25 additions and 33 deletions

View file

@ -33,8 +33,11 @@ import java.util.Map;
import java.util.Objects;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.addClientInfoHeaders;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getYoutubeAndroidAppUserAgent;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getAndroidUserAgent;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getIosUserAgent;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isAndroidStreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isIosStreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isTvHtml5SimplyEmbeddedPlayerStreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
import static org.schabi.newpipe.extractor.utils.Utils.EMPTY_STRING;
import static org.schabi.newpipe.extractor.utils.Utils.isBlank;
@ -562,54 +565,44 @@ public final class YoutubeDashManifestCreator {
@Nonnull final ItagItem itagItem,
final DeliveryType deliveryType)
throws YoutubeDashManifestCreationException {
final boolean isAWebStreamingUrl = isWebStreamingUrl(baseStreamingUrl);
final boolean isAHtml5StreamingUrl = isWebStreamingUrl(baseStreamingUrl)
|| isTvHtml5SimplyEmbeddedPlayerStreamingUrl(baseStreamingUrl);
final boolean isAnAndroidStreamingUrl = isAndroidStreamingUrl(baseStreamingUrl);
final boolean isAnAndroidStreamingUrlAndAPostLiveDvrStream = isAnAndroidStreamingUrl
&& deliveryType == DeliveryType.LIVE;
if (isAWebStreamingUrl) {
final boolean isAnIosStreamingUrl = isIosStreamingUrl(baseStreamingUrl);
if (isAHtml5StreamingUrl) {
baseStreamingUrl += ALR_YES;
}
baseStreamingUrl = appendRnParamAndSqParamIfNeeded(baseStreamingUrl, deliveryType);
final Downloader downloader = NewPipe.getDownloader();
if (isAWebStreamingUrl) {
if (isAHtml5StreamingUrl) {
final String mimeTypeExpected = itagItem.getMediaFormat().getMimeType();
if (!isNullOrEmpty(mimeTypeExpected)) {
return getStreamingWebUrlWithoutRedirects(downloader, baseStreamingUrl,
mimeTypeExpected, deliveryType);
}
} else if (isAnAndroidStreamingUrlAndAPostLiveDvrStream) {
} else if (isAnAndroidStreamingUrl || isAnIosStreamingUrl) {
try {
final Map<String, List<String>> headers = new HashMap<>();
headers.put("User-Agent", Collections.singletonList(
getYoutubeAndroidAppUserAgent(null)));
isAnAndroidStreamingUrl ? getAndroidUserAgent(null)
: getIosUserAgent(null)));
final byte[] emptyBody = "".getBytes(StandardCharsets.UTF_8);
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);
+ (isAnIosStreamingUrl ? "ANDROID" : "IOS")
+ " streaming URL response", e);
}
}
try {
final Map<String, List<String>> headers = new HashMap<>();
if (isAnAndroidStreamingUrl) {
headers.put("User-Agent", Collections.singletonList(
getYoutubeAndroidAppUserAgent(null)));
}
return downloader.get(baseStreamingUrl, headers);
return downloader.get(baseStreamingUrl);
} 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);
} 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);
}
}
@ -834,8 +827,10 @@ public final class YoutubeDashManifestCreator {
* sequence of the stream
* @param deliveryType the {@link DeliveryType} of the stream, see the enum for
* possible values
* @param itagItem the {@link ItagItem} which will be used to get the duration
* of progressive streams
* @param durationSecondsFallback the duration in seconds, extracted from player response, used
* as a fallback
* as a fallback if the duration could not be determined
* @return a {@link Document} object which contains a {@code <MPD>} element
* @throws YoutubeDashManifestCreationException if something goes wrong when generating/
* appending the {@link Document object} or the
@ -1698,7 +1693,7 @@ public final class YoutubeDashManifestCreator {
}
/**
* Set the clear factor of cached OTF streams
* Set the clear factor of cached OTF streams.
*
* @param otfStreamsClearFactor the clear factor of OTF streams manifests cache.
*/
@ -1707,7 +1702,7 @@ public final class YoutubeDashManifestCreator {
}
/**
* Set the clear factor of cached post-live-DVR streams
* Set the clear factor of cached post-live-DVR streams.
*
* @param postLiveDvrStreamsClearFactor the clear factor of post-live-DVR streams manifests
* cache.
@ -1718,7 +1713,7 @@ public final class YoutubeDashManifestCreator {
}
/**
* Set the clear factor of cached progressive streams
* Set the clear factor of cached progressive streams.
*
* @param progressiveStreamsClearFactor the clear factor of progressive streams manifests
* cache.

View file

@ -29,12 +29,10 @@ import static org.schabi.newpipe.extractor.services.youtube.ItagItem.CONTENT_LEN
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.fixThumbnailUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.generateContentPlaybackNonce;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.generateTParameter;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getClientVersion;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonAndroidPostResponse;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonIosPostResponse;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getJsonPostResponse;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getTextFromObject;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareAndroidMobileJsonBuilder;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareDesktopJsonBuilder;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareIosMobileJsonBuilder;
@ -1366,9 +1364,8 @@ public class YoutubeStreamExtractor extends StreamExtractor {
// Add the content playback nonce to the stream URL
streamUrl += "&" + CPN + "=" + contentPlaybackNonce;
if (isWebStreamingUrl(streamUrl)) {
streamUrl = tryDecryptUrl(streamUrl, videoId) + "&cver=" + getClientVersion();
}
// Decrypt the n parameter if it is present
streamUrl = tryDecryptUrl(streamUrl, videoId);
final JsonObject initRange = formatData.getObject("initRange");
final JsonObject indexRange = formatData.getObject("indexRange");