kopia lustrzana https://github.com/TeamNewPipe/NewPipeExtractor
Merge 9730de277b
into fafd471606
commit
aa0fa00bad
|
@ -476,6 +476,7 @@ public class PeertubeStreamExtractor extends StreamExtractor {
|
|||
.setMediaFormat(fmt)
|
||||
.setLanguageCode(languageCode)
|
||||
.setAutoGenerated(false)
|
||||
.setAutoTranslated(false)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -665,40 +665,77 @@ public class YoutubeStreamExtractor extends StreamExtractor {
|
|||
|
||||
@Override
|
||||
@Nonnull
|
||||
public List<SubtitlesStream> getSubtitles(final MediaFormat format) throws ParsingException {
|
||||
public List<SubtitlesStream> getSubtitles(@Nonnull final MediaFormat format)
|
||||
throws ParsingException {
|
||||
assertPageFetched();
|
||||
|
||||
// We cannot store the subtitles list because the media format may change
|
||||
final List<SubtitlesStream> subtitlesToReturn = new ArrayList<>();
|
||||
final List<SubtitlesStream> subtitles = new ArrayList<>();
|
||||
final List<SubtitlesStream> autoTranslatedSubtitles = new ArrayList<>();
|
||||
final JsonObject renderer = playerResponse.getObject("captions")
|
||||
.getObject("playerCaptionsTracklistRenderer");
|
||||
final JsonArray captionsArray = renderer.getArray("captionTracks");
|
||||
// TODO: use this to apply auto translation to different language from a source language
|
||||
// final JsonArray autoCaptionsArray = renderer.getArray("translationLanguages");
|
||||
|
||||
for (int i = 0; i < captionsArray.size(); i++) {
|
||||
final String languageCode = captionsArray.getObject(i).getString("languageCode");
|
||||
final String baseUrl = captionsArray.getObject(i).getString("baseUrl");
|
||||
final String vssId = captionsArray.getObject(i).getString("vssId");
|
||||
|
||||
if (languageCode != null && baseUrl != null && vssId != null) {
|
||||
final boolean isAutoGenerated = vssId.startsWith("a.");
|
||||
final String cleanUrl = baseUrl
|
||||
// Remove preexisting format if exists
|
||||
.replaceAll("&fmt=[^&]*", "")
|
||||
// Remove translation language
|
||||
.replaceAll("&tlang=[^&]*", "");
|
||||
|
||||
subtitlesToReturn.add(new SubtitlesStream.Builder()
|
||||
.setContent(cleanUrl + "&fmt=" + format.getSuffix(), true)
|
||||
.setMediaFormat(format)
|
||||
.setLanguageCode(languageCode)
|
||||
.setAutoGenerated(isAutoGenerated)
|
||||
.build());
|
||||
}
|
||||
// Generate list of languages available for auto-translations
|
||||
final List<String> translationLanguages;
|
||||
if (renderer.has("translationLanguages")) {
|
||||
translationLanguages = renderer.getArray("translationLanguages")
|
||||
.stream()
|
||||
.map(JsonObject.class::cast)
|
||||
.map(lang -> lang.getString("languageCode"))
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
translationLanguages = Collections.emptyList();
|
||||
}
|
||||
|
||||
return subtitlesToReturn;
|
||||
// Add subtitles
|
||||
for (int i = 0; i < captionsArray.size(); i++) {
|
||||
final JsonObject caption = captionsArray.getObject(i);
|
||||
final String languageCode = caption.getString("languageCode");
|
||||
final String baseUrl = caption.getString("baseUrl");
|
||||
final String vssId = caption.getString("vssId");
|
||||
|
||||
if (languageCode == null || baseUrl == null || vssId == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final boolean isAutoGenerated = vssId.startsWith("a.");
|
||||
final String cleanUrl = baseUrl
|
||||
// Remove preexisting format if exists
|
||||
.replaceAll("&fmt=[^&]*", "")
|
||||
// Remove translation language
|
||||
.replaceAll("&tlang=[^&]*", "");
|
||||
|
||||
// add base subtitles
|
||||
subtitles.add(new SubtitlesStream.Builder()
|
||||
.setContent(cleanUrl + "&fmt=" + format.getSuffix(), true)
|
||||
.setMediaFormat(format)
|
||||
.setLanguageCode(languageCode)
|
||||
.setAutoGenerated(isAutoGenerated)
|
||||
.setAutoTranslated(false)
|
||||
.build());
|
||||
|
||||
// add auto-translations of this subtitle if available
|
||||
if (caption.getBoolean("isTranslatable")) {
|
||||
for (final String tLanguageCode : translationLanguages) {
|
||||
autoTranslatedSubtitles.add(new SubtitlesStream.Builder()
|
||||
.setContent(cleanUrl + "&fmt=" + format.getSuffix()
|
||||
+ "&tlang=" + tLanguageCode, true)
|
||||
.setMediaFormat(format)
|
||||
.setLanguageCode(tLanguageCode)
|
||||
.setAutoGenerated(true)
|
||||
.setAutoTranslated(true)
|
||||
.setBaseLanguageCode(languageCode)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// add auto-translations at the end for better sorting
|
||||
subtitles.addAll(autoTranslatedSubtitles);
|
||||
|
||||
return subtitles;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,8 +12,11 @@ import javax.annotation.Nullable;
|
|||
|
||||
public final class SubtitlesStream extends Stream {
|
||||
private final MediaFormat format;
|
||||
@Nullable
|
||||
private final Locale baseLocale;
|
||||
private final Locale locale;
|
||||
private final boolean autoGenerated;
|
||||
private final boolean autoTranslated;
|
||||
private final String code;
|
||||
|
||||
/**
|
||||
|
@ -30,8 +33,11 @@ public final class SubtitlesStream extends Stream {
|
|||
@Nullable
|
||||
private String manifestUrl;
|
||||
private String languageCode;
|
||||
@Nullable
|
||||
private String baseLanguageCode;
|
||||
// Use of the Boolean class instead of the primitive type needed for setter call check
|
||||
private Boolean autoGenerated;
|
||||
private Boolean autoTranslated;
|
||||
|
||||
/**
|
||||
* Create a new {@link Builder} instance with default values.
|
||||
|
@ -140,6 +146,18 @@ public final class SubtitlesStream extends Stream {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the language code of the base language used to auto-translate
|
||||
* the {@link SubtitlesStream} to the current language code.
|
||||
*
|
||||
* @param baseLanguageCode the language code of the {@link SubtitlesStream}
|
||||
* @return this {@link Builder} instance
|
||||
*/
|
||||
public Builder setBaseLanguageCode(@Nullable final String baseLanguageCode) {
|
||||
this.baseLanguageCode = baseLanguageCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the subtitles have been auto-generated by the streaming service.
|
||||
*
|
||||
|
@ -152,6 +170,18 @@ public final class SubtitlesStream extends Stream {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the subtitles have been automatically translated
|
||||
* (i.e. by a machine like Google Translator) by the streaming service.
|
||||
* @param autoTranslated whether the subtitles have been automatically translated by the
|
||||
* streaming service
|
||||
* @return this {@link Builder} instance
|
||||
*/
|
||||
public Builder setAutoTranslated(final boolean autoTranslated) {
|
||||
this.autoTranslated = autoTranslated;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link SubtitlesStream} using the builder's current values.
|
||||
*
|
||||
|
@ -196,31 +226,41 @@ public final class SubtitlesStream extends Stream {
|
|||
+ "with setIsAutoGenerated.");
|
||||
}
|
||||
|
||||
if (autoTranslated == null) {
|
||||
throw new IllegalStateException("The subtitles stream has been not set as an "
|
||||
+ "automatically translated subtitles stream or not. "
|
||||
+ "Please specify this information with setIsAutoTranslated.");
|
||||
}
|
||||
|
||||
if (id == null) {
|
||||
id = languageCode + (mediaFormat != null ? "." + mediaFormat.suffix
|
||||
: "");
|
||||
}
|
||||
|
||||
return new SubtitlesStream(id, content, isUrl, mediaFormat, deliveryMethod,
|
||||
languageCode, autoGenerated, manifestUrl);
|
||||
languageCode, autoGenerated, autoTranslated, baseLanguageCode, manifestUrl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new subtitles stream.
|
||||
*
|
||||
* @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
|
||||
* manifest
|
||||
* @param mediaFormat the {@link MediaFormat} used by the stream
|
||||
* @param deliveryMethod the {@link DeliveryMethod} of the stream
|
||||
* @param languageCode the language code of the stream
|
||||
* @param autoGenerated whether the subtitles are auto-generated by the streaming service
|
||||
* @param manifestUrl the URL of the manifest this stream comes from (if applicable,
|
||||
* otherwise null)
|
||||
* @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
|
||||
* manifest
|
||||
* @param mediaFormat the {@link MediaFormat} used by the stream
|
||||
* @param deliveryMethod the {@link DeliveryMethod} of the stream
|
||||
* @param languageCode the language code of the stream
|
||||
* @param autoGenerated whether the subtitles are auto-generated by the streaming service
|
||||
* @param autoTranslated whether the subtitles are auto-translated by the streaming service
|
||||
* @param baseLanguageCode the language code of the base language used to translate
|
||||
* the subtitles to the current language
|
||||
* or null if the subtitles are not auto-translated
|
||||
* @param manifestUrl the URL of the manifest this stream comes from (if applicable,
|
||||
* otherwise null)
|
||||
*/
|
||||
@SuppressWarnings("checkstyle:ParameterNumber")
|
||||
private SubtitlesStream(@Nonnull final String id,
|
||||
|
@ -230,6 +270,8 @@ public final class SubtitlesStream extends Stream {
|
|||
@Nonnull final DeliveryMethod deliveryMethod,
|
||||
@Nonnull final String languageCode,
|
||||
final boolean autoGenerated,
|
||||
final boolean autoTranslated,
|
||||
@Nullable final String baseLanguageCode,
|
||||
@Nullable final String manifestUrl) throws ParsingException {
|
||||
super(id, content, isUrl, mediaFormat, deliveryMethod, manifestUrl);
|
||||
this.locale = LocaleCompat.forLanguageTag(languageCode).orElseThrow(
|
||||
|
@ -238,6 +280,14 @@ public final class SubtitlesStream extends Stream {
|
|||
this.code = languageCode;
|
||||
this.format = mediaFormat;
|
||||
this.autoGenerated = autoGenerated;
|
||||
this.autoTranslated = autoTranslated;
|
||||
if (baseLanguageCode == null) {
|
||||
this.baseLocale = null;
|
||||
} else {
|
||||
this.baseLocale = LocaleCompat.forLanguageTag(baseLanguageCode).orElseThrow(
|
||||
() -> new ParsingException(
|
||||
"not a valid locale language code: " + baseLanguageCode));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -250,7 +300,7 @@ public final class SubtitlesStream extends Stream {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return whether if the subtitles are auto-generated.
|
||||
* Return whether the subtitles are auto-generated.
|
||||
* <p>
|
||||
* Some streaming services can generate subtitles for their contents, like YouTube.
|
||||
* </p>
|
||||
|
@ -261,6 +311,21 @@ public final class SubtitlesStream extends Stream {
|
|||
return autoGenerated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the subtitles are translated automatically by a machine.
|
||||
*
|
||||
* <p>
|
||||
* Some streaming services provide automatically translated subtitles.
|
||||
* YouTube, for example, uses Google translator to generate translated subtitles.
|
||||
* Automatically translated subtitles might not coincide completely with the original text.
|
||||
* </p>
|
||||
*
|
||||
* @return {code true} if the subtitles are auto-translated, {@link false} otherwise
|
||||
*/
|
||||
public boolean isAutoTranslated() {
|
||||
return autoTranslated;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -299,6 +364,37 @@ public final class SubtitlesStream extends Stream {
|
|||
return locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link Locale baseLocale} which was used to automatically translated the subtitles
|
||||
* into the current {@link #locale}.
|
||||
*
|
||||
* @return the {@link Locale baseLocale} for the subtitle translation
|
||||
* or {@code null} if the subtitle is not auto-translated
|
||||
*/
|
||||
@Nullable
|
||||
public Locale getBaseLocale() {
|
||||
return baseLocale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display base language name of the subtitles.
|
||||
*
|
||||
* @return the display language name of the subtitles
|
||||
*/
|
||||
public String getDisplayBaseLanguageName() {
|
||||
return locale.getDisplayName(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the language tag of the subtitles.
|
||||
*
|
||||
* @return the language tag of the subtitles
|
||||
*/
|
||||
public String getBaseLanguageTag() {
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* No subtitles which are currently extracted use an {@link ItagItem}, so {@code null} is
|
||||
* returned by this method.
|
||||
|
@ -310,4 +406,16 @@ public final class SubtitlesStream extends Stream {
|
|||
public ItagItem getItagItem() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SubtitlesStream{"
|
||||
+ "format=" + format
|
||||
+ ", baseLocale=" + baseLocale
|
||||
+ ", locale=" + locale
|
||||
+ ", autoGenerated=" + autoGenerated
|
||||
+ ", autoTranslated=" + autoTranslated
|
||||
+ ", code='" + code + '\''
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.schabi.newpipe.extractor.utils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
|
||||
|
@ -16,7 +17,7 @@ public final class LocaleCompat {
|
|||
|
||||
// Source: The AndroidX LocaleListCompat class's private forLanguageTagCompat() method.
|
||||
// Use Locale.forLanguageTag() on Android API level >= 21 / Java instead.
|
||||
public static Optional<Locale> forLanguageTag(final String str) {
|
||||
public static Optional<Locale> forLanguageTag(@Nonnull final String str) {
|
||||
if (str.contains("-")) {
|
||||
final String[] args = str.split("-", -1);
|
||||
if (args.length > 2) {
|
||||
|
|
|
@ -50,6 +50,7 @@ import org.schabi.newpipe.extractor.stream.Description;
|
|||
import org.schabi.newpipe.extractor.stream.StreamExtractor;
|
||||
import org.schabi.newpipe.extractor.stream.StreamSegment;
|
||||
import org.schabi.newpipe.extractor.stream.StreamType;
|
||||
import org.schabi.newpipe.extractor.stream.SubtitlesStream;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
|
@ -603,4 +604,67 @@ public class YoutubeStreamExtractorDefaultTest {
|
|||
.anyMatch(s -> s.getAudioTrackType() == AudioTrackType.DESCRIPTIVE));
|
||||
}
|
||||
}
|
||||
|
||||
public static class GeneratedSubtitles {
|
||||
private static YoutubeStreamExtractor extractor;
|
||||
private static List<SubtitlesStream> subtitles;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "generatedSubtitles"));
|
||||
extractor = (YoutubeStreamExtractor) YouTube
|
||||
.getStreamExtractor("https://www.youtube.com/watch?v=bvwohQavFV8");
|
||||
extractor.fetchPage();
|
||||
subtitles = extractor.getSubtitlesDefault();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUploaderProvidedSubtitles() {
|
||||
assertEquals(1, subtitles.stream().filter(s -> !s.isAutoGenerated()).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutoGeneratedSubtitles() {
|
||||
assertEquals(1, subtitles.stream().filter(
|
||||
s -> s.isAutoGenerated() && !s.isAutoTranslated()).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutoTranslatedSubtitles() {
|
||||
assertTrue(subtitles.stream().anyMatch(SubtitlesStream::isAutoTranslated));
|
||||
}
|
||||
}
|
||||
|
||||
public static class GeneratedAndTranslatedSubtitles {
|
||||
private static YoutubeStreamExtractor extractor;
|
||||
private static List<SubtitlesStream> subtitles;
|
||||
|
||||
@BeforeAll
|
||||
public static void setUp() throws Exception {
|
||||
YoutubeTestsUtils.ensureStateless();
|
||||
NewPipe.init(DownloaderFactory.getDownloader(RESOURCE_PATH + "generatedAndTranslatedSubtitles"));
|
||||
extractor = (YoutubeStreamExtractor) YouTube
|
||||
.getStreamExtractor("https://www.youtube.com/watch?v=_cMxraX_5RE");
|
||||
extractor.fetchPage();
|
||||
subtitles = extractor.getSubtitlesDefault();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUploaderProvidedSubtitles() {
|
||||
System.out.println("Getestet");
|
||||
assertEquals(9, subtitles.stream().filter(s -> !s.isAutoGenerated()).count());
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutoGeneratedSubtitles() {
|
||||
assertFalse(subtitles.stream().anyMatch(s -> s.isAutoGenerated() && !s.isAutoTranslated()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testAutoTranslatedSubtitles() {
|
||||
assertTrue(subtitles.stream().anyMatch(SubtitlesStream::isAutoTranslated));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"request": {
|
||||
"httpMethod": "GET",
|
||||
"url": "https://www.youtube.com/iframe_api",
|
||||
"headers": {
|
||||
"Accept-Language": [
|
||||
"en-GB, en;q\u003d0.9"
|
||||
]
|
||||
},
|
||||
"localization": {
|
||||
"languageCode": "en",
|
||||
"countryCode": "GB"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"responseCode": 200,
|
||||
"responseMessage": "",
|
||||
"responseHeaders": {
|
||||
"alt-svc": [
|
||||
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
|
||||
],
|
||||
"cache-control": [
|
||||
"private, max-age\u003d0"
|
||||
],
|
||||
"content-type": [
|
||||
"text/javascript; charset\u003dutf-8"
|
||||
],
|
||||
"cross-origin-opener-policy-report-only": [
|
||||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"cross-origin-resource-policy": [
|
||||
"cross-origin"
|
||||
],
|
||||
"date": [
|
||||
"Fri, 10 May 2024 18:09:22 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Fri, 10 May 2024 18:09:22 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
],
|
||||
"p3p": [
|
||||
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
|
||||
],
|
||||
"permissions-policy": [
|
||||
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
|
||||
],
|
||||
"report-to": [
|
||||
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
|
||||
],
|
||||
"server": [
|
||||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003d5lZN_zS_nS8; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d5oQ2igvAhi8; Domain\u003d.youtube.com; Expires\u003dWed, 06-Nov-2024 18:09:22 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_PRIVACY_METADATA\u003dCgJERRIEEgAgJA%3D%3D; Domain\u003d.youtube.com; Expires\u003dWed, 06-Nov-2024 18:09:22 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
||||
],
|
||||
"x-content-type-options": [
|
||||
"nosniff"
|
||||
],
|
||||
"x-frame-options": [
|
||||
"SAMEORIGIN"
|
||||
],
|
||||
"x-xss-protection": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"responseBody": "var scriptUrl \u003d \u0027https:\\/\\/www.youtube.com\\/s\\/player\\/17fd9675\\/www-widgetapi.vflset\\/www-widgetapi.js\u0027;try{var ttPolicy\u003dwindow.trustedTypes.createPolicy(\"youtube-widget-api\",{createScriptURL:function(x){return x}});scriptUrl\u003dttPolicy.createScriptURL(scriptUrl)}catch(e){}var YT;if(!window[\"YT\"])YT\u003d{loading:0,loaded:0};var YTConfig;if(!window[\"YTConfig\"])YTConfig\u003d{\"host\":\"https://www.youtube.com\"};\nif(!YT.loading){YT.loading\u003d1;(function(){var l\u003d[];YT.ready\u003dfunction(f){if(YT.loaded)f();else l.push(f)};window.onYTReady\u003dfunction(){YT.loaded\u003d1;var i\u003d0;for(;i\u003cl.length;i++)try{l[i]()}catch(e){}};YT.setConfig\u003dfunction(c){var k;for(k in c)if(c.hasOwnProperty(k))YTConfig[k]\u003dc[k]};var a\u003ddocument.createElement(\"script\");a.type\u003d\"text/javascript\";a.id\u003d\"www-widgetapi-script\";a.src\u003dscriptUrl;a.async\u003dtrue;var c\u003ddocument.currentScript;if(c){var n\u003dc.nonce||c.getAttribute(\"nonce\");if(n)a.setAttribute(\"nonce\",\nn)}var b\u003ddocument.getElementsByTagName(\"script\")[0];b.parentNode.insertBefore(a,b)})()};\n",
|
||||
"latestUrl": "https://www.youtube.com/iframe_api"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
"request": {
|
||||
"httpMethod": "GET",
|
||||
"url": "https://www.youtube.com/sw.js",
|
||||
"headers": {
|
||||
"Referer": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Accept-Language": [
|
||||
"en-GB, en;q\u003d0.9"
|
||||
]
|
||||
},
|
||||
"localization": {
|
||||
"languageCode": "en",
|
||||
"countryCode": "GB"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"responseCode": 200,
|
||||
"responseMessage": "",
|
||||
"responseHeaders": {
|
||||
"access-control-allow-credentials": [
|
||||
"true"
|
||||
],
|
||||
"access-control-allow-origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"alt-svc": [
|
||||
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
|
||||
],
|
||||
"cache-control": [
|
||||
"private, max-age\u003d0"
|
||||
],
|
||||
"content-type": [
|
||||
"text/javascript; charset\u003dutf-8"
|
||||
],
|
||||
"cross-origin-opener-policy": [
|
||||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"date": [
|
||||
"Fri, 10 May 2024 18:09:22 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Fri, 10 May 2024 18:09:22 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
],
|
||||
"p3p": [
|
||||
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
|
||||
],
|
||||
"permissions-policy": [
|
||||
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
|
||||
],
|
||||
"report-to": [
|
||||
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
|
||||
],
|
||||
"server": [
|
||||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003dT8VnXOSp4uA; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dSat, 14-Aug-2021 18:09:22 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
||||
],
|
||||
"x-content-type-options": [
|
||||
"nosniff"
|
||||
],
|
||||
"x-frame-options": [
|
||||
"SAMEORIGIN"
|
||||
],
|
||||
"x-xss-protection": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"responseBody": "\n self.addEventListener(\u0027install\u0027, event \u003d\u003e {\n event.waitUntil(self.skipWaiting());\n });\n self.addEventListener(\u0027activate\u0027, event \u003d\u003e {\n event.waitUntil(\n self.clients.claim().then(() \u003d\u003e self.registration.unregister()));\n });\n ",
|
||||
"latestUrl": "https://www.youtube.com/sw.js"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,76 @@
|
|||
{
|
||||
"request": {
|
||||
"httpMethod": "GET",
|
||||
"url": "https://www.youtube.com/iframe_api",
|
||||
"headers": {
|
||||
"Accept-Language": [
|
||||
"en-GB, en;q\u003d0.9"
|
||||
]
|
||||
},
|
||||
"localization": {
|
||||
"languageCode": "en",
|
||||
"countryCode": "GB"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"responseCode": 200,
|
||||
"responseMessage": "",
|
||||
"responseHeaders": {
|
||||
"alt-svc": [
|
||||
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
|
||||
],
|
||||
"cache-control": [
|
||||
"private, max-age\u003d0"
|
||||
],
|
||||
"content-type": [
|
||||
"text/javascript; charset\u003dutf-8"
|
||||
],
|
||||
"cross-origin-opener-policy-report-only": [
|
||||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"cross-origin-resource-policy": [
|
||||
"cross-origin"
|
||||
],
|
||||
"date": [
|
||||
"Fri, 10 May 2024 18:09:24 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Fri, 10 May 2024 18:09:24 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
],
|
||||
"p3p": [
|
||||
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
|
||||
],
|
||||
"permissions-policy": [
|
||||
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
|
||||
],
|
||||
"report-to": [
|
||||
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
|
||||
],
|
||||
"server": [
|
||||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003d41-Oy5v90x8; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d41qxFjSBh3I; Domain\u003d.youtube.com; Expires\u003dWed, 06-Nov-2024 18:09:24 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_PRIVACY_METADATA\u003dCgJERRIEEgAgMQ%3D%3D; Domain\u003d.youtube.com; Expires\u003dWed, 06-Nov-2024 18:09:24 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
||||
],
|
||||
"x-content-type-options": [
|
||||
"nosniff"
|
||||
],
|
||||
"x-frame-options": [
|
||||
"SAMEORIGIN"
|
||||
],
|
||||
"x-xss-protection": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"responseBody": "var scriptUrl \u003d \u0027https:\\/\\/www.youtube.com\\/s\\/player\\/17fd9675\\/www-widgetapi.vflset\\/www-widgetapi.js\u0027;try{var ttPolicy\u003dwindow.trustedTypes.createPolicy(\"youtube-widget-api\",{createScriptURL:function(x){return x}});scriptUrl\u003dttPolicy.createScriptURL(scriptUrl)}catch(e){}var YT;if(!window[\"YT\"])YT\u003d{loading:0,loaded:0};var YTConfig;if(!window[\"YTConfig\"])YTConfig\u003d{\"host\":\"https://www.youtube.com\"};\nif(!YT.loading){YT.loading\u003d1;(function(){var l\u003d[];YT.ready\u003dfunction(f){if(YT.loaded)f();else l.push(f)};window.onYTReady\u003dfunction(){YT.loaded\u003d1;var i\u003d0;for(;i\u003cl.length;i++)try{l[i]()}catch(e){}};YT.setConfig\u003dfunction(c){var k;for(k in c)if(c.hasOwnProperty(k))YTConfig[k]\u003dc[k]};var a\u003ddocument.createElement(\"script\");a.type\u003d\"text/javascript\";a.id\u003d\"www-widgetapi-script\";a.src\u003dscriptUrl;a.async\u003dtrue;var c\u003ddocument.currentScript;if(c){var n\u003dc.nonce||c.getAttribute(\"nonce\");if(n)a.setAttribute(\"nonce\",\nn)}var b\u003ddocument.getElementsByTagName(\"script\")[0];b.parentNode.insertBefore(a,b)})()};\n",
|
||||
"latestUrl": "https://www.youtube.com/iframe_api"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,84 @@
|
|||
{
|
||||
"request": {
|
||||
"httpMethod": "GET",
|
||||
"url": "https://www.youtube.com/sw.js",
|
||||
"headers": {
|
||||
"Referer": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"Accept-Language": [
|
||||
"en-GB, en;q\u003d0.9"
|
||||
]
|
||||
},
|
||||
"localization": {
|
||||
"languageCode": "en",
|
||||
"countryCode": "GB"
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"responseCode": 200,
|
||||
"responseMessage": "",
|
||||
"responseHeaders": {
|
||||
"access-control-allow-credentials": [
|
||||
"true"
|
||||
],
|
||||
"access-control-allow-origin": [
|
||||
"https://www.youtube.com"
|
||||
],
|
||||
"alt-svc": [
|
||||
"h3\u003d\":443\"; ma\u003d2592000,h3-29\u003d\":443\"; ma\u003d2592000"
|
||||
],
|
||||
"cache-control": [
|
||||
"private, max-age\u003d0"
|
||||
],
|
||||
"content-type": [
|
||||
"text/javascript; charset\u003dutf-8"
|
||||
],
|
||||
"cross-origin-opener-policy": [
|
||||
"same-origin; report-to\u003d\"youtube_main\""
|
||||
],
|
||||
"date": [
|
||||
"Fri, 10 May 2024 18:09:24 GMT"
|
||||
],
|
||||
"expires": [
|
||||
"Fri, 10 May 2024 18:09:24 GMT"
|
||||
],
|
||||
"origin-trial": [
|
||||
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
|
||||
],
|
||||
"p3p": [
|
||||
"CP\u003d\"This is not a P3P policy! See http://support.google.com/accounts/answer/151657?hl\u003den-GB for more info.\""
|
||||
],
|
||||
"permissions-policy": [
|
||||
"ch-ua-arch\u003d*, ch-ua-bitness\u003d*, ch-ua-full-version\u003d*, ch-ua-full-version-list\u003d*, ch-ua-model\u003d*, ch-ua-wow64\u003d*, ch-ua-form-factor\u003d*, ch-ua-platform\u003d*, ch-ua-platform-version\u003d*"
|
||||
],
|
||||
"report-to": [
|
||||
"{\"group\":\"youtube_main\",\"max_age\":2592000,\"endpoints\":[{\"url\":\"https://csp.withgoogle.com/csp/report-to/youtube_main\"}]}"
|
||||
],
|
||||
"server": [
|
||||
"ESF"
|
||||
],
|
||||
"set-cookie": [
|
||||
"YSC\u003deg0CcKL2VB4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
|
||||
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dSat, 14-Aug-2021 18:09:24 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
|
||||
],
|
||||
"strict-transport-security": [
|
||||
"max-age\u003d31536000"
|
||||
],
|
||||
"x-content-type-options": [
|
||||
"nosniff"
|
||||
],
|
||||
"x-frame-options": [
|
||||
"SAMEORIGIN"
|
||||
],
|
||||
"x-xss-protection": [
|
||||
"0"
|
||||
]
|
||||
},
|
||||
"responseBody": "\n self.addEventListener(\u0027install\u0027, event \u003d\u003e {\n event.waitUntil(self.skipWaiting());\n });\n self.addEventListener(\u0027activate\u0027, event \u003d\u003e {\n event.waitUntil(\n self.clients.claim().then(() \u003d\u003e self.registration.unregister()));\n });\n ",
|
||||
"latestUrl": "https://www.youtube.com/sw.js"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Ładowanie…
Reference in New Issue