From ca1e60b138bb13485e202e7c65f2f01f695ed019 Mon Sep 17 00:00:00 2001 From: girst Date: Thu, 17 Jun 2021 15:06:03 +0200 Subject: [PATCH] move to new api again, use new api for age-gate bypass get_video_info?html5=1 is now also being shut down, so we do really need to move to the new innertube api. :/ --- app/common/common.py | 43 ++++++++++++++++++++--------------------- app/youtube/__init__.py | 1 + 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/app/common/common.py b/app/common/common.py index acf3c5c..d0989ce 100644 --- a/app/common/common.py +++ b/app/common/common.py @@ -201,10 +201,10 @@ def update_channel(db, xmldata, from_webhook=False): return True -def get_video_info(video_id, sts=0, algo=""): +def get_video_info(video_id, sts=0, algo="", _embed=False): """ returns: best-quality muxed video stream, stream map, player_response, error-type/mesage - error types: player, malformed, livestream, geolocked, exhausted + error types: player, malformed, livestream, geolocked, agegated, no-url, exhausted """ player_error, metadata = None, None # for 'exhausted' with sqlite3.connect(cf['global']['database']) as conn: @@ -214,14 +214,14 @@ def get_video_info(video_id, sts=0, algo=""): today = datetime.now(timezone.utc).strftime("%Y%m%d") # XXX: anticaptcha hasn't been adapted # XXX: this is not cached any more! - # XXX: age-gated now broken: HtVdAasjOgU (embed ok), XgnwCQzjau8 (no embed) + # note: age-gated works as long as it's embeddable (HtVdAasjOgU ok, XgnwCQzjau8 bad) r = requests.post("https://www.youtube-nocookie.com/youtubei/v1/player?key=AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8", json={ 'videoId': video_id, 'context': { 'client': { 'gl': 'US', 'hl': 'en', - 'clientName': 'WEB', + 'clientName': 'WEB_EMBEDDED_PLAYER' if _embed else 'WEB', 'clientVersion': f'2.{today}.01.01', } }, @@ -232,30 +232,29 @@ def get_video_info(video_id, sts=0, algo=""): return None, None, None, 'banned', 'possible IP ban' metadata = r.json() + if "error" in metadata: + return None, None, metadata, "malformed", metadata.get("error",{}).get("message","") playabilityStatus = metadata['playabilityStatus']['status'] if playabilityStatus != "OK": playabilityReason = metadata['playabilityStatus'].get('reason', '//'.join(metadata['playabilityStatus'].get('messages',[]))) player_error = f"{playabilityStatus}: {playabilityReason}" #if playabilityStatus == "UNPLAYABLE": XXX: do we need that still? - if playabilityStatus == "LOGIN_REQUIRED" and metadata['playabilityStatus'].get('reason') == "Sign in to confirm your age" and sts != 0: - r = requests.get("https://www.youtube.com/get_video_info?html5=1&video_id="+video_id, { - "video_id": video_id, - "eurl": f"https://youtube.googleapis.com/v/{video_id}", - "el": "embedded", - "sts": sts, - "hl": "en_US", - }) - params = parse_qs(r.text) - if 'errorcode' in params: # status=fail - return None, None, None, 'malformed', params['reason'][0] - from flask import current_app - current_app.logger.error(r.text) - metadata = json.loads(params.get('player_response')[0]) - - # without videoDetails, there's only the error message - maybe_metadata = metadata if 'videoDetails' in metadata else None - return None, None, maybe_metadata, 'player', player_error + if (playabilityStatus == "LOGIN_REQUIRED" + and "confirm your age" in metadata['playabilityStatus'].get('reason') + and sts != 0 # only need metadata when no sts (via pubsubhubbub) + and not _embed + ): + _, _, metadata_embed, error_embed, _ = get_video_info(video_id, sts, algo, True) + if not error_embed: + metadata['streamingData'] = metadata_embed['streamingData'] + metadata['playabilityStatus'] = metadata_embed['playabilityStatus'] + else: + return None, None, metadata, 'agegated', player_error + else: + # without videoDetails, there's only the error message + maybe_metadata = metadata if 'videoDetails' in metadata else None + return None, None, maybe_metadata, 'player', player_error # livestreams have no adaptive/muxed formats: is_live = metadata['videoDetails'].get('isLive', False) diff --git a/app/youtube/__init__.py b/app/youtube/__init__.py index 46b1475..52d8e28 100644 --- a/app/youtube/__init__.py +++ b/app/youtube/__init__.py @@ -85,6 +85,7 @@ def watch(): 'malformed': "Video ID is invalid.", 'geolocked': "This video is geolocked.", 'livestream': "Livestreams not supported on this instance.", + 'agegated': "Unable to bypass age-restriction.", 'exhausted': errdetails or "Couldn't extract video URLs.", 'player': errdetails, }.get(error) -- 2.39.3