Compare commits

..

41 Commits
v0.24.2 ... dev

Author SHA1 Message Date
TobiGr 8e92227b2e Fix JDoc 2024-11-24 17:15:36 +01:00
Stypox eebcc46255
Release v0.24.3 2024-11-24 17:07:47 +01:00
Stypox 9fb03f6c87
Merge pull request #1192 from TeamNewPipe/user-agent
[tests] Update user agent
2024-11-18 17:13:55 +01:00
TobiGr e4a1a6ecd8 Fix tests 2024-11-17 21:38:47 +01:00
TobiGr 727e791602 [YouTube] Update mocks 2024-11-17 21:38:46 +01:00
TobiGr d635d4db2a Make RecordingDownloader more resillient against ReCaptchaExceptions
Implement a max number of requests per minute to prevent hitting reate limits and triggering ReCaptchaExceptions. This slows down the RecordingDownloader significantly and can be adjusted if needed. A request ist retried once when facing a ReCaptchaException.
2024-11-17 21:38:46 +01:00
Stypox ea1a1d1375
Merge pull request #1242 from TeamNewPipe/revert-1205-feature-branch
Revert "Refactored Identifiers"
2024-11-16 14:01:10 +01:00
Stypox c00d0a7028
Revert "Refactored Identifiers (#1205)"
This reverts commit 0de224124b.
2024-11-16 14:00:38 +01:00
Stypox d3d5f2b3f0
Merge pull request #1240 from AudricV/yt_fix-playlists-items-extraction
[YouTube] Add support for new playlist items data structure
2024-11-14 16:37:35 +01:00
congyuluo 0de224124b
Refactored Identifiers (#1205)
Extractor.pageFetched -> Extractor.isPageFetched
Stream.equalStats(Stream) is renamed to Stream.areStatsEqual(Stream)
Stream.getBitrate() is renamed to Stream.getBitRate()
2024-11-13 10:01:20 +01:00
AudricV 183563cc9e
[YouTube] Add support for playlists lockupViewModels
This new data type, A/B tested or rolled out at the time the changes
are commited, is present on multiple surfaces.
2024-11-10 21:44:06 +01:00
AudricV f52d2269fc
[YouTube] Move channel verified status check from badges to a method
This method will be used in more places such as the new playlist item
data.

Support for a new icon used in artist channels has been also added.
2024-11-10 20:18:04 +01:00
TobiGr 667c867ad8 Update user agent to Firefox ESR 128 2024-11-10 17:27:22 +01:00
Tobi 169098432b
Merge pull request #1239 from AudricV/yt_fix-shorts-thumbnails-extraction
[YouTube] Fix Shorts' thumbnails extraction in their channel tab
2024-11-06 09:42:13 +01:00
AudricV 06b2c8e2aa
[YouTube] Fix Shorts' thumbnails extraction in their channel tab
Wrong methods were used to access and extract the thumbnails' data.
This has been fixed with this commit.
2024-11-06 09:31:42 +01:00
Tobi c343e31ed2
Merge pull request #1236 from Thompson3142/fix_scrubbing_seekbar_preview_crash
Add documentation for faulty framesets
2024-10-27 14:42:06 +01:00
TobiGr 1f26c12098 Use JDoc and inherit doc 2024-10-27 09:45:15 +01:00
Tobi 6af22e3e45
Merge pull request #1237 from AudricV/yt_more-audio-track-types-support
[YouTube] Add support for automatic dubbed and secondary audio tracks
2024-10-27 09:19:01 +01:00
AudricV 8a3350f79d
[YouTube] Add support for automatic dubbed and secondary tracks 2024-10-26 20:32:39 +02:00
Thompson3142 542867ff4d Add documentation for faulty framesets 2024-10-24 19:36:35 +02:00
Tobi abba78cf9d
Merge pull request #1235 from TeamNewPipe/dependabot/gradle/org.junit-junit-bom-5.11.3
Bump org.junit:junit-bom from 5.11.2 to 5.11.3
2024-10-22 20:53:10 +02:00
dependabot[bot] 534bbc90cf
Bump org.junit:junit-bom from 5.11.2 to 5.11.3
Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.11.2 to 5.11.3.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.11.2...r5.11.3)

---
updated-dependencies:
- dependency-name: org.junit:junit-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-22 09:39:48 +00:00
Tobi f169885dbc
Merge pull request #1219 from floriegl/fix-case-sensitive-jitpack-coordinates
Fix for JitPack case sensitive coordinates in README
2024-10-10 15:28:04 +02:00
Tobi 18c9f1fd38
Merge pull request #1233 from TeamNewPipe/dependabot/gradle/org.junit-junit-bom-5.11.2
Bump org.junit:junit-bom from 5.11.0 to 5.11.2
2024-10-05 20:22:02 +02:00
dependabot[bot] fb81eaab82
Bump org.junit:junit-bom from 5.11.0 to 5.11.2
Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.11.0 to 5.11.2.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.11.0...r5.11.2)

---
updated-dependencies:
- dependency-name: org.junit:junit-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-05 18:17:38 +00:00
Tobi 5431069588
Merge pull request #1231 from AudricV/yt_fix-n-param-decode-function-extraction
[YouTube] Fix extraction of n param deobfuscation function name
2024-10-05 20:16:15 +02:00
Tobi 743a4000b8
Merge pull request #1207 from TeamNewPipe/fix/peertube-certain-domains
[PeerTube] Fix parsing ID for instances whose domain ends with a or c
2024-10-05 19:20:42 +02:00
AudricV 69ff271be1
[YouTube] Fix extraction of n param deobfuscation function name
This commit adds two new regular expressions to parse the n parameter function.

