Skip to content

Instantly share code, notes, and snippets.

@pukkandan
Last active March 21, 2023 09:11
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pukkandan/fcf5ca1785c80f64e471f0ee14f990fb to your computer and use it in GitHub Desktop.
Save pukkandan/fcf5ca1785c80f64e471f0ee14f990fb to your computer and use it in GitHub Desktop.
yt-dlp plugin to bypass youtube age-gate
Moved to https://github.com/pukkandan/YT_AgeGateBypass
"""
SPDX-License-Identifier: MIT https://opensource.org/licenses/MIT
Copyright © 2022 pukkandan.ytdlp@gmail.com
yt-dlp plugin extractor to bypass youtube age-gate
Needs yt-dlp 2022.09.17 or above
Usage: Import this file in ytdlp_plugins/extractor/__init__.py
See https://github.com/yt-dlp/yt-dlp#plugins for details
Uses account proxy https://youtube-proxy.zerody.one by https://github.com/zerodytrash
to fetch video formats and proxy service https://www.4everproxy.com for download (if required)
Set "VIDEO_PROXY = None" to disable the proxy service
Note: The account proxy has limited resources. Please do not abuse
"""
import base64
from yt_dlp.utils import get_first, parse_qs
from yt_dlp.extractor.youtube import YoutubeIE
ACCOUNT_PROXY = 'https://youtube-proxy.zerody.one'
VIDEO_PROXY = 'https://phx.4everproxy.com'
class Youtube_AgeGateBypassIE(YoutubeIE, plugin_name='AGB'):
_TESTS = [{
'url': 'Cr381pDsSsA',
'info_dict': {
'id': 'Cr381pDsSsA',
'ext': 'mp4',
'playable_in_embed': False,
'live_status': 'not_live',
'channel_id': 'UCDhvbka47fW1vwOmU3ssGkQ',
'channel_url': 'https://www.youtube.com/channel/UCDhvbka47fW1vwOmU3ssGkQ',
'view_count': int,
'thumbnail': 'https://i.ytimg.com/vi_webp/Cr381pDsSsA/sddefault.webp',
'comment_count': int,
'tags': 'count:14',
'availability': 'needs_auth',
'duration': 958,
'uploader_id': 'multilazyazz',
'categories': ['Film & Animation'],
'title': 'Some Girls from Equestria have a Fall Formal Fuck-up',
'uploader': 'Liquid Sky',
'uploader_url': 'http://www.youtube.com/user/multilazyazz',
'upload_date': '20150403',
'channel_follower_count': int,
'chapters': [{'start_time': 0, 'end_time': 522.0, 'title': '<Untitled Chapter 1>'}, {'start_time': 522.0, 'title': '8:43] Boards of Canada - 1969', 'end_time': 958}],
'description': 'md5:3789850a3dc23cd55279131a82abcc84',
'like_count': int,
'channel': 'Liquid Sky',
'age_limit': 18,
}
}] + YoutubeIE._TESTS
def _download_player_responses(self, url, smuggled_data, video_id, *args, **kwargs):
AGB_CLIENT = 'web'
ret = super()._download_player_responses(url, smuggled_data, video_id, *args, **kwargs)
_, ytcfg, player_responses, player_url, *_ = ret
is_agegated = any(map(self._is_agegated, player_responses)) \
and all(self._is_agegated(pr) or self._is_unplayable(pr) for pr in player_responses)
if is_agegated:
pr = self._download_json(
f'{ACCOUNT_PROXY}/getPlayer', video_id,
'Downloading Zerody API JSON', fatal=False, query={
'videoId': video_id,
'clientName': self._extract_client_name(ytcfg, AGB_CLIENT),
'clientVersion': self._extract_client_version(ytcfg, AGB_CLIENT),
'signatureTimestamp': self._extract_signature_timestamp(video_id, player_url, ytcfg),
'reason': 'LOGIN_REQUIRED',
'startTimeSecs': 0,
'client': 'yt-dlp',
})
if pr:
player_responses.append(pr)
streaming_data = get_first(player_responses, 'streamingData') or {}
if VIDEO_PROXY:
streaming_data['_use_proxy'] = True
return ret
def _extract_formats(self, streaming_data, *args, **kwargs):
has_gcr = False
for f in super()._extract_formats(streaming_data, *args, **kwargs):
if get_first(streaming_data, '_use_proxy') and parse_qs(f.get('url')).get('gcr'):
has_gcr = True
f['url'] = f'{VIDEO_PROXY}/direct/' + base64.b64encode(f['url'].encode()).decode()
yield f
if has_gcr:
self.to_screen('Video formats have GCR. Using proxy for download')
@BanementI
Copy link

there's some specific(?) kinds of 18+ video that can't be downloaded, but unfortunately it is embarassing to give the ID even for debug reasons, if i can reproduce using my own example videos then i'll give a video ID (since the redacted one is probably useless tbh). if i cant then i'll give you the video ID

Verbose redacted
yt-dlp https://www.youtube.com/watch?v=REDACTED --verbose
[debug] Command-line config: ['https://www.youtube.com/watch?v=REDACTED', '--verbose']
[debug] Encodings: locale UTF-8, fs utf-8, out UTF-8, err UTF-8, pref UTF-8
[debug] yt-dlp version 2022.04.08 [7884ade65] (zip)
[debug] Plugins: ['Youtube_AgeGateBypassIE']
[debug] Python version 3.7.3 (CPython 64bit) - Linux-4.4.0-19041-Microsoft-x86_64-with-debian-10.11
[debug] Checking exe version: ffmpeg -bsfs
[debug] Checking exe version: ffprobe -bsfs
[debug] exe versions: ffmpeg 4.1.8-0, ffprobe 4.1.8-0, phantomjs 5, rtmpdump 2.4
[debug] Optional libraries: certifi, Crypto, secretstorage, mutagen, sqlite
[debug] Proxy map: {}
[debug] [youtube:AGB] Extracting URL: https://www.youtube.com/watch?v=REDACTED
[youtube:AGB] REDACTED: Downloading webpage
[youtube:AGB] REDACTED: Downloading android player API JSON
[youtube:AGB] REDACTED: Downloading tv embedded player API JSON
[youtube:AGB] REDACTED: Downloading web embedded config
[youtube:AGB] REDACTED: Downloading player fae06c11
[youtube:AGB] REDACTED: Downloading web embedded player API JSON
ERROR: [youtube:AGB] REDACTED: Sign in to confirm your age. This video may be inappropriate for some users.
  File "/usr/local/bin/yt-dlp/yt_dlp/extractor/common.py", line 641, in extract
    ie_result = self._real_extract(url)
  File "/usr/local/bin/ytdlp_plugins/extractor/Youtube_AgeGateBypass.py", line 77, in _real_extract
    res = super()._real_extract(url)
  File "/usr/local/bin/yt-dlp/yt_dlp/extractor/youtube.py", line 3377, in _real_extract
    self.raise_no_formats(reason, expected=True)
  File "/usr/local/bin/yt-dlp/yt_dlp/extractor/common.py", line 1161, in raise_no_formats
    raise ExtractorError(msg, expected=expected, video_id=video_id)

@Spotlightsrule
Copy link

Spotlightsrule commented Aug 10, 2022

Current version of this plugin does not work. No-opping line 38 by replacing its contents with if True: seems to fix it. I am a total Python noob, so this may not be the best fix, but it worked for me.

@pukkandan
Copy link
Author

@Spotlightsrule Fixed

I would suggest not to use if True:. This causes all videos to be passed through the proxy, putting unnecessary load on it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment