[YouTube] Update DASH manifest creation clients' handling

- Use POST requests with the same body as official clients do;
- Update methods checking the client streaming URLs come from:
  - Replace TVHTML5_SIMPLY_EMBEDDED_PLAYER by TVHTML5;
  - Add WEB_EMBEDDED_PLAYER.
This commit is contained in:
AudricV 2025-01-30 20:17:31 +01:00 committed by Stypox
parent 38e2b67cb7
commit 9333d7fcdc
No known key found for this signature in database
GPG Key ID: 4BDF1B40A49FDD23
2 changed files with 28 additions and 14 deletions

View File

@ -180,8 +180,10 @@ public final class YoutubeParsingHelper {
"https://www.youtube.com/feeds/videos.xml?channel_id="; "https://www.youtube.com/feeds/videos.xml?channel_id=";
private static final String FEED_BASE_USER = "https://www.youtube.com/feeds/videos.xml?user="; private static final String FEED_BASE_USER = "https://www.youtube.com/feeds/videos.xml?user=";
private static final Pattern C_WEB_PATTERN = Pattern.compile("&c=WEB"); private static final Pattern C_WEB_PATTERN = Pattern.compile("&c=WEB");
private static final Pattern C_TVHTML5_SIMPLY_EMBEDDED_PLAYER_PATTERN = private static final Pattern C_WEB_EMBEDDED_PLAYER_PATTERN =
Pattern.compile("&c=TVHTML5_SIMPLY_EMBEDDED_PLAYER"); Pattern.compile("&c=WEB_EMBEDDED_PLAYER");
private static final Pattern C_TVHTML5_PLAYER_PATTERN =
Pattern.compile("&c=TVHTML5");
private static final Pattern C_ANDROID_PATTERN = Pattern.compile("&c=ANDROID"); private static final Pattern C_ANDROID_PATTERN = Pattern.compile("&c=ANDROID");
private static final Pattern C_IOS_PATTERN = Pattern.compile("&c=IOS"); private static final Pattern C_IOS_PATTERN = Pattern.compile("&c=IOS");
@ -1394,15 +1396,24 @@ public final class YoutubeParsingHelper {
} }
/** /**
* Check if the streaming URL is a URL from the YouTube {@code TVHTML5_SIMPLY_EMBEDDED_PLAYER} * Check if the streaming URL is from the YouTube {@code WEB_EMBEDDED_PLAYER} client.
* client.
* *
* @param url the streaming URL on which check if it's a {@code TVHTML5_SIMPLY_EMBEDDED_PLAYER} * @param url the streaming URL to be checked.
* streaming URL. * @return true if it's a {@code WEB_EMBEDDED_PLAYER} streaming URL, false otherwise
* @return true if it's a {@code TVHTML5_SIMPLY_EMBEDDED_PLAYER} streaming URL, false otherwise
*/ */
public static boolean isTvHtml5SimplyEmbeddedPlayerStreamingUrl(@Nonnull final String url) { public static boolean isWebEmbeddedPlayerStreamingUrl(@Nonnull final String url) {
return Parser.isMatch(C_TVHTML5_SIMPLY_EMBEDDED_PLAYER_PATTERN, url); return Parser.isMatch(C_WEB_EMBEDDED_PLAYER_PATTERN, url);
}
/**
* Check if the streaming URL is a URL from the YouTube {@code TVHTML5} client.
*
* @param url the streaming URL on which check if it's a {@code TVHTML5}
* streaming URL.
* @return true if it's a {@code TVHTML5} streaming URL, false otherwise
*/
public static boolean isTvHtml5StreamingUrl(@Nonnull final String url) {
return Parser.isMatch(C_TVHTML5_PLAYER_PATTERN, url);
} }
/** /**

View File

@ -5,8 +5,9 @@ import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getIosUserAgent; 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.isAndroidStreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isIosStreamingUrl; 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.isTvHtml5StreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl; import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebStreamingUrl;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.isWebEmbeddedPlayerStreamingUrl;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty; import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
import org.schabi.newpipe.extractor.MediaFormat; import org.schabi.newpipe.extractor.MediaFormat;
@ -582,8 +583,8 @@ public final class YoutubeDashManifestCreatorsUtils {
* This method fetches, for OTF streams and for post-live-DVR streams: * This method fetches, for OTF streams and for post-live-DVR streams:
* <ul> * <ul>
* <li>the base URL of the stream, to which are appended {@link #SQ_0} and * <li>the base URL of the stream, to which are appended {@link #SQ_0} and
* {@link #RN_0} parameters, with a {@code GET} request for streaming URLs from HTML5 * {@link #RN_0} parameters, with a {@code POS} request for streaming URLs from
* clients and a {@code POST} request for the ones from the {@code ANDROID} and the * {@code WEB}, {@code TVHTML5}, {@code WEB_EMBEDDED_PLAYER}, {@code ANDROID} and
* {@code IOS} clients;</li> * {@code IOS} clients;</li>
* <li>for streaming URLs from HTML5 clients, the {@link #ALR_YES} param is also added. * <li>for streaming URLs from HTML5 clients, the {@link #ALR_YES} param is also added.
* </li> * </li>
@ -602,7 +603,8 @@ public final class YoutubeDashManifestCreatorsUtils {
final DeliveryType deliveryType) final DeliveryType deliveryType)
throws CreationException { throws CreationException {
final boolean isHtml5StreamingUrl = isWebStreamingUrl(baseStreamingUrl) final boolean isHtml5StreamingUrl = isWebStreamingUrl(baseStreamingUrl)
|| isTvHtml5SimplyEmbeddedPlayerStreamingUrl(baseStreamingUrl); || isTvHtml5StreamingUrl(baseStreamingUrl)
|| isWebEmbeddedPlayerStreamingUrl(baseStreamingUrl);
final boolean isAndroidStreamingUrl = isAndroidStreamingUrl(baseStreamingUrl); final boolean isAndroidStreamingUrl = isAndroidStreamingUrl(baseStreamingUrl);
final boolean isIosStreamingUrl = isIosStreamingUrl(baseStreamingUrl); final boolean isIosStreamingUrl = isIosStreamingUrl(baseStreamingUrl);
if (isHtml5StreamingUrl) { if (isHtml5StreamingUrl) {
@ -748,7 +750,8 @@ public final class YoutubeDashManifestCreatorsUtils {
int redirectsCount = 0; int redirectsCount = 0;
while (!responseMimeType.equals(responseMimeTypeExpected) while (!responseMimeType.equals(responseMimeTypeExpected)
&& redirectsCount < MAXIMUM_REDIRECT_COUNT) { && redirectsCount < MAXIMUM_REDIRECT_COUNT) {
final Response response = downloader.get(streamingUrl, headers); final byte[] html5Body = new byte[] {0x78, 0};
final Response response = downloader.post(streamingUrl, headers, html5Body);
final int responseCode = response.responseCode(); final int responseCode = response.responseCode();
if (responseCode != 200) { if (responseCode != 200) {