It also improves existing regular expressions by using the constant representing
multiple characters instead of adding the one or multiple characters
token manually in each regex for everything and not only function names.
2024-09-29 16:01:10 +02:00
Audric V. eb30316a36
Merge pull request #1222 from AudricV/yt_fix-videos-channel-tab-linkhandler-serialization
[YouTube] Fix serialization of Videos channel tab when it is already fetched
2024-09-29 15:58:43 +02:00
AudricV 42c1afaf87
[YouTube] Fix serialization of Videos channel tab when already fetched
Also remove usage of Optional as fields as it is not a good practice. This
simplifies in some places channel info extraction code.
2024-09-29 15:35:21 +02:00
Audric V. 596bce294d
Merge pull request #1221 from AudricV/yt_support-new-shorts-ui-data
[YouTube] Fix extraction of Shorts in channels and remove visitor data usage
2024-09-29 14:54:07 +02:00
AudricV f9ffdd91d5
[YouTube] Update YoutubeChannelTabExtractorTest.Shorts test class mocks 2024-09-08 17:51:08 +02:00
AudricV 34f28fc1f0
[YouTube] Remove visitorData usage for shorts continuations
It isn't required anymore and not used by extractor anymore since commit
5a6da5f43e, as the wrong page ID is used as a
visitor data (the VerifiedStatus value as a string).
2024-09-08 17:41:23 +02:00
AudricV f926fbcf35
[YouTube] Add support for shortsLockupViewModels
This new UI data type is replacing the reelItemRenderer one.
2024-09-08 17:21:40 +02:00
floriegl 36cc17c789
Update dependency coordinates due to case sensitivity in JitPack 2024-09-04 15:33:05 +02:00
TobiGr 6e3a4a6d9d [SoundCloud] Fix test: title changed 2024-08-15 12:22:37 +02:00
Tobi 70d6a06bf2
Merge pull request #1211 from TeamNewPipe/dependabot/gradle/org.junit-junit-bom-5.11.0
Bump org.junit:junit-bom from 5.10.3 to 5.11.0
2024-08-15 12:12:40 +02:00
dependabot[bot] 1278517492
Bump org.junit:junit-bom from 5.10.3 to 5.11.0
Bumps [org.junit:junit-bom](https://github.com/junit-team/junit5) from 5.10.3 to 5.11.0.
- [Release notes](https://github.com/junit-team/junit5/releases)
- [Commits](https://github.com/junit-team/junit5/compare/r5.10.3...r5.11.0)

---
updated-dependencies:
- dependency-name: org.junit:junit-bom
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-15 09:10:12 +00:00
TobiGr bcacfc53c5 [PeerTube] Fix parsing id for instances whose domain ends with a or c
The pattern to detect the channel ID was faulty and e.g. the ID detected for "https://kolektiva.media/video-channels/documentary_channel" was "a/video-channels" which is wrong.  A new pattern is added to distinguish between URLs and potential IDs because IDs must not start with a "/" while IDs inside an URL must.

Fixes TeamNewPipe/NewPipe#11369
2024-08-02 18:19:45 +02:00
TobiGr 6963385176 Fix issue template dir name 2024-08-02 12:50:30 +02:00
opusforlife2 5f1ba8cf7d
Add issue templates (#1204)
* Create bug report template

* Create feature request template

* Create config.yml

---------

Co-authored-by: TobiGr <tobigr@users.noreply.github.com>
2024-08-02 12:44:11 +02:00
388 changed files with 15198 additions and 14807 deletions

93
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@ -0,0 +1,93 @@
name: Bug report
description: Create a bug report to help us improve
labels: [bug]
body:
- type: markdown
attributes:
value: |
Thank you for helping to make the NewPipe Extractor better by reporting a bug. :hugs:
Please fill in as much information as possible about your bug so that we don't have to play "information ping-pong" and can help you immediately.
- type: checkboxes
id: checklist
attributes:
label: "Checklist"
options:
- label: "I am able to reproduce the bug with the latest version given here: [CLICK THIS LINK](https://github.com/TeamNewPipe/NewPipeExtractor/releases/latest)."
required: true
- label: "I am aware that this issue is being opened for the NewPipe Extractor, NOT the [app](https://github.com/TeamNewPipe/NewPipe), and my bug report will be dismissed otherwise."
required: true
- label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipeExtractor/issues) or [closed](https://github.com/TeamNewPipe/NewPipeExtractor/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to."
required: true
- label: "I have taken the time to fill in all the required details. I understand that the bug report will be dismissed otherwise."
required: true
- label: "This issue contains only one bug."
required: true
- label: "I have read and understood the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/dev/.github/CONTRIBUTING.md)."
required: true
- type: input
id: extractor-version
attributes:
label: Affected version
description: "In which NewPipe Extractor version did you encounter the bug?"
placeholder: "x.xx.x"
validations:
required: true
- type: textarea
id: steps-to-reproduce
attributes:
label: Steps to reproduce the bug
description: |
What did you do for the bug to show up?
If you can't cause the bug to show up again reliably (and hence don't have a proper set of steps to give us), please still try to give as many details as possible on how you think you encountered the bug.
placeholder: |
1. Init NewPipe with 'NewPipe.init(...)'
2. Create a StreamExtractor for xyz: 'StreamExtractor e = YouTube.getStreamExtractor(xyz.com)'
3. Get the description 'e.getDescription()'
validations:
required: true
- type: textarea
id: expected-behavior
attributes:
label: Expected behavior
description: |
Tell us what you expect to happen.
- type: textarea
id: actual-behavior
attributes:
label: Actual behavior
description: |
Tell us what happens with the steps given above.
- type: textarea
id: screen-media
attributes:
label: Screenshots/Screen recordings
description: |
A picture or video is worth a thousand words.
If applicable, add screenshots or a screen recording to help explain your problem.
GitHub supports uploading them directly in the text box.
If your file is too big for Github to accept, try to compress it (ZIP-file) or feel free to paste a link to an image/video hoster here instead.
- type: textarea
id: logs
attributes:
label: Logs
description: |
If your bug includes a log you think we need to see, paste it here.
- type: textarea
id: additional-information
attributes:
label: Additional information
description: |
Any other information you'd like to include, for instance that
* your cat disabled your network connection
* ...

8
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,8 @@
blank_issues_enabled: false
contact_links:
- name: 💬 Matrix
url: https://matrix.to/#/#newpipe:matrix.newpipe-ev.de
about: Chat with us via Matrix for quick Q/A
- name: 💬 IRC
url: https://web.libera.chat/#newpipe
about: Chat with us via IRC for quick Q/A

50
.github/ISSUE_TEMPLATE/enhancement.yml vendored Normal file
View File

@ -0,0 +1,50 @@
name: Feature request
description: Suggest an idea for this project
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
Thank you for helping to make the NewPipe Extractor better by suggesting a feature. :hugs:
Your ideas are highly welcome! The Extractor is made for you, the downstream developers, after all.
- type: checkboxes
id: checklist
attributes:
label: "Checklist"
options:
- label: "I am aware that this issue is being opened for the NewPipe Extractor, NOT the [app](https://github.com/TeamNewPipe/NewPipe), and my feature request will be dismissed otherwise."
required: true
- label: "I made sure that there are *no existing issues* - [open](https://github.com/TeamNewPipe/NewPipeExtractor/issues) or [closed](https://github.com/TeamNewPipe/NewPipeExtractor/issues?q=is%3Aissue+is%3Aclosed) - which I could contribute my information to."
required: true
- label: "I have taken the time to fill in all the required details. I understand that the feature request will be dismissed otherwise."
required: true
- label: "This issue contains only one feature request."
required: true
- label: "I have read and understood the [contribution guidelines](https://github.com/TeamNewPipe/NewPipe/blob/dev/.github/CONTRIBUTING.md)."
required: true
- type: textarea
id: feature-description
attributes:
label: Feature description
description: |
Explain how you want the Extractor's behavior to change to suit your needs.
validations:
required: true
- type: textarea
id: why-is-the-feature-requested
attributes:
label: Why do you want this feature?
description: |
Describe any problem or limitation you come across while using the Extractor which would be solved by this feature.
validations:
required: true
- type: textarea
id: additional-information
attributes:
label: Additional information
description: Any other information you'd like to include, for instance sketches, mockups, pictures of cats, etc.

View File

@ -1,6 +1,6 @@
# NewPipe Extractor
[![CI](https://github.com/TeamNewPipe/NewPipeExtractor/actions/workflows/ci.yml/badge.svg?branch=dev&event=schedule)](https://github.com/TeamNewPipe/NewPipeExtractor/actions/workflows/ci.yml) [![JIT Pack Badge](https://jitpack.io/v/TeamNewPipe/NewPipeExtractor.svg)](https://jitpack.io/#TeamNewPipe/NewPipeExtractor) [JDoc](https://teamnewpipe.github.io/NewPipeExtractor/javadoc/) • [Documentation](https://teamnewpipe.github.io/documentation/)
[![CI](https://github.com/TeamNewPipe/NewPipeExtractor/actions/workflows/ci.yml/badge.svg?branch=dev&event=schedule)](https://github.com/TeamNewPipe/NewPipeExtractor/actions/workflows/ci.yml) [![JIT Pack Badge](https://jitpack.io/v/teamnewpipe/NewPipeExtractor.svg)](https://jitpack.io/#teamnewpipe/NewPipeExtractor) [JDoc](https://teamnewpipe.github.io/NewPipeExtractor/javadoc/) • [Documentation](https://teamnewpipe.github.io/documentation/)
NewPipe Extractor is a library for extracting things from streaming sites. It is a core component of [NewPipe](https://github.com/TeamNewPipe/NewPipe), but could be used independently.
@ -11,7 +11,7 @@ NewPipe Extractor is available at JitPack's Maven repo.
If you're using Gradle, you could add NewPipe Extractor as a dependency with the following steps:
1. Add `maven { url 'https://jitpack.io' }` to the `repositories` in your `build.gradle`.
2. Add `implementation 'com.github.TeamNewPipe:NewPipeExtractor:INSERT_VERSION_HERE'` to the `dependencies` in your `build.gradle`. Replace `INSERT_VERSION_HERE` with the [latest release](https://github.com/TeamNewPipe/NewPipeExtractor/releases/latest).
2. Add `implementation 'com.github.teamnewpipe:NewPipeExtractor:INSERT_VERSION_HERE'` to the `dependencies` in your `build.gradle`. Replace `INSERT_VERSION_HERE` with the [latest release](https://github.com/TeamNewPipe/NewPipeExtractor/releases/latest).
3. If you are using tools to minimize your project, make sure to keep the files below, by e.g. adding the following lines to your proguard file:
```
## Rules for NewPipeExtractor
@ -30,7 +30,7 @@ To test changes quickly you can build the library locally. A good approach would
```groovy
includeBuild('../NewPipeExtractor') {
dependencySubstitution {
substitute module('com.github.TeamNewPipe:NewPipeExtractor') with project(':extractor')
substitute module('com.github.teamnewpipe:NewPipeExtractor') with project(':extractor')
}
}
```
@ -40,7 +40,7 @@ Another approach would be to use the local Maven repository, here's a gist of ho
1. Add `mavenLocal()` in your project `repositories` list (usually as the first entry to give priority above the others).
2. It's _recommended_ that you change the `version` of this library (e.g. `LOCAL_SNAPSHOT`).
3. Run gradle's `ìnstall` task to deploy this library to your local repository (using the wrapper, present in the root of this project: `./gradlew install`)
4. Change the dependency version used in your project to match the one you chose in step 2 (`implementation 'com.github.TeamNewPipe:NewPipeExtractor:LOCAL_SNAPSHOT'`)
4. Change the dependency version used in your project to match the one you chose in step 2 (`implementation 'com.github.teamnewpipe:NewPipeExtractor:LOCAL_SNAPSHOT'`)
> Tip for Android Studio users: After you make changes and run the `install` task, use the menu option `File → "Sync with File System"` to refresh the library in your project.

View File

@ -8,7 +8,7 @@ allprojects {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
version 'v0.24.2'
version 'v0.24.3'
group 'com.github.TeamNewPipe'
repositories {
@ -29,7 +29,7 @@ allprojects {
ext {
nanojsonVersion = "1d9e1aea9049fc9f85e68b43ba39fe7be1c1f751"
spotbugsVersion = "4.8.6"
junitVersion = "5.10.3"
junitVersion = "5.11.3"
checkstyleVersion = "10.4"
}
}

View File

@ -5,6 +5,7 @@ import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.linkhandler.ListLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Parser;
import javax.annotation.Nonnull;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
@ -14,6 +15,7 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
private static final PeertubeChannelLinkHandlerFactory INSTANCE
= new PeertubeChannelLinkHandlerFactory();
private static final String ID_PATTERN = "((accounts|a)|(video-channels|c))/([^/?&#]*)";
private static final String ID_URL_PATTERN = "/((accounts|a)|(video-channels|c))/([^/?&#]*)";
public static final String API_ENDPOINT = "/api/v1/";
private PeertubeChannelLinkHandlerFactory() {
@ -25,7 +27,7 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
@Override
public String getId(final String url) throws ParsingException, UnsupportedOperationException {
return fixId(Parser.matchGroup(ID_PATTERN, url, 0));
return fixId(Parser.matchGroup(ID_URL_PATTERN, url, 0));
}
@Override
@ -74,12 +76,13 @@ public final class PeertubeChannelLinkHandlerFactory extends ListLinkHandlerFact
* @param id the id to fix
* @return the fixed id
*/
private String fixId(final String id) {
if (id.startsWith("a/")) {
return "accounts" + id.substring(1);
} else if (id.startsWith("c/")) {
return "video-channels" + id.substring(1);
private String fixId(@Nonnull final String id) {
final String cleanedId = id.startsWith("/") ? id.substring(1) : id;
if (cleanedId.startsWith("a/")) {
return "accounts" + cleanedId.substring(1);
} else if (cleanedId.startsWith("c/")) {
return "video-channels" + cleanedId.substring(1);
}
return id;
return cleanedId;
}
}

View File

@ -11,12 +11,14 @@ import org.schabi.newpipe.extractor.localization.Localization;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.defaultAlertsCheck;
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.hasArtistOrVerifiedIconBadgeAttachment;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.prepareDesktopJsonBuilder;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
@ -233,7 +235,7 @@ public final class YoutubeChannelHelper {
* properties.
* </p>
*/
public static final class ChannelHeader {
public static final class ChannelHeader implements Serializable {
/**
* Types of supported YouTube channel headers.
@ -294,27 +296,27 @@ public final class YoutubeChannelHelper {
*/
public final HeaderType headerType;
private ChannelHeader(@Nonnull final JsonObject json, final HeaderType headerType) {
public ChannelHeader(@Nonnull final JsonObject json, final HeaderType headerType) {
this.json = json;
this.headerType = headerType;
}
}
/**
* Get a channel header as an {@link Optional} it if exists.
* Get a channel header it if exists.
*
* @param channelResponse a full channel JSON response
* @return an {@link Optional} containing a {@link ChannelHeader} or an empty {@link Optional}
* if no supported header has been found
* @return a {@link ChannelHeader} or {@code null} if no supported header has been found
*/
@Nonnull
public static Optional<ChannelHeader> getChannelHeader(
@Nullable
public static ChannelHeader getChannelHeader(
@Nonnull final JsonObject channelResponse) {
final JsonObject header = channelResponse.getObject(HEADER);
if (header.has(C4_TABBED_HEADER_RENDERER)) {
return Optional.of(header.getObject(C4_TABBED_HEADER_RENDERER))
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.C4_TABBED));
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.C4_TABBED))
.orElse(null);
} else if (header.has(CAROUSEL_HEADER_RENDERER)) {
return header.getObject(CAROUSEL_HEADER_RENDERER)
.getArray(CONTENTS)
@ -324,17 +326,20 @@ public final class YoutubeChannelHelper {
.filter(item -> item.has(TOPIC_CHANNEL_DETAILS_RENDERER))
.findFirst()
.map(item -> item.getObject(TOPIC_CHANNEL_DETAILS_RENDERER))
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.CAROUSEL));
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.CAROUSEL))
.orElse(null);
} else if (header.has("pageHeaderRenderer")) {
return Optional.of(header.getObject("pageHeaderRenderer"))
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.PAGE));
.map(json -> new ChannelHeader(json, ChannelHeader.HeaderType.PAGE))
.orElse(null);
} else if (header.has("interactiveTabbedHeaderRenderer")) {
return Optional.of(header.getObject("interactiveTabbedHeaderRenderer"))
.map(json -> new ChannelHeader(json,
ChannelHeader.HeaderType.INTERACTIVE_TABBED));
} else {
return Optional.empty();
ChannelHeader.HeaderType.INTERACTIVE_TABBED))
.orElse(null);
}
return null;
}
/**
@ -359,27 +364,11 @@ public final class YoutubeChannelHelper {
final JsonObject pageHeaderViewModel = channelHeader.json.getObject(CONTENT)
.getObject(PAGE_HEADER_VIEW_MODEL);
final boolean hasCircleOrMusicIcon = pageHeaderViewModel.getObject(TITLE)
.getObject("dynamicTextViewModel")
.getObject("text")
.getArray("attachmentRuns")
.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.anyMatch(attachmentRun -> attachmentRun.getObject("element")
.getObject("type")
.getObject("imageType")
.getObject("image")
.getArray("sources")
.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.anyMatch(source -> {
final String imageName = source.getObject("clientResource")
.getString("imageName");
return "CHECK_CIRCLE_FILLED".equals(imageName)
|| "MUSIC_FILLED".equals(imageName);
}));
final boolean hasCircleOrMusicIcon = hasArtistOrVerifiedIconBadgeAttachment(
pageHeaderViewModel.getObject(TITLE)
.getObject("dynamicTextViewModel")
.getObject("text")
.getArray("attachmentRuns"));
if (!hasCircleOrMusicIcon && pageHeaderViewModel.getObject("image")
.has("contentPreviewImageViewModel")) {
// If a pageHeaderRenderer has no object in which a check verified may be
@ -418,7 +407,7 @@ public final class YoutubeChannelHelper {
* If the ID cannot still be get, the fallback channel ID, if provided, will be used.
* </p>
*
* @param header the channel header
* @param channelHeader the channel header
* @param fallbackChannelId the fallback channel ID, which can be null
* @return the ID of the channel
* @throws ParsingException if the channel ID cannot be got from the channel header, the
@ -426,12 +415,10 @@ public final class YoutubeChannelHelper {
*/
@Nonnull
public static String getChannelId(
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Nonnull final Optional<ChannelHeader> header,
@Nullable final ChannelHeader channelHeader,
@Nonnull final JsonObject jsonResponse,
@Nullable final String fallbackChannelId) throws ParsingException {
if (header.isPresent()) {
final ChannelHeader channelHeader = header.get();
if (channelHeader != null) {
switch (channelHeader.headerType) {
case C4_TABBED:
final String channelId = channelHeader.json.getObject(HEADER)
@ -486,10 +473,9 @@ public final class YoutubeChannelHelper {
}
@Nonnull
public static String getChannelName(@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
@Nonnull final Optional<ChannelHeader> channelHeader,
@Nonnull final JsonObject jsonResponse,
@Nullable final JsonObject channelAgeGateRenderer)
public static String getChannelName(@Nullable final ChannelHeader channelHeader,
@Nullable final JsonObject channelAgeGateRenderer,
@Nonnull final JsonObject jsonResponse)
throws ParsingException {
if (channelAgeGateRenderer != null) {
final String title = channelAgeGateRenderer.getString("channelTitle");
@ -506,7 +492,8 @@ public final class YoutubeChannelHelper {
return metadataRendererTitle;
}
return channelHeader.map(header -> {
return Optional.ofNullable(channelHeader)
.map(header -> {
final JsonObject channelJson = header.json;
switch (header.headerType) {
case PAGE:

View File

@ -1584,6 +1584,29 @@ public final class YoutubeParsingHelper {
return false;
}
public static boolean hasArtistOrVerifiedIconBadgeAttachment(
@Nonnull final JsonArray attachmentRuns) {
return attachmentRuns.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.anyMatch(attachmentRun -> attachmentRun.getObject("element")
.getObject("type")
.getObject("imageType")
.getObject("image")
.getArray("sources")
.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.anyMatch(source -> {
final String imageName = source.getObject("clientResource")
.getString("imageName");
return "CHECK_CIRCLE_FILLED".equals(imageName)
|| "AUDIO_BADGE".equals(imageName)
|| "MUSIC_FILLED".equals(imageName);
}));
}
/**
* Generate a content playback nonce (also called {@code cpn}), sent by YouTube clients in
* playback requests (and also for some clients, in the player request body).
@ -1720,9 +1743,12 @@ public final class YoutubeParsingHelper {
case "original":
return AudioTrackType.ORIGINAL;
case "dubbed":
case "dubbed-auto":
return AudioTrackType.DUBBED;
case "descriptive":
return AudioTrackType.DESCRIPTIVE;
case "secondary":
return AudioTrackType.SECONDARY;
default:
return null;
}

View File

@ -22,7 +22,7 @@ final class YoutubeThrottlingParameterUtils {
private static final String SINGLE_CHAR_VARIABLE_REGEX = "[a-zA-Z0-9$_]";
private static final String FUNCTION_NAME_REGEX = SINGLE_CHAR_VARIABLE_REGEX + "+";
private static final String MULTIPLE_CHARS_REGEX = SINGLE_CHAR_VARIABLE_REGEX + "+";
private static final String ARRAY_ACCESS_REGEX = "\\[(\\d+)]";
@ -30,31 +30,54 @@ final class YoutubeThrottlingParameterUtils {
private static final Pattern[] DEOBFUSCATION_FUNCTION_NAME_REGEXES = {
/*
* The first regex matches the following text, where we want rDa and the array index
* The first regex matches the following text, where we want Wma and the array index
* accessed:
*
* a.D&&(b="nn"[+a.D],WL(a),c=a.j[b]||null)&&(c=SDa[0](c),a.set(b,c),SDa.length||Wma("")
*/
Pattern.compile(SINGLE_CHAR_VARIABLE_REGEX + "=\"nn\"\\[\\+" + MULTIPLE_CHARS_REGEX
+ "\\." + MULTIPLE_CHARS_REGEX + "]," + MULTIPLE_CHARS_REGEX + "\\("
+ MULTIPLE_CHARS_REGEX + "\\)," + MULTIPLE_CHARS_REGEX + "="
+ MULTIPLE_CHARS_REGEX + "\\." + MULTIPLE_CHARS_REGEX + "\\["
+ MULTIPLE_CHARS_REGEX + "]\\|\\|null\\).+\\|\\|(" + MULTIPLE_CHARS_REGEX
+ ")\\(\"\"\\)"),
/*
* The second regex matches the following text, where we want SDa and the array index
* accessed:
*
* a.D&&(b="nn"[+a.D],WL(a),c=a.j[b]||null)&&(c=SDa[0](c),a.set(b,c),SDa.length||Wma("")
*/
Pattern.compile(SINGLE_CHAR_VARIABLE_REGEX + "=\"nn\"\\[\\+" + MULTIPLE_CHARS_REGEX
+ "\\." + MULTIPLE_CHARS_REGEX + "]," + MULTIPLE_CHARS_REGEX + "\\("
+ MULTIPLE_CHARS_REGEX + "\\)," + MULTIPLE_CHARS_REGEX + "="
+ MULTIPLE_CHARS_REGEX + "\\." + MULTIPLE_CHARS_REGEX + "\\["
+ MULTIPLE_CHARS_REGEX + "]\\|\\|null\\)&&\\(" + MULTIPLE_CHARS_REGEX + "=("
+ MULTIPLE_CHARS_REGEX + ")" + ARRAY_ACCESS_REGEX),
/*
* The third regex matches the following text, where we want rma:
*
* a.D&&(b="nn"[+a.D],c=a.get(b))&&(c=rDa[0](c),a.set(b,c),rDa.length||rma("")
*/
Pattern.compile(SINGLE_CHAR_VARIABLE_REGEX + "=\"nn\"\\[\\+" + MULTIPLE_CHARS_REGEX
+ "\\." + MULTIPLE_CHARS_REGEX + "]," + MULTIPLE_CHARS_REGEX + "="
+ MULTIPLE_CHARS_REGEX + "\\.get\\(" + MULTIPLE_CHARS_REGEX + "\\)\\).+\\|\\|("
+ MULTIPLE_CHARS_REGEX + ")\\(\"\"\\)"),
/*
* The fourth regex matches the following text, where we want rDa and the array index
* accessed:
*
* a.D&&(b="nn"[+a.D],c=a.get(b))&&(c=rDa[0](c),a.set(b,c),rDa.length||rma("")
*/
Pattern.compile(SINGLE_CHAR_VARIABLE_REGEX + "+=\"nn\"\\[\\+"
+ SINGLE_CHAR_VARIABLE_REGEX + "+\\." + SINGLE_CHAR_VARIABLE_REGEX + "+],"
+ SINGLE_CHAR_VARIABLE_REGEX + "+=" + SINGLE_CHAR_VARIABLE_REGEX
+ "+\\.get\\(" + SINGLE_CHAR_VARIABLE_REGEX + "+\\)\\)&&\\("
+ SINGLE_CHAR_VARIABLE_REGEX + "+=(" + SINGLE_CHAR_VARIABLE_REGEX
+ "+)\\[(\\d+)]"),
Pattern.compile(SINGLE_CHAR_VARIABLE_REGEX + "=\"nn\"\\[\\+" + MULTIPLE_CHARS_REGEX
+ "\\." + MULTIPLE_CHARS_REGEX + "]," + MULTIPLE_CHARS_REGEX + "="
+ MULTIPLE_CHARS_REGEX + "\\.get\\(" + MULTIPLE_CHARS_REGEX + "\\)\\)&&\\("
+ MULTIPLE_CHARS_REGEX + "=(" + MULTIPLE_CHARS_REGEX + ")\\[(\\d+)]"),
/*
* The second regex matches the following text, where we want rma:
*
* a.D&&(b="nn"[+a.D],c=a.get(b))&&(c=rDa[0](c),a.set(b,c),rDa.length||rma("")
*/
Pattern.compile(SINGLE_CHAR_VARIABLE_REGEX + "+=\"nn\"\\[\\+"
+ SINGLE_CHAR_VARIABLE_REGEX + "+\\." + SINGLE_CHAR_VARIABLE_REGEX + "+],"
+ SINGLE_CHAR_VARIABLE_REGEX + "+=" + SINGLE_CHAR_VARIABLE_REGEX + "+\\.get\\("
+ SINGLE_CHAR_VARIABLE_REGEX + "+\\)\\).+\\|\\|(" + SINGLE_CHAR_VARIABLE_REGEX
+ "+)\\(\"\"\\)"),
/*
* The third regex matches the following text, where we want BDa and the array index
* The fifth regex matches the following text, where we want BDa and the array index
* accessed:
*
* (b=String.fromCharCode(110),c=a.get(b))&&(c=BDa[0](c)
@ -62,17 +85,17 @@ final class YoutubeThrottlingParameterUtils {
Pattern.compile("\\(" + SINGLE_CHAR_VARIABLE_REGEX + "=String\\.fromCharCode\\(110\\),"
+ SINGLE_CHAR_VARIABLE_REGEX + "=" + SINGLE_CHAR_VARIABLE_REGEX + "\\.get\\("
+ SINGLE_CHAR_VARIABLE_REGEX + "\\)\\)" + "&&\\(" + SINGLE_CHAR_VARIABLE_REGEX
+ "=(" + FUNCTION_NAME_REGEX + ")" + "(?:" + ARRAY_ACCESS_REGEX + ")?\\("
+ "=(" + MULTIPLE_CHARS_REGEX + ")" + "(?:" + ARRAY_ACCESS_REGEX + ")?\\("
+ SINGLE_CHAR_VARIABLE_REGEX + "\\)"),
/*
* The fourth regex matches the following text, where we want Yva and the array index
* The sixth regex matches the following text, where we want Yva and the array index
* accessed:
*
* .get("n"))&&(b=Yva[0](b)
*/
Pattern.compile("\\.get\\(\"n\"\\)\\)&&\\(" + SINGLE_CHAR_VARIABLE_REGEX
+ "=(" + FUNCTION_NAME_REGEX + ")(?:" + ARRAY_ACCESS_REGEX + ")?\\("
+ "=(" + MULTIPLE_CHARS_REGEX + ")(?:" + ARRAY_ACCESS_REGEX + ")?\\("
+ SINGLE_CHAR_VARIABLE_REGEX + "\\)")
};
// CHECKSTYLE:ON

View File

@ -325,6 +325,8 @@ public final class YoutubeDashManifestCreatorsUtils {
case DESCRIPTIVE:
return "description";
default:
// Secondary track types do not seem to have a dedicated role in the DASH
// specification, so use alternate for them
return "alternate";
}
}

View File

@ -73,8 +73,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
private JsonObject jsonResponse;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private Optional<ChannelHeader> channelHeader;
@Nullable
private ChannelHeader channelHeader;
private String channelId;
@ -132,7 +132,7 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
public String getName() throws ParsingException {
assertPageFetched();
return YoutubeChannelHelper.getChannelName(
channelHeader, jsonResponse, channelAgeGateRenderer);
channelHeader, channelAgeGateRenderer, jsonResponse);
}
@Nonnull
@ -146,40 +146,40 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
.orElseThrow(() -> new ParsingException("Could not get avatars"));
}
return channelHeader.map(header -> {
switch (header.headerType) {
case PAGE:
final JsonObject imageObj = header.json.getObject(CONTENT)
.getObject(PAGE_HEADER_VIEW_MODEL)
.getObject(IMAGE);
return Optional.ofNullable(channelHeader)
.map(header -> {
switch (header.headerType) {
case PAGE:
final JsonObject imageObj = header.json.getObject(CONTENT)
.getObject(PAGE_HEADER_VIEW_MODEL)
.getObject(IMAGE);
if (imageObj.has(CONTENT_PREVIEW_IMAGE_VIEW_MODEL)) {
return imageObj.getObject(CONTENT_PREVIEW_IMAGE_VIEW_MODEL)
.getObject(IMAGE)
.getArray(SOURCES);
if (imageObj.has(CONTENT_PREVIEW_IMAGE_VIEW_MODEL)) {
return imageObj.getObject(CONTENT_PREVIEW_IMAGE_VIEW_MODEL)
.getObject(IMAGE)
.getArray(SOURCES);
}
if (imageObj.has("decoratedAvatarViewModel")) {
return imageObj.getObject("decoratedAvatarViewModel")
.getObject(AVATAR)
.getObject("avatarViewModel")
.getObject(IMAGE)
.getArray(SOURCES);
}
// Return an empty avatar array as a fallback
return new JsonArray();
case INTERACTIVE_TABBED:
return header.json.getObject("boxArt")
.getArray(THUMBNAILS);
case C4_TABBED:
case CAROUSEL:
default:
return header.json.getObject(AVATAR)
.getArray(THUMBNAILS);
}
if (imageObj.has("decoratedAvatarViewModel")) {
return imageObj.getObject("decoratedAvatarViewModel")
.getObject(AVATAR)
.getObject("avatarViewModel")
.getObject(IMAGE)
.getArray(SOURCES);
}
// Return an empty avatar array as a fallback
return new JsonArray();
case INTERACTIVE_TABBED:
return header.json.getObject("boxArt")
.getArray(THUMBNAILS);
case C4_TABBED:
case CAROUSEL:
default:
return header.json.getObject(AVATAR)
.getArray(THUMBNAILS);
}
})
})
.map(YoutubeParsingHelper::getImagesFromThumbnailsArray)
.orElseThrow(() -> new ParsingException("Could not get avatars"));
}
@ -192,7 +192,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
return List.of();
}
return channelHeader.map(header -> {
return Optional.ofNullable(channelHeader)
.map(header -> {
if (header.headerType == HeaderType.PAGE) {
final JsonObject pageHeaderViewModel = header.json.getObject(CONTENT)
.getObject(PAGE_HEADER_VIEW_MODEL);
@ -235,16 +236,14 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
return UNKNOWN_SUBSCRIBER_COUNT;
}
if (channelHeader.isPresent()) {
final ChannelHeader header = channelHeader.get();
if (header.headerType == HeaderType.INTERACTIVE_TABBED) {
if (channelHeader != null) {
if (channelHeader.headerType == HeaderType.INTERACTIVE_TABBED) {
// No subscriber count is available on interactiveTabbedHeaderRenderer header
return UNKNOWN_SUBSCRIBER_COUNT;
}
final JsonObject headerJson = header.json;
if (header.headerType == HeaderType.PAGE) {
final JsonObject headerJson = channelHeader.json;
if (channelHeader.headerType == HeaderType.PAGE) {
return getSubscriberCountFromPageChannelHeader(headerJson);
}
@ -321,19 +320,17 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
}
try {
if (channelHeader.isPresent()) {
final ChannelHeader header = channelHeader.get();
if (header.headerType == HeaderType.INTERACTIVE_TABBED) {
/*
In an interactiveTabbedHeaderRenderer, the real description, is only available
in its header
The other one returned in non-About tabs accessible in the
microformatDataRenderer object of the response may be completely different
The description extracted is incomplete and the original one can be only
accessed from the About tab
*/
return getTextFromObject(header.json.getObject("description"));
}
if (channelHeader != null
&& channelHeader.headerType == HeaderType.INTERACTIVE_TABBED) {
/*
In an interactiveTabbedHeaderRenderer, the real description, is only available
in its header
The other one returned in non-About tabs accessible in the
microformatDataRenderer object of the response may be completely different
The description extracted is incomplete and the original one can be only
accessed from the About tab
*/
return getTextFromObject(channelHeader.json.getObject("description"));
}
return jsonResponse.getObject(METADATA)
@ -368,8 +365,12 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
return false;
}
return YoutubeChannelHelper.isChannelVerified(channelHeader.orElseThrow(() ->
new ParsingException("Could not get verified status")));
if (channelHeader == null) {
throw new ParsingException(
"Could not get channel verified status, no channel header has been extracted");
}
return YoutubeChannelHelper.isChannelVerified(channelHeader);
}
@Nonnull
@ -421,6 +422,19 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
final String urlSuffix = urlParts[urlParts.length - 1];
/*
Make a copy of the channelHeader member to avoid keeping a reference to
this YoutubeChannelExtractor instance which would prevent serialization of
the ReadyChannelTabListLinkHandler instance created above
*/
final ChannelHeader channelHeaderCopy;
if (channelHeader == null) {
channelHeaderCopy = null;
} else {
channelHeaderCopy = new ChannelHeader(channelHeader.json,
channelHeader.headerType);
}
switch (urlSuffix) {
case "videos":
// Since the Videos tab has already its contents fetched, make
@ -431,9 +445,8 @@ public class YoutubeChannelExtractor extends ChannelExtractor {
channelId,
ChannelTabs.VIDEOS,
(service, linkHandler) -> new VideosTabExtractor(
service, linkHandler, tabRenderer, channelHeader,
name, id, url)));
service, linkHandler, tabRenderer,
channelHeaderCopy, name, id, url)));
break;
case "shorts":
addNonVideosTab.accept(ChannelTabs.SHORTS);

View File

@ -42,30 +42,15 @@ import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
*/
public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
/**
* Whether the visitor data extracted from the initial channel response is required to be used
* for continuations.
*
* <p>
* A valid {@code visitorData} is required to get continuations of shorts in channels.
* </p>
*
* <p>
* It should be not used when it is not needed, in order to reduce YouTube's tracking.
* </p>
*/
private final boolean useVisitorData;
@Nullable
protected YoutubeChannelHelper.ChannelHeader channelHeader;
private JsonObject jsonResponse;
private String channelId;
@Nullable
private String visitorData;
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
protected Optional<YoutubeChannelHelper.ChannelHeader> channelHeader;
public YoutubeChannelTabExtractor(final StreamingService service,
final ListLinkHandler linkHandler) {
super(service, linkHandler);
useVisitorData = getName().equals(ChannelTabs.SHORTS);
}
@Nonnull
@ -100,9 +85,6 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
jsonResponse = data.jsonResponse;
channelHeader = YoutubeChannelHelper.getChannelHeader(jsonResponse);
channelId = data.channelId;
if (useVisitorData) {
visitorData = jsonResponse.getObject("responseContext").getString("visitorData");
}
}
@Nonnull
@ -123,9 +105,9 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
}
protected String getChannelName() throws ParsingException {
return YoutubeChannelHelper.getChannelName(
channelHeader, jsonResponse,
YoutubeChannelHelper.getChannelAgeGateRenderer(jsonResponse));
return YoutubeChannelHelper.getChannelName(channelHeader,
YoutubeChannelHelper.getChannelAgeGateRenderer(jsonResponse),
jsonResponse);
}
@Nonnull
@ -159,11 +141,14 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
}
}
final VerifiedStatus verifiedStatus = channelHeader.flatMap(header ->
YoutubeChannelHelper.isChannelVerified(header)
? Optional.of(VerifiedStatus.VERIFIED)
: Optional.of(VerifiedStatus.UNVERIFIED))
.orElse(VerifiedStatus.UNKNOWN);
final VerifiedStatus verifiedStatus;
if (channelHeader == null) {
verifiedStatus = VerifiedStatus.UNKNOWN;
} else {
verifiedStatus = YoutubeChannelHelper.isChannelVerified(channelHeader)
? VerifiedStatus.VERIFIED
: VerifiedStatus.UNVERIFIED;
}
// If a channel tab is fetched, the next page requires channel ID and name, as channel
// streams don't have their channel specified.
@ -176,10 +161,8 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
channelName, channelUrl)
.orElse(null);
final Page nextPage = getNextPageFrom(continuation,
useVisitorData && !isNullOrEmpty(visitorData)
? List.of(channelName, channelUrl, verifiedStatus.toString(), visitorData)
: List.of(channelName, channelUrl, verifiedStatus.toString()));
final Page nextPage = getNextPageFrom(
continuation, List.of(channelName, channelUrl, verifiedStatus.toString()));
return new InfoItemsPage<>(collector, nextPage);
}
@ -299,6 +282,9 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
} else if (richItem.has("reelItemRenderer")) {
commitReel(collector, richItem.getObject("reelItemRenderer"),
channelVerifiedStatus, channelName, channelUrl);
} else if (richItem.has("shortsLockupViewModel")) {
commitShortsLockup(collector, richItem.getObject("shortsLockupViewModel"),
channelVerifiedStatus, channelName, channelUrl);
} else if (richItem.has("playlistRenderer")) {
commitPlaylist(collector, richItem.getObject("playlistRenderer"),
channelVerifiedStatus, channelName, channelUrl);
@ -325,6 +311,12 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
} else if (item.has("expandedShelfContentsRenderer")) {
return collectItemsFrom(collector, item.getObject("expandedShelfContentsRenderer")
.getArray("items"), channelVerifiedStatus, channelName, channelUrl);
} else if (item.has("lockupViewModel")) {
final JsonObject lockupViewModel = item.getObject("lockupViewModel");
if ("LOCKUP_CONTENT_TYPE_PLAYLIST".equals(lockupViewModel.getString("contentType"))) {
commitPlaylistLockup(collector, lockupViewModel, channelVerifiedStatus,
channelName, channelUrl);
}
} else if (item.has("continuationItemRenderer")) {
return Optional.ofNullable(item.getObject("continuationItemRenderer"));
}
@ -356,6 +348,61 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
});
}
private static void commitShortsLockup(@Nonnull final MultiInfoItemsCollector collector,
@Nonnull final JsonObject shortsLockupViewModel,
@Nonnull final VerifiedStatus channelVerifiedStatus,
@Nullable final String channelName,
@Nullable final String channelUrl) {
collector.commit(
new YoutubeShortsLockupInfoItemExtractor(shortsLockupViewModel) {
@Override
public String getUploaderName() throws ParsingException {
return isNullOrEmpty(channelName) ? super.getUploaderName() : channelName;
}
@Override
public String getUploaderUrl() throws ParsingException {
return isNullOrEmpty(channelUrl) ? super.getUploaderName() : channelUrl;
}
@Override
public boolean isUploaderVerified() {
return channelVerifiedStatus == VerifiedStatus.VERIFIED;
}
});
}
private void commitPlaylistLockup(@Nonnull final MultiInfoItemsCollector collector,
@Nonnull final JsonObject playlistLockupViewModel,
@Nonnull final VerifiedStatus channelVerifiedStatus,
@Nullable final String channelName,
@Nullable final String channelUrl) {
collector.commit(
new YoutubeMixOrPlaylistLockupInfoItemExtractor(playlistLockupViewModel) {
@Override
public String getUploaderName() throws ParsingException {
return isNullOrEmpty(channelName) ? super.getUploaderName() : channelName;
}
@Override
public String getUploaderUrl() throws ParsingException {
return isNullOrEmpty(channelUrl) ? super.getUploaderName() : channelUrl;
}
@Override
public boolean isUploaderVerified() throws ParsingException {
switch (channelVerifiedStatus) {
case VERIFIED:
return true;
case UNVERIFIED:
return false;
default:
return super.isUploaderVerified();
}
}
});
}
private void commitVideo(@Nonnull final MultiInfoItemsCollector collector,
@Nonnull final TimeAgoParser timeAgoParser,
@Nonnull final JsonObject jsonObject,
@ -434,8 +481,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
.getString("token");
final byte[] body = JsonWriter.string(prepareDesktopJsonBuilder(getExtractorLocalization(),
getExtractorContentCountry(),
useVisitorData && channelIds.size() >= 3 ? channelIds.get(2) : null)
getExtractorContentCountry())
.value("continuation", continuation)
.done())
.getBytes(StandardCharsets.UTF_8);
@ -457,8 +503,7 @@ public class YoutubeChannelTabExtractor extends ChannelTabExtractor {
VideosTabExtractor(final StreamingService service,
final ListLinkHandler linkHandler,
final JsonObject tabRenderer,
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
final Optional<YoutubeChannelHelper.ChannelHeader> channelHeader,
@Nullable final YoutubeChannelHelper.ChannelHeader channelHeader,
final String channelName,
final String channelId,
final String channelUrl) {

View File

@ -0,0 +1,193 @@
package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.ListExtractor;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.playlist.PlaylistInfo;
import org.schabi.newpipe.extractor.playlist.PlaylistInfoItemExtractor;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubePlaylistLinkHandlerFactory;
import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import java.util.List;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.extractPlaylistTypeFromPlaylistId;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getUrlFromNavigationEndpoint;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.hasArtistOrVerifiedIconBadgeAttachment;
public class YoutubeMixOrPlaylistLockupInfoItemExtractor implements PlaylistInfoItemExtractor {
@Nonnull
private final JsonObject lockupViewModel;
@Nonnull
private final JsonObject thumbnailViewModel;
@Nonnull
private final JsonObject lockupMetadataViewModel;
@Nonnull
private final JsonObject firstMetadataRow;
@Nonnull
private PlaylistInfo.PlaylistType playlistType;
public YoutubeMixOrPlaylistLockupInfoItemExtractor(@Nonnull final JsonObject lockupViewModel) {
this.lockupViewModel = lockupViewModel;
this.thumbnailViewModel = lockupViewModel.getObject("contentImage")
.getObject("collectionThumbnailViewModel")
.getObject("primaryThumbnail")
.getObject("thumbnailViewModel");
this.lockupMetadataViewModel = lockupViewModel.getObject("metadata")
.getObject("lockupMetadataViewModel");
/*
The metadata rows are structured in the following way:
1st part: uploader info, playlist type, playlist updated date
2nd part: space row
3rd element: first video
4th (not always returned for playlists with less than 2 items?): second video
5th element (always returned, but at a different index for playlists with less than 2
items?): Show full playlist
The first metadata row has the following structure:
1st array element: uploader info
2nd element: playlist type (course, playlist, podcast)
3rd element (not always returned): playlist updated date
*/
this.firstMetadataRow = lockupMetadataViewModel.getObject("metadata")
.getObject("contentMetadataViewModel")
.getArray("metadataRows")
.getObject(0);
try {
this.playlistType = extractPlaylistTypeFromPlaylistId(getPlaylistId());
} catch (final ParsingException e) {
// If we cannot extract the playlist type, fall back to the normal one
this.playlistType = PlaylistInfo.PlaylistType.NORMAL;
}
}
@Override
public String getUploaderName() throws ParsingException {
return firstMetadataRow.getArray("metadataParts")
.getObject(0)
.getObject("text")
.getString("content");
}
@Override
public String getUploaderUrl() throws ParsingException {
if (playlistType != PlaylistInfo.PlaylistType.NORMAL) {
// If the playlist is a mix, there is no uploader as they are auto-generated
return null;
}
return getUrlFromNavigationEndpoint(
firstMetadataRow.getArray("metadataParts")
.getObject(0)
.getObject("text")
.getArray("commandRuns")
.getObject(0)
.getObject("onTap")
.getObject("innertubeCommand"));
}
@Override
public boolean isUploaderVerified() throws ParsingException {
if (playlistType != PlaylistInfo.PlaylistType.NORMAL) {
// If the playlist is a mix, there is no uploader as they are auto-generated
return false;
}
return hasArtistOrVerifiedIconBadgeAttachment(
firstMetadataRow.getArray("metadataParts")
.getObject(0)
.getObject("text")
.getArray("attachmentRuns"));
}
@Override
public long getStreamCount() throws ParsingException {
if (playlistType != PlaylistInfo.PlaylistType.NORMAL) {
// If the playlist is a mix, we are not able to get its stream count
return ListExtractor.ITEM_COUNT_INFINITE;
}
try {
return Long.parseLong(Utils.removeNonDigitCharacters(
thumbnailViewModel.getArray("overlays")
.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.filter(overlay -> overlay.has("thumbnailOverlayBadgeViewModel"))
.findFirst()
.orElseThrow(() -> new ParsingException(
"Could not get thumbnailOverlayBadgeViewModel"))
.getObject("thumbnailOverlayBadgeViewModel")
.getArray("thumbnailBadges")
.stream()
.filter(JsonObject.class::isInstance)
.map(JsonObject.class::cast)
.filter(badge -> badge.has("thumbnailBadgeViewModel"))
.findFirst()
.orElseThrow(() ->
new ParsingException("Could not get thumbnailBadgeViewModel"))
.getObject("thumbnailBadgeViewModel")
.getString("text")));
} catch (final Exception e) {
throw new ParsingException("Could not get playlist stream count", e);
}
}
@Override
public String getName() throws ParsingException {
return lockupMetadataViewModel.getObject("title")
.getString("content");
}
@Override
public String getUrl() throws ParsingException {
// If the playlist item is a mix, we cannot return just its playlist ID as mix playlists
// are not viewable in playlist pages
// Use directly getUrlFromNavigationEndpoint in this case, which returns the watch URL with
// the mix playlist
if (playlistType == PlaylistInfo.PlaylistType.NORMAL) {
try {
return YoutubePlaylistLinkHandlerFactory.getInstance().getUrl(getPlaylistId());
} catch (final Exception ignored) {
}
}
return getUrlFromNavigationEndpoint(lockupViewModel.getObject("rendererContext")
.getObject("commandContext")
.getObject("onTap")
.getObject("innertubeCommand"));
}
@Nonnull
@Override
public List<Image> getThumbnails() throws ParsingException {
return getImagesFromThumbnailsArray(thumbnailViewModel.getObject("image")
.getArray("sources"));
}
@Nonnull
@Override
public PlaylistInfo.PlaylistType getPlaylistType() throws ParsingException {
return playlistType;
}
private String getPlaylistId() throws ParsingException {
String id = lockupViewModel.getString("contentId");
if (Utils.isNullOrEmpty(id)) {
id = lockupViewModel.getObject("rendererContext")
.getObject("commandContext")
.getObject("watchEndpoint")
.getString("playlistId");
}
if (Utils.isNullOrEmpty(id)) {
throw new ParsingException("Could not get playlist ID");
}
return id;
}
}

View File

@ -20,13 +20,19 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* A {@link StreamInfoItemExtractor} for YouTube's {@code reelItemRenderers}.
* A {@link StreamInfoItemExtractor} for YouTube's {@code reelItemRenderer}s.
*
* <p>
* {@code reelItemRenderers} are returned on YouTube for their short-form contents on almost every
* {@code reelItemRenderer}s were returned on YouTube for their short-form contents on almost every
* place and every major client. They provide a limited amount of information and do not provide
* the exact view count, any uploader info (name, URL, avatar, verified status) and the upload date.
* </p>
*
* <p>
* At the time this documentation has been updated, they are being replaced by
* {@code shortsLockupViewModel}s. See {@link YoutubeShortsLockupInfoItemExtractor} for an
* extractor for this new UI data type.
* </p>
*/
public class YoutubeReelInfoItemExtractor implements StreamInfoItemExtractor {

View File

@ -245,6 +245,13 @@ public class YoutubeSearchExtractor extends SearchExtractor {
} else if (item.has("showRenderer")) {
collector.commit(new YoutubeShowRendererInfoItemExtractor(
item.getObject("showRenderer")));
} else if (item.has("lockupViewModel")) {
final JsonObject lockupViewModel = item.getObject("lockupViewModel");
if ("LOCKUP_CONTENT_TYPE_PLAYLIST".equals(
lockupViewModel.getString("contentType"))) {
collector.commit(
new YoutubeMixOrPlaylistLockupInfoItemExtractor(lockupViewModel));
}
}
}
}

View File

@ -0,0 +1,150 @@
package org.schabi.newpipe.extractor.services.youtube.extractors;
import com.grack.nanojson.JsonObject;
import org.schabi.newpipe.extractor.Image;
import org.schabi.newpipe.extractor.exceptions.ParsingException;
import org.schabi.newpipe.extractor.localization.DateWrapper;
import org.schabi.newpipe.extractor.services.youtube.linkHandler.YoutubeStreamLinkHandlerFactory;
import org.schabi.newpipe.extractor.stream.StreamInfoItemExtractor;
import org.schabi.newpipe.extractor.stream.StreamType;
import org.schabi.newpipe.extractor.utils.Utils;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import static org.schabi.newpipe.extractor.services.youtube.YoutubeParsingHelper.getImagesFromThumbnailsArray;
import static org.schabi.newpipe.extractor.utils.Utils.isNullOrEmpty;
/**
* A {@link StreamInfoItemExtractor} for YouTube's {@code shortsLockupViewModel}s.
*
* <p>
* {@code shortsLockupViewModel}s are returned on YouTube for their short-form contents on almost
* every place and every major client. They provide a limited amount of information and do not
* provide the exact view count, any uploader info (name, URL, avatar, verified status) and the
* upload date.
* </p>
*
* <p>
* At the time this documentation has been written, this data UI type is not fully used (rolled
* out), so {@code reelItemRenderer}s are also returned. See {@link YoutubeReelInfoItemExtractor}
* for an extractor for this UI data type.
* </p>
*/
public class YoutubeShortsLockupInfoItemExtractor implements StreamInfoItemExtractor {
@Nonnull
private final JsonObject shortsLockupViewModel;
public YoutubeShortsLockupInfoItemExtractor(@Nonnull final JsonObject shortsLockupViewModel) {
this.shortsLockupViewModel = shortsLockupViewModel;
}
@Override
public String getName() throws ParsingException {
return shortsLockupViewModel.getObject("overlayMetadata")
.getObject("primaryText")
.getString("content");
}
@Override
public String getUrl() throws ParsingException {
String videoId = shortsLockupViewModel.getObject("onTap")
.getObject("innertubeCommand")
.getObject("reelWatchEndpoint")
.getString("videoId");
if (isNullOrEmpty(videoId)) {
videoId = shortsLockupViewModel.getObject("inlinePlayerData")
.getObject("onVisible")
.getObject("innertubeCommand")
.getObject("watchEndpoint")
.getString("videoId");
}
if (isNullOrEmpty(videoId)) {
throw new ParsingException("Could not get video ID");
}
try {
return YoutubeStreamLinkHandlerFactory.getInstance().getUrl(videoId);
} catch (final Exception e) {
throw new ParsingException("Could not get URL", e);
}
}
@Nonnull
@Override
public List<Image> getThumbnails() throws ParsingException {
return getImagesFromThumbnailsArray(shortsLockupViewModel.getObject("thumbnail")
.getArray("sources"));
}
@Override
public StreamType getStreamType() throws ParsingException {
return StreamType.VIDEO_STREAM;
}
@Override
public long getViewCount() throws ParsingException {
final String viewCountText = shortsLockupViewModel.getObject("overlayMetadata")
.getObject("secondaryText")
.getString("content");
if (!isNullOrEmpty(viewCountText)) {
// This approach is language dependent
if (viewCountText.toLowerCase().contains("no views")) {
return 0;
}
return Utils.mixedNumberWordToLong(viewCountText);
}
throw new ParsingException("Could not get short view count");
}
@Override
public boolean isShortFormContent() {
return true;
}
// All the following properties cannot be obtained from shortsLockupViewModels
@Override
public boolean isAd() throws ParsingException {
return false;
}
@Override
public long getDuration() throws ParsingException {
return -1;
}
@Override
public String getUploaderName() throws ParsingException {
return null;
}
@Override
public String getUploaderUrl() throws ParsingException {
return null;
}
@Override
public boolean isUploaderVerified() throws ParsingException {
return false;
}
@Nullable
@Override
public String getTextualUploadDate() throws ParsingException {
return null;
}
@Nullable
@Override
public DateWrapper getUploadDate() throws ParsingException {
return null;
}
}

View File

@ -726,6 +726,13 @@ public class YoutubeStreamExtractor extends StreamExtractor {
} else if (result.has("compactPlaylistRenderer")) {
return new YoutubeMixOrPlaylistInfoItemExtractor(
result.getObject("compactPlaylistRenderer"));
} else if (result.has("lockupViewModel")) {
final JsonObject lockupViewModel = result.getObject("lockupViewModel");
if ("LOCKUP_CONTENT_TYPE_PLAYLIST".equals(
lockupViewModel.getString("contentType"))) {
return new YoutubeMixOrPlaylistLockupInfoItemExtractor(
lockupViewModel);
}
}
return null;
})
@ -1377,6 +1384,20 @@ public class YoutubeStreamExtractor extends StreamExtractor {
return itagInfo;
}
/**
* {@inheritDoc}
* Should return a list of Frameset object that contains preview of stream frames
*
* <p><b>Warning:</b> When using this method be aware
* that the YouTube API very rarely returns framesets,
* that are slightly too small e.g. framesPerPageX = 5, frameWidth = 160, but the url contains
* a storyboard that is only 795 pixels wide (5*160 &gt; 795). You will need to handle this
* "manually" to avoid errors.</p>
*
* @see <a href="https://github.com/TeamNewPipe/NewPipe/pull/11596">
* TeamNewPipe/NewPipe#11596</a>
*/
@Nonnull
@Override
public List<Frameset> getFrames() throws ExtractionException {

View File

@ -1,12 +1,13 @@
package org.schabi.newpipe.extractor.stream;
/**
* An enum representing the track type of an {@link AudioStream} extracted by a {@link
* An enum representing the track type of {@link AudioStream}s extracted by a {@link
* StreamExtractor}.
*/
public enum AudioTrackType {
/**
* An original audio track of the video.
* An original audio track of a video.
*/
ORIGINAL,
@ -20,6 +21,7 @@ public enum AudioTrackType {
/**
* A descriptive audio track.
*
* <p>
* A descriptive audio track is an audio track in which descriptions of visual elements of
* a video are added to the original audio, with the goal to make a video more accessible to
@ -29,5 +31,15 @@ public enum AudioTrackType {
* @see <a href="https://en.wikipedia.org/wiki/Audio_description">
* https://en.wikipedia.org/wiki/Audio_description</a>
*/
DESCRIPTIVE
DESCRIPTIVE,
/**
* A secondary audio track.
*
* <p>
* A secondary audio track can be an alternate audio track from the original language of a
* video or an alternate language.
* </p>
*/
SECONDARY
}

View File

@ -18,8 +18,11 @@ import okhttp3.RequestBody;
import okhttp3.ResponseBody;
public final class DownloaderTestImpl extends Downloader {
/**
* Should be the latest Firefox ESR version.
*/
private static final String USER_AGENT
= "Mozilla/5.0 (Windows NT 10.0; rv:91.0) Gecko/20100101 Firefox/91.0";
= "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0";
private static DownloaderTestImpl instance;
private final OkHttpClient client;

View File

@ -15,6 +15,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;
import javax.annotation.Nonnull;
@ -37,17 +38,31 @@ import javax.annotation.Nonnull;
*/
class RecordingDownloader extends Downloader {
public final static String FILE_NAME_PREFIX = "generated_mock_";
public static final String FILE_NAME_PREFIX = "generated_mock_";
// From https://stackoverflow.com/a/15875500/13516981
private final static String IP_V4_PATTERN =
private static final String IP_V4_PATTERN =
"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";
private int index = 0;
private final String path;
// try to prevent ReCaptchaExceptions / rate limits by tracking and throttling the requests
/**
* Creates the folder described by {@code stringPath} if it does not exists.
* The maximum number of requests per 20 seconds which are executed
* by the {@link RecordingDownloader}.
* 20 seconds is used as upper bound because the rate limit can be triggered within 30 seconds
* and hitting the rate limit should be prevented because it comes with a bigger delay.
* The values can be adjusted when executing the downloader and running into problems.
* <p>TODO: Allow adjusting the value by setting a param in the gradle command</p>
*/
private static final int MAX_REQUESTS_PER_20_SECONDS = 30;
private static final long[] requestTimes = new long[MAX_REQUESTS_PER_20_SECONDS];
private static int requestTimesCursor = -1;
private static final Random throttleRandom = new Random();
/**
* Creates the folder described by {@code stringPath} if it does not exist.
* Deletes existing files starting with {@link RecordingDownloader#FILE_NAME_PREFIX}.
* @param stringPath Path to the folder where the json files will be saved to.
*/
@ -69,6 +84,48 @@ class RecordingDownloader extends Downloader {
@Override
public Response execute(@Nonnull final Request request) throws IOException,
ReCaptchaException {
// Delay the execution if the max number of requests per minute is reached
final long currentTime = System.currentTimeMillis();
// the cursor points to the latest request time and the next position is the oldest one
final int oldestRequestTimeCursor = (requestTimesCursor + 1) % requestTimes.length;
final long oldestRequestTime = requestTimes[oldestRequestTimeCursor];
if (oldestRequestTime + 20_000 >= currentTime) {
try {
// sleep at least until the oldest request is 20s old, but not more than 20s
final int minSleepTime = (int) (currentTime - oldestRequestTime);
Thread.sleep(minSleepTime + throttleRandom.nextInt(20_000 - minSleepTime));
} catch (InterruptedException e) {
// handle the exception gracefully because it's not critical for the test
System.err.println("Error while throttling the RecordingDownloader.");
e.printStackTrace();
}
}
requestTimesCursor = oldestRequestTimeCursor; // the oldest value needs to be overridden
requestTimes[requestTimesCursor] = System.currentTimeMillis();
// Handle ReCaptchaExceptions by retrying the request once after a while
try {
return executeRequest(request);
} catch (ReCaptchaException e) {
try {
// sleep for 35-60 seconds to circumvent the rate limit
System.out.println("Throttling the RecordingDownloader to handle a ReCaptcha."
+ " Sleeping for 35-60 seconds.");
Thread.sleep(35_000 + throttleRandom.nextInt(25_000));
} catch (InterruptedException ie) {
// handle the exception gracefully because it's not critical for the test
System.err.println("Error while throttling the RecordingDownloader.");
ie.printStackTrace();
e.printStackTrace();
}
return executeRequest(request);
}
}
@Nonnull
private Response executeRequest(@Nonnull final Request request) throws IOException,
ReCaptchaException {
final Downloader downloader = DownloaderTestImpl.getInstance();
Response response = downloader.execute(request);
String cleanedResponseBody = response.responseBody().replaceAll(IP_V4_PATTERN, "127.0.0.1");

View File

@ -234,4 +234,111 @@ public class PeertubeChannelExtractorTest {
assertTrue(extractor.getTags().isEmpty());
}
}
public static class DocumentaryChannel implements BaseChannelExtractorTest {
// https://github.com/TeamNewPipe/NewPipe/issues/11369
private static PeertubeChannelExtractor extractor;
@BeforeAll
public static void setUp() throws Exception {
NewPipe.init(DownloaderTestImpl.getInstance());
// setting instance might break test when running in parallel
PeerTube.setInstance(new PeertubeInstance("https://kolektiva.media", "kolektiva.media"));
extractor = (PeertubeChannelExtractor) PeerTube
.getChannelExtractor("https://kolektiva.media/video-channels/documentary_channel");
extractor.fetchPage();
}
/*//////////////////////////////////////////////////////////////////////////
// Extractor
//////////////////////////////////////////////////////////////////////////*/
@Test
public void testServiceId() {
assertEquals(PeerTube.getServiceId(), extractor.getServiceId());
}
@Test
public void testName() throws ParsingException {
assertEquals("Documentary Channel", extractor.getName());
}
@Test
public void testId() throws ParsingException {
assertEquals("video-channels/documentary_channel", extractor.getId());
}
@Test
public void testUrl() throws ParsingException {
assertEquals("https://kolektiva.media/video-channels/documentary_channel", extractor.getUrl());
}
@Test
public void testOriginalUrl() throws ParsingException {
assertEquals("https://kolektiva.media/video-channels/documentary_channel", extractor.getOriginalUrl());
}
/*//////////////////////////////////////////////////////////////////////////
// ChannelExtractor
//////////////////////////////////////////////////////////////////////////*/
@Test
public void testDescription() {
assertNotNull(extractor.getDescription());
}
@Test
void testParentChannelName() throws ParsingException {
assertEquals("consumedmind", extractor.getParentChannelName());
}
@Test
void testParentChannelUrl() throws ParsingException {
assertEquals("https://kolektiva.media/accounts/consumedmind", extractor.getParentChannelUrl());
}
@Test
void testParentChannelAvatars() {
defaultTestImageCollection(extractor.getParentChannelAvatars());
}
@Test
public void testAvatars() {
defaultTestImageCollection(extractor.getAvatars());
}
@Test
public void testBanners() throws ParsingException {
assertGreaterOrEqual(1, extractor.getBanners().size());
}
@Test
public void testFeedUrl() throws ParsingException {
assertEquals("https://kolektiva.media/feeds/videos.xml?videoChannelId=2994", extractor.getFeedUrl());
}
@Test
public void testSubscriberCount() {
assertGreaterOrEqual(25, extractor.getSubscriberCount());
}
@Test
@Override
public void testVerified() throws Exception {
assertFalse(extractor.isVerified());
}
@Test
@Override
public void testTabs() throws Exception {
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
}
@Test
@Override
public void testTags() throws Exception {
assertTrue(extractor.getTags().isEmpty());
}
}
}

View File

@ -33,6 +33,7 @@ public class PeertubeChannelLinkHandlerFactoryTest {
assertTrue(linkHandler.acceptUrl("https://peertube.stream/video-channels/kranti_channel@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/videos"));
assertTrue(linkHandler.acceptUrl("https://peertube.stream/api/v1/video-channels/7682d9f2-07be-4622-862e-93ec812e2ffa"));
assertTrue(linkHandler.acceptUrl("https://kolektiva.media/video-channels/documentary_channel"));
assertDoNotAcceptNonURLs(linkHandler);
}
@ -60,6 +61,16 @@ public class PeertubeChannelLinkHandlerFactoryTest {
linkHandler.fromUrl("https://peertube.stream/c/kranti_channel@videos.squat.net/video-playlists").getId());
assertEquals("video-channels/kranti_channel@videos.squat.net",
linkHandler.fromUrl("https://peertube.stream/api/v1/video-channels/kranti_channel@videos.squat.net").getId());
// instance URL ending with an "a": https://kolektiva.media
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/video-channels/documentary_channel/videos").getId());
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/c/documentary_channel/videos").getId());
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/c/documentary_channel/video-playlists").getId());
assertEquals("video-channels/documentary_channel",
linkHandler.fromUrl("https://kolektiva.media/api/v1/video-channels/documentary_channel").getId());
}
@Test

View File

@ -49,7 +49,7 @@ public class SoundcloudStreamExtractorTest {
@Override public StreamExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return SoundCloud; }
@Override public String expectedName() { return "Jess Glynne & Jax Jones - One Touch"; }
@Override public String expectedName() { return "One Touch"; }
@Override public String expectedId() { return "621612588"; }
@Override public String expectedUrlContains() { return UPLOADER + "/" + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }

View File

@ -232,8 +232,7 @@ public class YoutubeChannelExtractorTest {
@Test
@Override
public void testTabs() throws Exception {
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS,
ChannelTabs.LIVESTREAMS, ChannelTabs.PLAYLISTS);
assertTabsContain(extractor.getTabs(), ChannelTabs.VIDEOS, ChannelTabs.PLAYLISTS);
assertTrue(extractor.getTabs().stream()
.filter(it -> ChannelTabs.VIDEOS.equals(it.getContentFilters().get(0)))
.allMatch(ReadyChannelTabListLinkHandler.class::isInstance));

View File

@ -40,7 +40,7 @@ public class YoutubeStreamExtractorLivestreamTest extends DefaultStreamExtractor
@Override public StreamExtractor extractor() { return extractor; }
@Override public StreamingService expectedService() { return YouTube; }
@Override public String expectedName() { return "lofi hip hop radio \uD83D\uDCDA - beats to relax/study to"; }
@Override public String expectedName() { return "lofi hip hop radio \uD83D\uDCDA beats to relax/study to"; }
@Override public String expectedId() { return ID; }
@Override public String expectedUrlContains() { return YoutubeStreamExtractorDefaultTest.BASE_URL + ID; }
@Override public String expectedOriginalUrlContains() { return URL; }

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 18:09:57 GMT"
"Sun, 10 Nov 2024 17:54:30 GMT"
],
"expires": [
"Thu, 18 Jul 2024 18:09:57 GMT"
"Sun, 10 Nov 2024 17:54:30 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dAc2NF4wLV18; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 18:09:57 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003da4d0v1pvpMk; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:54:30 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:47:54 GMT"
"Sun, 10 Nov 2024 17:47:59 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:47:54 GMT"
"Sun, 10 Nov 2024 17:47:59 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dQ-hpT9jfKtU; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:47:54 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dj9_R69devYo; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:47:59 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -13,7 +13,7 @@
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -362,7 +362,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:47:56 GMT"
"Sun, 10 Nov 2024 17:48:19 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -382,7 +382,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtzVEVQR1dURHphWSjMquW0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgGA%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xd625b21ac0ea5a53\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23703445,23804281,23946420,23966208,23986028,23998056,24004644,24077241,24166867,24181174,24241378,24290971,24439361,24453989,24456089,24468724,24499533,24542367,24548627,24548629,24550458,24566687,24690004,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51030101,51037346,51037353,51041512,51050361,51053689,51057848,51057851,51060353,51063643,51064835,51072748,51091058,51091331,51095478,51098297,51098299,51102410,51105630,51111738,51113658,51113661,51115184,51116067,51117319,51118932,51121939,51124104,51133103,51139379,51141472,51148688,51148974,51148983,51149607,51150450,51152050,51157411,51157430,51157432,51157838,51158470,51158514,51160545,51162170,51163635,51165467,51165568,51169117,51170249,51172670,51172684,51172691,51172700,51172707,51172716,51172723,51172728,51173021,51173508,51175606,51176511,51178310,51178333,51178340,51178357,51178706,51178982,51182275,51183508,51183909,51184022,51184990,51186528,51186670,51189826,51190059,51190075,51190078,51190085,51190198,51190213,51190220,51190229,51190652,51193591,51194137,51195231,51196476,51196769,51197569,51197687,51197694,51197697,51197708,51199193,51200251,51200256,51200295,51200298,51200568,51201350,51201363,51201372,51201381,51201428,51201435,51201444,51201451,51201814,51203141,51203200,51204329,51204587,51204938,51207174,51207191,51207196,51207209,51209172,51210770,51211461,51212464,51212553,51212567,51213807,51217504,51219800,51221011,51221152,51222152,51222695,51223962,51224134,51224747,51224922,51225437,51226344,51227408,51227772,51227881,51227902,51228202,51228349,51228351,51228695,51228771,51228776,51228787,51228796,51228805,51228814,51229628,51230124,51230423,51230478,51230492,51232125,51232143,51232230,51233332,51235147,51237540,51238400,51238514,51238569,51238736,51240880,51240888,51241028,51241600\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIusK-7pKxhwMVBDPxBR08yQnhMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UC6nSFpj9HTCZ5t-N3Rm3-HA\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"Cgt2SjhfUUx2UnFmayjj48O5BjIKCgJERRIEEgAgRQ%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x3a41c164850da49a\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"9406121,23804281,23880829,23880835,23966208,23986021,24004644,24077241,24166867,24181174,24241378,24299873,24439361,24445497,24453989,24459436,24542367,24547317,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51030101,51037344,51037351,51050361,51053689,51057844,51057851,51063643,51064835,51072748,51091058,51095478,51098299,51101169,51111738,51115184,51117319,51124104,51129210,51133103,51134507,51141472,51144925,51151423,51152050,51156055,51157411,51157841,51158514,51160545,51165467,51169118,51176511,51178310,51178331,51178344,51178355,51178982,51182851,51183909,51184990,51194137,51195231,51204329,51213773,51217504,51221150,51222382,51222973,51223961,51226709,51227037,51227778,51228350,51230241,51230478,51231220,51231814,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51249749,51251836,51255676,51255680,51255743,51256074,51256084,51257900,51257911,51257916,51258066,51259133,51260456,51263449,51265335,51265364,51265369,51266454,51272458,51273608,51274583,51275782,51276557,51276565,51281227,51282069,51282086,51282792,51283950,51284503,51285052,51285417,51285717,51287196,51287500,51289926,51289935,51289938,51289952,51289961,51289970,51290043,51291889,51294322,51295132,51295578,51296439,51298019,51298020,51299154,51299710,51299724,51299977,51299999,51300010,51300176,51300241,51300699,51302492,51302680,51303667,51303669,51303789,51304004,51304155,51305839,51306259,51307502,51308045,51308060,51308871,51309313,51310323,51311031,51311034,51311505,51311520,51312150,51312688,51313149,51313767,51314158,51314669,51314681,51314692,51314699,51314710,51314727,51315041,51315914,51315919,51315926,51315935,51315940,51315949,51315956,51315963,51315968,51315979,51316415,51316749,51317749,51318845,51320778,51323366,51325576,51326208,51326527,51326641,51326762,51326932,51327144,51327165,51327178,51327614,51327636,51328144,51329146,51329227,51329392,51329506,51330194,51330660,51331481,51331500,51331522,51331531,51331538,51331547,51331554,51331561,51332896,51333739,51333878,51335364,51335570,51335973,51336632,51337186,51337349,51337702,51338495,51338524,51339163,51339747,51340618,51341226,51341729,51342093,51342576,51342845,51343110,51343368,51344672,51344926,51345126,51345228\"},{\"key\":\"visitor_data\",\"value\":\"Cgt2SjhfUUx2UnFmayjj48O5BjIKCgJERRIEEgAgRQ%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIxIjKt6nSiQMVJEF6BR10IyrwMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UC6nSFpj9HTCZ5t-N3Rm3-HA\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:49:35 GMT"
"Sun, 10 Nov 2024 17:46:56 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:49:35 GMT"
"Sun, 10 Nov 2024 17:46:56 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dZHHPT-DrXJQ; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:49:35 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dHEqrYtop-08; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:46:56 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:48:47 GMT"
"Sun, 10 Nov 2024 17:46:57 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:48:47 GMT"
"Sun, 10 Nov 2024 17:46:57 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003d9_8OVS-ITHc; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:48:47 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dw-_Feucl-TI; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:46:57 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,17 +3,17 @@
"httpMethod": "POST",
"url": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Cookie": [
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -374,7 +374,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:48:48 GMT"
"Sun, 10 Nov 2024 17:46:57 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -394,7 +394,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtiVTZPVEtWdkUtayiAq-W0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgMg%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xe140936d506561d9\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23946420,23966208,23986015,23998056,24004644,24077241,24108448,24166867,24181174,24241378,24290971,24439361,24453989,24456089,24468724,24542367,24543669,24548627,24548629,24550458,24566687,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51030101,51037342,51037349,51041512,51050361,51053689,51057846,51057851,51060353,51063643,51064835,51072748,51087998,51091058,51091331,51095478,51098297,51098299,51102409,51111738,51113656,51113663,51115184,51116067,51118932,51124104,51126280,51131738,51133103,51139379,51141472,51144926,51148688,51148978,51148985,51149422,51149607,51150448,51152050,51153490,51157411,51157430,51157432,51157838,51157895,51158470,51158514,51160545,51160817,51162170,51163641,51165467,51165568,51170247,51172670,51172686,51172691,51172702,51172705,51172716,51172721,51172730,51173021,51175606,51176511,51177817,51178310,51178331,51178348,51178355,51178706,51178982,51182275,51183910,51184022,51184990,51186528,51186669,51186752,51189826,51190059,51190073,51190082,51190085,51190200,51190209,51190216,51190231,51190652,51195231,51196476,51196769,51197685,51197694,51197697,51197704,51199193,51199719,51200184,51200249,51200260,51200295,51200300,51200568,51201352,51201367,51201372,51201383,51201426,51201437,51201442,51201447,51201814,51203200,51204329,51204585,51207178,51207187,51207200,51207215,51211461,51212466,51212545,51212551,51212567,51213714,51213807,51213887,51217504,51219800,51221011,51221152,51222759,51222972,51223961,51224134,51224655,51224747,51224921,51225437,51226344,51226709,51227410,51227776,51227880,51227902,51228202,51228349,51228352,51228695,51228769,51228774,51228785,51228800,51228809,51228818,51229233,51230123,51230477,51230492,51231813,51232109,51232143,51236268,51237540,51237884,51238568,51238737,51240880,51240890,51241028,51241658,51241862\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMImfCdh5OxhwMVgEtPBB1-bw1fMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCEOXxzW2vU0P-0THehuIIeg\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtZNC1HTkNITGlOYyiR48O5BjIKCgJERRIEEgAgRg%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x89e1c78312cedec5\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23966208,23986027,24004644,24077241,24108448,24166867,24181174,24186125,24241378,24299875,24439361,24453989,24459436,24502053,24542367,24547316,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51030101,51037346,51037351,51043774,51050361,51053689,51057848,51057851,51063643,51064835,51072748,51091058,51095478,51098299,51111738,51115184,51117319,51119595,51124104,51129210,51133103,51134507,51141472,51152050,51157411,51157841,51158514,51160545,51165467,51169118,51176511,51178316,51178335,51178342,51178351,51178982,51182850,51183910,51184990,51195231,51204329,51213773,51217504,51221152,51222382,51222973,51223961,51225391,51227037,51227772,51228350,51230241,51230478,51231814,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51251836,51255676,51255680,51255743,51256074,51256084,51257563,51257904,51257911,51257914,51258066,51258612,51263448,51265335,51265362,51265367,51266454,51272458,51273608,51274583,51275785,51276557,51276565,51277311,51281227,51282071,51282082,51282792,51285052,51285419,51285717,51287196,51287500,51289922,51289935,51289938,51289952,51289963,51289972,51291319,51292055,51294322,51294589,51294590,51295132,51295578,51296439,51298019,51298021,51299626,51299710,51299724,51299977,51300005,51300018,51300176,51300241,51300699,51302492,51302680,51303667,51303669,51303789,51304155,51305032,51305494,51305691,51305839,51306259,51306545,51307502,51308045,51308060,51309313,51310323,51310742,51311025,51311038,51311147,51311505,51312144,51312688,51312880,51313149,51313767,51314158,51314679,51314694,51314701,51314710,51314729,51315041,51315910,51315921,51315926,51315931,51315940,51315945,51315954,51315959,51315972,51315977,51316747,51317748,51318844,51321167,51322670,51323366,51325576,51326208,51326233,51326527,51326641,51326767,51326932,51327144,51327163,51327178,51327636,51328144,51328948,51329227,51329505,51330194,51330662,51331198,51331487,51331502,51331518,51331535,51331538,51331547,51331552,51331563,51331691,51332896,51333739,51333878,51335646,51337187,51337350,51337854,51338523,51339163,51339517,51339747,51340616,51341226,51341757,51342093,51342468,51342740,51343110,51343368,51344663,51344727,51345228\"},{\"key\":\"visitor_data\",\"value\":\"CgtZNC1HTkNITGlOYyiR48O5BjIKCgJERRIEEgAgRg%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIuqqokKnSiQMVcWh6BR08NAEDMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCEOXxzW2vU0P-0THehuIIeg\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027;report-uri /cspreport"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:49:19 GMT"
"Sun, 10 Nov 2024 17:46:57 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:49:19 GMT"
"Sun, 10 Nov 2024 17:46:57 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dauHnMsX2TkQ; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:49:19 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dDum5dtfP5VQ; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:46:57 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:47:35 GMT"
"Sun, 10 Nov 2024 17:46:59 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:47:35 GMT"
"Sun, 10 Nov 2024 17:46:59 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003doTOG10oOeIY; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:47:35 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003deZhZw_X0aHw; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:46:59 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -13,7 +13,7 @@
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -358,7 +358,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:47:36 GMT"
"Sun, 10 Nov 2024 17:47:05 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -378,7 +378,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"Cgt2Rm1wQklIYlhmVSi4quW0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgUQ%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x5b4ab0a81ff46292\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"9479112,23804281,23946420,23966208,23986033,23998056,24004644,24077241,24135942,24166867,24181174,24241378,24290971,24299873,24425061,24439361,24453989,24456089,24468724,24542367,24548627,24548629,24550458,24566687,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51030103,51037342,51037353,51041512,51043554,51043998,51050361,51053689,51057844,51057851,51057863,51060353,51063643,51064835,51072748,51091058,51091331,51095478,51098297,51098299,51101170,51102409,51105628,51111738,51113658,51113661,51115184,51116067,51117318,51118932,51120721,51124104,51133103,51139379,51141472,51148037,51148688,51148978,51148981,51149607,51152050,51157411,51157430,51157432,51157838,51158470,51158514,51160545,51162170,51163637,51165467,51165568,51170247,51172670,51172686,51172693,51172700,51172709,51172712,51172719,51172726,51175606,51176511,51177818,51178297,51178310,51178344,51178357,51178705,51178982,51181298,51182274,51183506,51183910,51184022,51184990,51186528,51187251,51189826,51190059,51190071,51190080,51190089,51190202,51190213,51190218,51190229,51190652,51191448,51195231,51196769,51197687,51197692,51197701,51197708,51199193,51200253,51200260,51200293,51200298,51200568,51201350,51201365,51201370,51201383,51201426,51201433,51201442,51201449,51201814,51203112,51204329,51204587,51207182,51207189,51207204,51207207,51211461,51212084,51212458,51212466,51212551,51212569,51213807,51217236,51217504,51219800,51219963,51221011,51221152,51222972,51223961,51224747,51224921,51225437,51226344,51227637,51227774,51227881,51228202,51228350,51228352,51228695,51228771,51228778,51228781,51228800,51228807,51228812,51230122,51230477,51230492,51231131,51231220,51232109,51232143,51232189,51232710,51234853,51235174,51235462,51237540,51237841,51238399,51238569,51238736,51240880,51240886,51241028,51241636,51241644,51242269\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMI3bWR5ZKxhwMVDEFPBB2x_wAnMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCYJ61XIK64sp6ZFFS8sctxw\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtiSkxMTlQ1NjlwOCiZ48O5BjIKCgJERRIEEgAgHQ%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x969100737f7caf2d\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23966208,23986025,24004644,24077241,24166867,24181174,24241378,24420425,24439361,24453989,24542367,24543669,24547317,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51043774,51050361,51053689,51063643,51064835,51072748,51091058,51095478,51098299,51107205,51111738,51115184,51117319,51124104,51129210,51133103,51135270,51141472,51144926,51152050,51157411,51157841,51158514,51160545,51165467,51169118,51176511,51178982,51179884,51182851,51183910,51184990,51195231,51204329,51213773,51217504,51222382,51222973,51223962,51227037,51227291,51228350,51230241,51230478,51230877,51231814,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51249751,51251836,51255676,51255680,51255743,51256074,51256084,51257939,51258066,51263449,51266454,51272458,51273608,51274583,51275782,51276557,51276565,51277535,51281227,51282792,51285052,51285717,51287196,51287500,51287509,51287510,51289938,51294322,51295132,51296439,51298019,51298021,51299627,51299710,51299724,51300176,51300241,51300699,51302492,51302680,51303667,51303669,51303789,51304155,51305032,51305839,51306259,51306416,51307502,51308045,51308060,51309313,51310323,51311505,51312688,51313149,51313767,51314158,51315041,51315245,51316749,51317749,51318845,51320400,51323366,51325523,51325576,51326207,51326641,51326703,51326932,51327636,51328144,51329227,51329506,51330194,51332896,51333739,51333878,51335973,51336056,51337186,51337350,51338524,51339163,51339747,51342093,51343110,51343368,51344412,51344725,51344926\"},{\"key\":\"visitor_data\",\"value\":\"CgtiSkxMTlQ1NjlwOCiZ48O5BjIKCgJERRIEEgAgHQ%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIrZColKnSiQMVD3R6BR3zPDaMMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCYJ61XIK64sp6ZFFS8sctxw\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:49:51 GMT"
"Sun, 10 Nov 2024 17:47:23 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:49:51 GMT"
"Sun, 10 Nov 2024 17:47:23 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dc9wErMbEWpQ; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:49:51 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dTDPINDDje70; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:47:23 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027;report-uri /cspreport"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:48:26 GMT"
"Sun, 10 Nov 2024 17:47:23 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:48:26 GMT"
"Sun, 10 Nov 2024 17:47:23 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dCZ8xidUhzf4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:48:26 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dCwHorxLAtLA; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:47:23 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:50:19 GMT"
"Sun, 10 Nov 2024 17:48:20 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:50:19 GMT"
"Sun, 10 Nov 2024 17:48:20 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003d_U6D2v9w8QE; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:50:19 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dwLNTGYmBqa4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:48:20 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -13,7 +13,7 @@
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -363,7 +363,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:50:21 GMT"
"Sun, 10 Nov 2024 17:48:20 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -383,7 +383,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"Cgt2UFRzSmhuM0J2SSjdq-W0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgVw%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x93cf961e95e44789\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23946420,23966208,23998056,24004644,24017848,24077241,24108447,24166867,24181174,24241378,24290971,24439361,24453989,24456089,24468724,24499533,24534951,24542367,24548627,24548629,24550458,24566687,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51041512,51043555,51050361,51053689,51060353,51063643,51064835,51072748,51091058,51091331,51095478,51098297,51098299,51101170,51102410,51111738,51115184,51116067,51118932,51119595,51124104,51133103,51139379,51141472,51146015,51148688,51149607,51152050,51155997,51157411,51157430,51157432,51157838,51158470,51158514,51160545,51162170,51165467,51165568,51170249,51175606,51176511,51178705,51178982,51183909,51184022,51184990,51185141,51186528,51189826,51190652,51195231,51196180,51196769,51197711,51199193,51200569,51201814,51204329,51204585,51210036,51211461,51213715,51213807,51217504,51219800,51221011,51223961,51224135,51224747,51224921,51225437,51226344,51227881,51228202,51228350,51228352,51228695,51230477,51230492,51232143,51232684,51235463,51236950,51237540,51238568,51238736,51239209,51239303,51241029\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIzZ65s5OxhwMVE0RPBB33uQzmMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCeY0bbntWzzVIaj2z3QigXg\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"Cgt3YnlVWl9pM05IOCjk48O5BjIKCgJERRIEEgAgTw%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x6a6e1d1954f31f83\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23966208,23986015,24000320,24004644,24077241,24166867,24181174,24186125,24216873,24241378,24367823,24425063,24439361,24453989,24499534,24542367,24547317,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51030103,51037346,51037349,51050361,51053689,51057846,51057853,51063643,51064835,51072748,51091058,51095478,51098299,51111738,51115184,51117319,51124104,51129210,51133103,51141472,51144925,51152050,51156055,51157411,51157838,51158514,51160545,51165467,51169118,51176511,51178320,51178327,51178346,51178351,51178982,51179884,51182850,51183910,51184990,51195231,51204329,51213773,51217504,51221152,51222382,51222973,51223962,51227037,51227778,51228350,51230241,51230478,51231814,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51249751,51251836,51255676,51255680,51255743,51256074,51256084,51257900,51257907,51257916,51258066,51263449,51265345,51265358,51265367,51266454,51269139,51272458,51273608,51274583,51275782,51276557,51276565,51281227,51282073,51282088,51282792,51285052,51285419,51285717,51287196,51287500,51287509,51287510,51289484,51289922,51289933,51289938,51289956,51289965,51289970,51290045,51291810,51294322,51294906,51295132,51295578,51296439,51297232,51298019,51298021,51299710,51299724,51299973,51300005,51300018,51300176,51300241,51300699,51302492,51302680,51303666,51303667,51303670,51303789,51304155,51305496,51305839,51306259,51306417,51306559,51306871,51307502,51308045,51308060,51309313,51310323,51310742,51311025,51311036,51311505,51312144,51312688,51313110,51313149,51313767,51314158,51314685,51314696,51314705,51314718,51314727,51315041,51315914,51315919,51315928,51315931,51315942,51315945,51315959,51315972,51315977,51316415,51316749,51316846,51317749,51318243,51318844,51322163,51323366,51323555,51325576,51326207,51326281,51326641,51326652,51326760,51326932,51327122,51327144,51327167,51327182,51327636,51328144,51329227,51329506,51330194,51330316,51330398,51330475,51330662,51331197,51331483,51331504,51331520,51331529,51331538,51331547,51331556,51331563,51332896,51333739,51333879,51335366,51335646,51336660,51337186,51337350,51338524,51339162,51339163,51339747,51341226,51342093,51342575,51342741,51342847,51343109,51343244,51343368,51343866,51344672\"},{\"key\":\"visitor_data\",\"value\":\"Cgt3YnlVWl9pM05IOCjk48O5BjIKCgJERRIEEgAgTw%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIrbDwt6nSiQMVeVp6BR1kviADMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCeY0bbntWzzVIaj2z3QigXg\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:45:17 GMT"
"Sun, 10 Nov 2024 17:47:25 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:45:17 GMT"
"Sun, 10 Nov 2024 17:47:25 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dmt8ojN0j5ss; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:45:17 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003ds2PN637_j94; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:47:25 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,17 +3,17 @@
"httpMethod": "POST",
"url": "https://www.youtube.com/youtubei/v1/browse?prettyPrint\u003dfalse",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Cookie": [
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -255,12 +255,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -376,7 +376,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:45:19 GMT"
"Sun, 10 Nov 2024 17:47:45 GMT"
],
"server": [
"scaffolding on HTTPServer2"

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:49:01 GMT"
"Sun, 10 Nov 2024 17:47:45 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:49:01 GMT"
"Sun, 10 Nov 2024 17:47:45 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dqO-eHy3Kz4k; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:49:01 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dECiwETXt944; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:47:45 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:46:52 GMT"
"Sun, 10 Nov 2024 17:47:46 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:46:52 GMT"
"Sun, 10 Nov 2024 17:47:46 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dCPnrnhg5fno; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:46:52 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dMXNUBrLOj0I; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:47:46 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:52:03 GMT"
"Sun, 10 Nov 2024 17:48:21 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:52:03 GMT"
"Sun, 10 Nov 2024 17:48:21 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dCy4aX6DBam4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:52:03 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003d4hCTcf7rUXA; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:48:21 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:51:50 GMT"
"Sun, 10 Nov 2024 17:48:58 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:51:50 GMT"
"Sun, 10 Nov 2024 17:48:58 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dgoEUVn3I_Gk; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:51:50 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dXTJBIfCZjcU; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:48:58 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,10 +3,10 @@
"httpMethod": "GET",
"url": "https://www.youtube.com/sw.js",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Accept-Language": [
@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:51:38 GMT"
"Sun, 10 Nov 2024 17:49:00 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:51:38 GMT"
"Sun, 10 Nov 2024 17:49:00 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003djgnm7tfpqYw; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:51:38 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dENzmdII1fQw; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:49:00 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -3,17 +3,17 @@
"httpMethod": "POST",
"url": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse",
"headers": {
"Referer": [
"Origin": [
"https://www.youtube.com"
],
"Origin": [
"Referer": [
"https://www.youtube.com"
],
"Cookie": [
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -361,7 +361,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:51:39 GMT"
"Sun, 10 Nov 2024 17:49:00 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -381,7 +381,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"Cgs5WUtfRXZBTXNKWSirrOW0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgEA%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xb264e2e3ad7e95b4\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"9407155,23804281,23946420,23966208,23998056,24004644,24007613,24077241,24108447,24166867,24173288,24181174,24241378,24266634,24290971,24378828,24439361,24453989,24456089,24468724,24499534,24542367,24548627,24548629,24550458,24566687,24697011,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51030101,51037342,51037351,51041512,51050361,51053689,51057842,51057857,51060353,51063643,51064835,51072748,51076858,51091058,51091331,51095478,51098297,51098299,51102410,51111738,51113656,51113663,51115184,51116067,51117318,51118932,51124104,51133103,51139379,51141472,51148688,51148976,51148983,51149607,51152050,51157411,51157430,51157432,51157838,51158470,51158514,51159332,51160545,51162170,51163639,51165467,51165568,51169118,51170248,51172672,51172684,51172695,51172702,51172705,51172712,51172719,51172728,51175606,51176511,51177818,51178318,51178327,51178344,51178351,51178705,51178982,51182274,51183506,51183910,51184022,51184990,51186528,51189826,51190059,51190071,51190080,51190085,51190198,51190211,51190220,51190231,51190652,51191461,51195231,51196181,51196769,51197687,51197694,51197697,51197704,51199193,51200253,51200260,51200291,51200302,51200569,51201350,51201365,51201372,51201383,51201428,51201435,51201442,51201449,51201542,51201814,51202231,51202419,51204329,51204586,51207176,51207187,51207196,51207213,51207302,51211461,51212464,51212555,51212567,51213807,51217504,51218321,51219800,51220610,51221011,51221152,51223962,51224433,51224747,51224922,51225437,51226344,51226707,51227774,51227881,51228202,51228350,51228352,51228695,51228769,51228776,51228781,51228800,51228803,51228812,51229177,51230477,51230492,51231081,51232143,51232191,51232677,51235078,51236658,51237540,51238399,51238568,51238736,51239331,51240880,51240886,51241029\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIupvy2JOxhwMVIj3xBR24uQwtMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCq19-LqvG35A-30oyAiPiqA\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtwN252WUt4bnBCOCiM5MO5BjIKCgJERRIEEgAgKg%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xd104e5d714f830d7\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23966208,23986028,24004644,24077241,24166867,24181174,24186125,24241378,24439361,24453989,24542367,24547316,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51050361,51053689,51063643,51064835,51072748,51091058,51095478,51098299,51111738,51115184,51117319,51119595,51124104,51129210,51133103,51141472,51152050,51157411,51157841,51158514,51160545,51165467,51169118,51176511,51178982,51182851,51183910,51184990,51194136,51195231,51204329,51213773,51217504,51222382,51222973,51223962,51227037,51228350,51228849,51230241,51230478,51231814,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51249749,51251836,51255676,51255680,51255743,51256074,51256084,51258066,51263449,51264008,51266454,51272458,51273608,51274583,51275785,51276557,51276565,51281227,51282792,51285052,51285717,51287196,51287500,51289938,51292055,51294322,51294583,51294584,51295132,51296439,51298019,51298020,51299154,51299710,51299724,51300176,51300241,51300699,51302492,51302680,51303667,51303670,51303789,51304155,51305031,51305558,51305839,51306256,51306870,51307502,51308045,51308060,51308708,51309313,51310323,51310742,51311147,51311505,51312688,51313149,51313767,51314158,51315041,51316438,51316747,51317748,51318844,51319711,51320778,51323366,51325576,51326207,51326641,51326932,51327616,51327636,51328144,51329227,51329505,51330194,51331675,51332896,51333670,51333739,51333879,51335365,51337186,51337349,51337774,51338524,51339163,51339518,51339747,51341342,51342093,51342468,51343109,51343244,51343368,51343866,51344927\"},{\"key\":\"visitor_data\",\"value\":\"CgtwN252WUt4bnBCOCiM5MO5BjIKCgJERRIEEgAgKg%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMI0c70yqnSiQMV9SEGAB3RCT0gMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCq19-LqvG35A-30oyAiPiqA\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:51:17 GMT"
"Sun, 10 Nov 2024 17:49:00 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:51:17 GMT"
"Sun, 10 Nov 2024 17:49:00 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dB7ZQVZteI6U; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:51:17 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dKCR7WRhwlzM; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:49:00 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -13,7 +13,7 @@
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -365,7 +365,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:51:18 GMT"
"Sun, 10 Nov 2024 17:49:05 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -385,7 +385,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtiT1B0Rk1tQkhLVSiWrOW0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgQA%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xacf065d4845918b6\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23885487,23946420,23966208,23986017,23998056,24004644,24077241,24166867,24181174,24241378,24290971,24439361,24453989,24456089,24468724,24499534,24542367,24543669,24548627,24548629,24550458,24566687,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51030103,51037344,51037351,51041512,51043774,51050361,51053689,51057848,51057855,51060353,51063643,51064835,51072748,51091058,51091331,51095478,51098297,51098299,51102409,51111738,51113658,51113663,51114642,51115184,51116067,51117319,51118932,51124104,51129247,51133103,51134506,51139379,51141472,51144925,51148688,51148978,51148985,51149306,51149607,51152050,51153492,51157411,51157430,51157432,51157838,51158470,51158514,51160545,51162170,51163639,51165467,51165568,51170247,51172670,51172688,51172691,51172698,51172709,51172712,51172721,51172726,51173020,51175606,51175619,51176511,51178316,51178327,51178340,51178351,51178705,51178982,51182275,51183909,51184022,51184990,51186528,51187250,51189826,51190061,51190073,51190082,51190085,51190198,51190211,51190216,51190229,51190652,51194136,51195231,51196180,51196769,51197687,51197690,51197701,51197706,51199193,51200051,51200249,51200260,51200291,51200298,51200568,51201350,51201365,51201372,51201381,51201430,51201435,51201440,51201451,51201814,51202232,51204329,51204586,51207174,51207187,51207196,51207209,51208329,51209973,51211461,51212466,51212551,51212569,51213807,51216379,51217504,51217767,51218324,51219800,51220670,51221011,51221146,51223962,51224747,51224922,51225437,51226344,51227395,51227776,51227881,51228202,51228349,51228351,51228695,51228765,51228778,51228783,51228796,51228809,51228816,51230124,51230478,51230492,51231220,51232143,51235371,51235463,51237540,51238569,51238736,51239329,51240878,51240888,51241028,51241192,51241212,51241813,51243005,51243941\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIpef8zpOxhwMVcFBPBB32mQPCMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCR-DXc1voovS8nhAvccRZhg\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtsLVc4aXJYQTRpbyiR5MO5BjIKCgJERRIEEgAgFg%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0x3b0f84f256641642\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23966208,23986016,24004644,24077241,24166867,24181174,24241378,24439361,24453989,24542367,24547316,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51030103,51037346,51037351,51043774,51050361,51053689,51057848,51057851,51063643,51064835,51072748,51091058,51095478,51098299,51111738,51115184,51117319,51124104,51129210,51133103,51141472,51144926,51151423,51152050,51157411,51157841,51158514,51160545,51165467,51169118,51176511,51178316,51178337,51178348,51178353,51178982,51182851,51183909,51184990,51195231,51199253,51204329,51213773,51213887,51217504,51219963,51221152,51222382,51222973,51223961,51227037,51227774,51228350,51230241,51230478,51231814,51237842,51239093,51241028,51242448,51243940,51248255,51248734,51249749,51251836,51255676,51255680,51255743,51256074,51256084,51257895,51257900,51257911,51257918,51258066,51263449,51265339,51265362,51265375,51266454,51268346,51272458,51273608,51274583,51275782,51276557,51276565,51281227,51282075,51282080,51282792,51285052,51285417,51285717,51287196,51287500,51289483,51289924,51289933,51289938,51289956,51289961,51289970,51290204,51291888,51292054,51294322,51295132,51295576,51296439,51298019,51298021,51299519,51299710,51299724,51299979,51299999,51300008,51300176,51300241,51300699,51302492,51302680,51303667,51303669,51303789,51304155,51304660,51304730,51305311,51305839,51306256,51306543,51306559,51307502,51308045,51308060,51308709,51309314,51310323,51310742,51311027,51311036,51311505,51312146,51312688,51312881,51313149,51313767,51314158,51314683,51314696,51314701,51314714,51314729,51315041,51315910,51315921,51315928,51315935,51315942,51315949,51315956,51315963,51315968,51315975,51316174,51316416,51317749,51318074,51318243,51318844,51323366,51325522,51325576,51326207,51326286,51326641,51326932,51327138,51327169,51327182,51327636,51328144,51328902,51329144,51329227,51329506,51329696,51330194,51331487,51331500,51331520,51331531,51331542,51331549,51331556,51331559,51332858,51332896,51333543,51333739,51333878,51336665,51337187,51337349,51337456,51337855,51338470,51338524,51339163,51339747,51340611,51341228,51341729,51342090,51342093,51342298,51342446,51342575,51343109,51343243,51343368,51344663,51344672,51345230\"},{\"key\":\"visitor_data\",\"value\":\"CgtsLVc4aXJYQTRpbyiR5MO5BjIKCgJERRIEEgAgFg%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIm56wzanSiQMVoF96BR37ESIDMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UCR-DXc1voovS8nhAvccRZhg\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Thu, 18 Jul 2024 17:51:07 GMT"
"Sun, 10 Nov 2024 17:49:34 GMT"
],
"expires": [
"Thu, 18 Jul 2024 17:51:07 GMT"
"Sun, 10 Nov 2024 17:49:34 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dw9VR4AUigv4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dFri, 22-Oct-2021 17:51:07 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003dciZmI0rA5B8; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:49:34 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

View File

@ -13,7 +13,7 @@
"SOCS\u003dCAE\u003d"
],
"X-YouTube-Client-Version": [
"2.20240718.01.00"
"2.20241107.11.00"
],
"X-YouTube-Client-Name": [
"1"
@ -229,12 +229,12 @@
48,
50,
52,
49,
49,
48,
55,
49,
56,
46,
48,
49,
49,
46,
48,
@ -359,7 +359,7 @@
"application/json; charset\u003dUTF-8"
],
"date": [
"Thu, 18 Jul 2024 17:51:08 GMT"
"Sun, 10 Nov 2024 17:49:34 GMT"
],
"server": [
"scaffolding on HTTPServer2"
@ -379,7 +379,7 @@
"0"
]
},
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgstcFYyWThEelA2VSiMrOW0BjIiCgJGUhIcEhgSFgsMDg8QERITFBUWFxgZGhscHR4fICEgMg%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20240718.01.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xd3d3538277ffc4e2\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"23804281,23946420,23966208,23986021,23998056,24004644,24077241,24166867,24181174,24241378,24290971,24367823,24439361,24453989,24456089,24457854,24468724,24542367,24548627,24548629,24550458,24566687,24699899,39325854,39326848,39326916,51009781,51010235,51016856,51017346,51020570,51025415,51030103,51037346,51037353,51041512,51050361,51053689,51057842,51057851,51060353,51063643,51064835,51072748,51087997,51091058,51091331,51095478,51098297,51098299,51102409,51111738,51113656,51113663,51115184,51116067,51118932,51124104,51133103,51139379,51141472,51144925,51148688,51148974,51148981,51149607,51152050,51157411,51157430,51157432,51157838,51158470,51158514,51160545,51162170,51163637,51165467,51165568,51169117,51170247,51172670,51172686,51172691,51172702,51172709,51172716,51172723,51172726,51172920,51175606,51176511,51177817,51178320,51178331,51178346,51178351,51178706,51178982,51182275,51183506,51183910,51184022,51184990,51186528,51189826,51190059,51190075,51190078,51190087,51190200,51190209,51190216,51190227,51190652,51195231,51196769,51197685,51197692,51197701,51197704,51199193,51200251,51200256,51200291,51200302,51200569,51201352,51201363,51201370,51201385,51201428,51201435,51201440,51201449,51201814,51203145,51203200,51204329,51204585,51207176,51207187,51207202,51207207,51209049,51211461,51211864,51212464,51212546,51212553,51212567,51213807,51217504,51218324,51219800,51221011,51221150,51222382,51223962,51224747,51224921,51225437,51226344,51226683,51227776,51227880,51227903,51228202,51228349,51228351,51228695,51228765,51228776,51228781,51228796,51228809,51228818,51230123,51230478,51230492,51230886,51231083,51232143,51232189,51232678,51236254,51237540,51238070,51238569,51238736,51239404,51240133,51240878,51240888,51241028,51241645\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20240718\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIyqKHypOxhwMV6YKxAx1bewjjMghleHRlcm5hbJoBAA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UC2DjFE7Xf11URZqWBigcVOQ\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"responseBody": "{\"responseContext\":{\"visitorData\":\"CgtBdGJnQm9rRFhmWSiu5MO5BjIKCgJERRIEEgAgHw%3D%3D\",\"serviceTrackingParams\":[{\"service\":\"CSI\",\"params\":[{\"key\":\"c\",\"value\":\"WEB\"},{\"key\":\"cver\",\"value\":\"2.20241107.11.00\"},{\"key\":\"yt_li\",\"value\":\"0\"},{\"key\":\"ResolveUrl_rid\",\"value\":\"0xd9fdd210611c51cf\"}]},{\"service\":\"GFEEDBACK\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"},{\"key\":\"e\",\"value\":\"9453586,9453587,23804281,23966208,23986016,24004644,24077241,24108447,24166867,24181174,24241378,24439361,24453989,24534952,24542367,24543669,24547316,24548629,24566687,24699899,39325854,39326986,51009781,51010235,51017346,51020570,51025415,51050361,51053689,51063643,51064835,51072748,51091058,51095478,51098299,51101170,51111738,51115184,51117319,51124104,51129210,51133103,51141472,51152050,51157411,51157838,51158514,51160545,51165467,51169118,51176511,51177818,51178982,51182850,51183909,51184990,51195231,51204329,51213773,51217504,51222382,51222973,51223962,51224489,51227037,51228350,51230241,51230478,51231814,51237842,51239093,51239210,51241028,51242448,51243940,51248255,51248734,51251836,51255676,51255680,51255743,51256074,51256084,51258066,51263449,51266454,51272458,51273608,51274583,51275785,51276557,51276565,51281227,51282792,51285052,51285717,51287196,51287500,51289938,51294322,51295132,51296439,51297233,51298019,51298021,51299710,51299724,51300176,51300241,51300699,51302492,51302680,51303665,51303667,51303670,51303789,51304155,51305839,51306259,51307502,51308045,51308060,51309313,51310323,51310742,51311146,51311505,51312688,51313149,51313767,51314158,51315041,51317749,51317787,51318845,51321590,51323366,51325576,51326207,51326282,51326641,51326932,51327636,51328144,51329227,51329505,51330194,51332896,51333739,51333879,51335734,51336160,51337187,51337349,51338440,51338524,51339163,51339518,51339522,51339747,51342093,51343110,51343244,51343368\"},{\"key\":\"visitor_data\",\"value\":\"CgtBdGJnQm9rRFhmWSiu5MO5BjIKCgJERRIEEgAgHw%3D%3D\"}]},{\"service\":\"GUIDED_HELP\",\"params\":[{\"key\":\"logged_in\",\"value\":\"0\"}]},{\"service\":\"ECATCHER\",\"params\":[{\"key\":\"client.version\",\"value\":\"2.20241107\"},{\"key\":\"client.name\",\"value\":\"WEB\"}]}],\"mainAppWebResponseContext\":{\"loggedOut\":true},\"webResponseContextExtensionData\":{\"hasDecorated\":true}},\"endpoint\":{\"clickTrackingParams\":\"IhMIq8CL26nSiQMVkkN6BR0DNTMRMghleHRlcm5hbA\u003d\u003d\",\"commandMetadata\":{\"webCommandMetadata\":{\"url\":\"/youtubei/v1/navigation/resolve_url\",\"webPageType\":\"WEB_PAGE_TYPE_CHANNEL\",\"rootVe\":3611,\"apiUrl\":\"/youtubei/v1/browse\"},\"resolveUrlCommandMetadata\":{\"isVanityUrl\":true}},\"browseEndpoint\":{\"browseId\":\"UC2DjFE7Xf11URZqWBigcVOQ\",\"params\":\"EgC4AQCSAwDyBgQKAjIA\"}}}",
"latestUrl": "https://www.youtube.com/youtubei/v1/navigation/resolve_url?prettyPrint\u003dfalse"
}
}

View File

@ -34,6 +34,9 @@
"cache-control": [
"private, max-age\u003d0"
],
"content-security-policy": [
"require-trusted-types-for \u0027script\u0027;report-uri /cspreport"
],
"content-type": [
"text/javascript; charset\u003dutf-8"
],
@ -41,10 +44,10 @@
"same-origin; report-to\u003d\"youtube_main\""
],
"date": [
"Wed, 24 Jul 2024 17:37:25 GMT"
"Sun, 10 Nov 2024 17:49:34 GMT"
],
"expires": [
"Wed, 24 Jul 2024 17:37:25 GMT"
"Sun, 10 Nov 2024 17:49:34 GMT"
],
"origin-trial": [
"AmhMBR6zCLzDDxpW+HfpP67BqwIknWnyMOXOQGfzYswFmJe+fgaI6XZgAzcxOrzNtP7hEDsOo1jdjFnVr2IdxQ4AAAB4eyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJXZWJWaWV3WFJlcXVlc3RlZFdpdGhEZXByZWNhdGlvbiIsImV4cGlyeSI6MTc1ODA2NzE5OSwiaXNTdWJkb21haW4iOnRydWV9"
@ -62,8 +65,8 @@
"ESF"
],
"set-cookie": [
"YSC\u003dQqImeZ_ECz4; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dThu, 28-Oct-2021 17:37:25 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
"YSC\u003d9-fGwlPnwcs; Domain\u003d.youtube.com; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone",
"VISITOR_INFO1_LIVE\u003d; Domain\u003d.youtube.com; Expires\u003dMon, 14-Feb-2022 17:49:34 GMT; Path\u003d/; Secure; HttpOnly; SameSite\u003dnone"
],
"strict-transport-security": [
"max-age\u003d31536000"

Some files were not shown because too many files have changed in this diff Show More