Tobi 2024-05-10 18:16:26 +00:00 zatwierdzone przez GitHub
commit aa0fa00bad
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
19 zmienionych plików z 3739 dodań i 40 usunięć

Wyświetl plik

@ -476,6 +476,7 @@ public class PeertubeStreamExtractor extends StreamExtractor {
.setMediaFormat(fmt)
.setLanguageCode(languageCode)
.setAutoGenerated(false)
.setAutoTranslated(false)
.build());
}
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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 + '\''
+ '}';
}
}

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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));
}
}
}

Wyświetl plik

@ -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"
}
}

Wyświetl plik

@ -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"
}
}

Wyświetl plik

@ -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"
}
}

Wyświetl plik

@ -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"
}
}