diff --git a/dist/Simple-YouTube-Age-Restriction-Bypass.user.js b/dist/Simple-YouTube-Age-Restriction-Bypass.user.js
index 7352ec6..1521c19 100644
--- a/dist/Simple-YouTube-Age-Restriction-Bypass.user.js
+++ b/dist/Simple-YouTube-Age-Restriction-Bypass.user.js
@@ -5,7 +5,7 @@
// @description:de Schaue YouTube Videos mit Altersbeschränkungen ohne Anmeldung und ohne dein Alter zu bestätigen :)
// @description:fr Regardez des vidéos YouTube avec des restrictions d'âge sans vous inscrire et sans confirmer votre âge :)
// @description:it Guarda i video con restrizioni di età su YouTube senza login e senza verifica dell'età :)
-// @version 2.4.2
+// @version 2.4.3
// @author Zerody (https://github.com/zerodytrash)
// @namespace https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/
// @supportURL https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/issues
@@ -264,7 +264,7 @@
return sendInnertubeRequest('v1/player', payload, requiresAuth);
}
- function getNext(payload) {
+ function getNext$1(payload) {
return sendInnertubeRequest('v1/next', payload, false);
}
@@ -447,28 +447,35 @@
return VIDEO_PROXY_SERVER_HOST + '/direct/' + btoa(originalUrl);
}
- function getPlayer(payload) {
- const queryParams = new URLSearchParams(payload).toString();
-
- const proxyUrl = ACCOUNT_PROXY_SERVER_HOST + '/getPlayer?' + queryParams;
+ function sendRequest(endpoint, payload) {
+ const queryParams = new URLSearchParams(payload);
+ const proxyUrl = `${ACCOUNT_PROXY_SERVER_HOST}/${endpoint}?${queryParams}`;
try {
const xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', proxyUrl, false);
xmlhttp.send(null);
- const playerResponse = nativeJSONParse(xmlhttp.responseText);
+ const proxyResponse = nativeJSONParse(xmlhttp.responseText);
// mark request as 'proxied'
- playerResponse.proxied = true;
+ proxyResponse.proxied = true;
- return playerResponse;
+ return proxyResponse;
} catch (err) {
error(err);
return { errorMessage: 'Proxy Connection failed' };
}
}
+ function getPlayer(payload) {
+ return sendRequest('getPlayer', payload);
+ }
+
+ function getNext(payload) {
+ return sendRequest('getNext', payload);
+ }
+
var tDesktop = "\n";
var tMobile = "\n \n \n \n\n";
@@ -518,7 +525,7 @@
let lastProxiedGoogleVideoUrlParams;
let cachedPlayerResponse = {};
- function getUnlockStrategies(playerResponse) {var _playerResponse$video, _playerResponse$playa, _playerResponse$previ;
+ function getPlayerUnlockStrategies(playerResponse) {var _playerResponse$video, _playerResponse$playa, _playerResponse$previ;
const videoId = ((_playerResponse$video = playerResponse.videoDetails) === null || _playerResponse$video === void 0 ? void 0 : _playerResponse$video.videoId) || getYtcfgValue('PLAYER_VARS').video_id;
const reason = ((_playerResponse$playa = playerResponse.playabilityStatus) === null || _playerResponse$playa === void 0 ? void 0 : _playerResponse$playa.status) || ((_playerResponse$previ = playerResponse.previewPlayabilityStatus) === null || _playerResponse$previ === void 0 ? void 0 : _playerResponse$previ.status);
const clientName = getYtcfgValue('INNERTUBE_CLIENT_NAME') || 'WEB';
@@ -528,8 +535,9 @@
return [
// Strategy 1: Retrieve the video info by using a age-gate bypass for the innertube API
// Source: https://github.com/yt-dlp/yt-dlp/issues/574#issuecomment-887171136
+ // 2022-02-24: No longer works properly. Sporadic error messages. YouTube seems to fix this.
{
- name: 'Embed',
+ name: 'Client Screen Embed',
requiresAuth: false,
payload: {
context: {
@@ -551,7 +559,32 @@
getPlayer: getPlayer$1 },
- // Strategy 2: Retrieve the video info by using the WEB_CREATOR client in combination with user authentication
+ // Strategy 2: Retrieve the video info by using the WEB_EMBEDDED_PLAYER client
+ // Only usable to bypass login restrictions on a handful of low restricted videos.
+ {
+ name: 'Embedded Player',
+ requiresAuth: false,
+ payload: {
+ context: {
+ client: {
+ clientName: 'WEB_EMBEDDED_PLAYER',
+ clientVersion: '1.20220220.00.00',
+ clientScreen: 'EMBED' },
+
+ thirdParty: {
+ embedUrl: 'https://www.youtube.com/' } },
+
+
+ playbackContext: {
+ contentPlaybackContext: {
+ signatureTimestamp } },
+
+
+ videoId },
+
+ getPlayer: getPlayer$1 },
+
+ // Strategy 3: Retrieve the video info by using the WEB_CREATOR client in combination with user authentication
// See https://github.com/yt-dlp/yt-dlp/pull/600
{
name: 'Creator + Auth',
@@ -575,7 +608,7 @@
getPlayer: getPlayer$1 },
- // Strategy 3: Retrieve the video info from an account proxy server.
+ // Strategy 4: Retrieve the video info from an account proxy server.
// See https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/tree/main/account-proxy
{
name: 'Account Proxy',
@@ -639,7 +672,7 @@
// Check if response is cached
if (cachedPlayerResponse.videoId === videoId) return createDeepCopy(cachedPlayerResponse);
- const unlockStrategies = getUnlockStrategies(playerResponse);
+ const unlockStrategies = getPlayerUnlockStrategies(playerResponse);
let unlockedPlayerResponse;
@@ -648,7 +681,7 @@
// Skip strategy if authentication is required and the user is not logged in
if (strategy.requiresAuth && !isUserLoggedIn()) return true;
- info(`Trying Unlock Method #${index + 1} (${strategy.name})`);
+ info(`Trying Player Unlock Method #${index + 1} (${strategy.name})`);
unlockedPlayerResponse = strategy.getPlayer(strategy.payload, strategy.requiresAuth);
@@ -661,26 +694,50 @@
return unlockedPlayerResponse;
}
- function unlockNextResponse(originalNextResponse) {
- info('Trying sidebar unlock');
+ let cachedNextResponse = {};
- const { videoId } = originalNextResponse.currentVideoEndpoint.watchEndpoint;
- const { clientName, clientVersion } = getYtcfgValue('INNERTUBE_CONTEXT').client;
- const payload = {
- context: {
- client: {
- clientName,
- clientVersion,
- clientScreen: 'EMBED' },
+ function getNextUnlockStrategies(nextResponse) {
+ const videoId = nextResponse.currentVideoEndpoint.watchEndpoint.videoId;
+ const clientName = getYtcfgValue('INNERTUBE_CLIENT_NAME') || 'WEB';
+ const clientVersion = getYtcfgValue('INNERTUBE_CLIENT_VERSION') || '2.20220203.04.00';
- thirdParty: {
- embedUrl: 'https://www.youtube.com/' } },
+ return [
+ // Strategy 1: Retrieve the sidebar and video description by using a age-gate bypass for the innertube API
+ // Source: https://github.com/yt-dlp/yt-dlp/issues/574#issuecomment-887171136
+ {
+ name: 'Embed',
+ payload: {
+ context: {
+ client: {
+ clientName,
+ clientVersion,
+ clientScreen: 'EMBED' },
+
+ thirdParty: {
+ embedUrl: 'https://www.youtube.com/' } },
+
+
+ videoId },
+
+ getNext: getNext$1 },
+
+ // Strategy 2: Retrieve the sidebar and video description from an account proxy server.
+ // See https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass/tree/main/account-proxy
+ {
+ name: 'Account Proxy',
+ payload: {
+ videoId,
+ clientName,
+ clientVersion,
+ isEmbed: +isEmbed },
+ getNext: getNext }];
- videoId };
+ }
- const unlockedNextResponse = getNext(payload);
+ function unlockNextResponse(originalNextResponse) {
+ const unlockedNextResponse = getUnlockedNextResponse(originalNextResponse);
// check if the sidebar of the unlocked response is still empty
if (isWatchNextSidebarEmpty(unlockedNextResponse)) {
@@ -691,6 +748,35 @@
mergeNextResponse(originalNextResponse, unlockedNextResponse);
}
+ function getUnlockedNextResponse(nextResponse) {
+ const videoId = nextResponse.currentVideoEndpoint.watchEndpoint.videoId;
+
+ if (!videoId) {
+ throw new Error(`Missing videoId in nextResponse`);
+ }
+
+ // Check if response is cached
+ if (cachedNextResponse.videoId === videoId) return createDeepCopy(cachedNextResponse);
+
+ const unlockStrategies = getNextUnlockStrategies(nextResponse);
+
+ let unlockedNextResponse;
+
+ // Try every strategy until one of them works
+ unlockStrategies.every((strategy, index) => {
+ info(`Trying Sidebar Unlock Method #${index + 1} (${strategy.name})`);
+
+ unlockedNextResponse = strategy.getNext(strategy.payload);
+
+ return isWatchNextSidebarEmpty(unlockedNextResponse);
+ });
+
+ // Cache response to prevent a flood of requests in case youtube processes a blocked response mutiple times.
+ cachedNextResponse = { videoId, ...createDeepCopy(unlockedNextResponse) };
+
+ return unlockedNextResponse;
+ }
+
function mergeNextResponse(originalNextResponse, unlockedNextResponse) {var _unlockedNextResponse, _unlockedNextResponse2, _unlockedNextResponse3, _unlockedNextResponse4, _unlockedNextResponse5;
if (isDesktop) {
// Transfer WatchNextResults to original response
diff --git a/package-lock.json b/package-lock.json
index 01faa35..5652586 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "simple-youtube-age-restriction-bypass",
- "version": "2.4.2",
+ "version": "2.4.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "simple-youtube-age-restriction-bypass",
- "version": "2.4.2",
+ "version": "2.4.3",
"license": "MIT",
"devDependencies": {
"@babel/preset-env": "^7.16.7",
diff --git a/package.json b/package.json
index 741872b..ad4f78b 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"type": "module",
"name": "simple-youtube-age-restriction-bypass",
"description": "A simple userscript to bypass YouTube's age verification and watch age restricted videos without having to sign in.",
- "version": "2.4.2",
+ "version": "2.4.3",
"repository": {
"type": "git",
"url": "git+https://github.com/zerodytrash/Simple-YouTube-Age-Restriction-Bypass.git"