From 8d66143c90c4b86e8ec8dfed67753bef2abf2114 Mon Sep 17 00:00:00 2001 From: Astounds Date: Sun, 3 May 2026 12:32:55 -0500 Subject: fix: update innertube clients and fix HLS/DASH quality switching - Update innertube client versions to match yt-dlp (android 21.02.35, ios 21.02.3, web 2.20260114.08.00, android_vr 1.65.10) - Remove obsolete clients (android-test-suite, ios_vr) - Replace tv_embedded with TVHTML5_SIMPLY (cn 75) - Add new clients: web_embedded, mweb, tv - Fix HLS freeze on quality switch: use nextLevel instead of currentLevel, handle bufferStalledError, stream proxy segments instead of buffering in memory - Populate DASH quality selector with actual sources (no Auto) - Render quality-select empty in template, let JS populate per mode --- youtube/constants.py | 190 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 youtube/constants.py (limited to 'youtube/constants.py') diff --git a/youtube/constants.py b/youtube/constants.py new file mode 100644 index 0000000..780cb10 --- /dev/null +++ b/youtube/constants.py @@ -0,0 +1,190 @@ +"""Constants used across yt-local application.""" + +import collections + +YOUTUBE_DOMAINS = ('youtube.com', 'youtu.be', 'youtube-nocookie.com') + +DEFAULT_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' +MOBILE_USER_AGENT = 'Mozilla/5.0 (Linux; Android 7.0; Redmi Note 4 Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36' + +REPLACEMENT_MAP = collections.OrderedDict([ + ('<', '_'), + ('>', '_'), + (': ', ' - '), + (':', '-'), + ('"', "'"), + ('/', '_'), + ('\\', '_'), + ('|', '-'), + ('?', ''), + ('*', '_'), + ('\t', ' '), +]) + +DOS_RESERVED_NAMES = frozenset({ + 'con', 'prn', 'aux', 'nul', 'com0', 'com1', 'com2', 'com3', + 'com4', 'com5', 'com6', 'com7', 'com8', 'com9', 'lpt0', + 'lpt1', 'lpt2', 'lpt3', 'lpt4', 'lpt5', 'lpt6', 'lpt7', + 'lpt8', 'lpt9' +}) + +INNERTUBE_CLIENTS = { + 'android': { + 'INNERTUBE_API_KEY': 'AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w', + 'INNERTUBE_CONTEXT': { + 'client': { + 'hl': 'en', + 'gl': 'US', + 'clientName': 'ANDROID', + 'clientVersion': '21.02.35', + 'osName': 'Android', + 'osVersion': '11', + 'androidSdkVersion': 30, + 'platform': 'MOBILE', + 'userAgent': 'com.google.android.youtube/21.02.35 (Linux; U; Android 11) gzip' + }, + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 3, + 'REQUIRE_JS_PLAYER': False, + }, + + 'ios': { + 'INNERTUBE_API_KEY': 'AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc', + 'INNERTUBE_CONTEXT': { + 'client': { + 'hl': 'en', + 'gl': 'US', + 'clientName': 'IOS', + 'clientVersion': '21.02.3', + 'deviceMake': 'Apple', + 'deviceModel': 'iPhone16,2', + 'osName': 'iPhone', + 'osVersion': '18.3.2.22D82', + 'userAgent': 'com.google.ios.youtube/21.02.3 (iPhone16,2; U; CPU iOS 18_3_2 like Mac OS X;)' + } + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 5, + 'REQUIRE_JS_PLAYER': False + }, + + 'tv_embedded': { + 'INNERTUBE_API_KEY': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8', + 'INNERTUBE_CONTEXT': { + 'client': { + 'hl': 'en', + 'gl': 'US', + 'clientName': 'TVHTML5_SIMPLY', + 'clientVersion': '1.0', + }, + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 75, + 'REQUIRE_JS_PLAYER': True, + }, + + 'web': { + 'INNERTUBE_API_KEY': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8', + 'INNERTUBE_CONTEXT': { + 'client': { + 'clientName': 'WEB', + 'clientVersion': '2.20260114.08.00', + 'userAgent': DEFAULT_USER_AGENT, + } + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 1 + }, + + 'web_embedded': { + 'INNERTUBE_API_KEY': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8', + 'INNERTUBE_CONTEXT': { + 'client': { + 'hl': 'en', + 'gl': 'US', + 'clientName': 'WEB_EMBEDDED_PLAYER', + 'clientVersion': '1.20260115.01.00', + }, + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 56, + 'REQUIRE_JS_PLAYER': True, + }, + + 'mweb': { + 'INNERTUBE_API_KEY': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8', + 'INNERTUBE_CONTEXT': { + 'client': { + 'hl': 'en', + 'gl': 'US', + 'clientName': 'MWEB', + 'clientVersion': '2.20260115.01.00', + 'userAgent': 'Mozilla/5.0 (iPad; CPU OS 16_7_10 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1,gzip(gfe)', + } + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 2, + 'REQUIRE_JS_PLAYER': True, + }, + + 'tv': { + 'INNERTUBE_API_KEY': 'AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8', + 'INNERTUBE_CONTEXT': { + 'client': { + 'hl': 'en', + 'gl': 'US', + 'clientName': 'TVHTML5', + 'clientVersion': '7.20260114.12.00', + 'userAgent': 'Mozilla/5.0 (ChromiumStylePlatform) Cobalt/25.lts.30.1034943-gold (unlike Gecko), Unknown_TV_Unknown_0/Unknown (Unknown, Unknown)', + } + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 7, + 'REQUIRE_JS_PLAYER': True, + }, + + 'android_vr': { + 'INNERTUBE_API_KEY': 'AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w', + 'INNERTUBE_CONTEXT': { + 'client': { + 'clientName': 'ANDROID_VR', + 'clientVersion': '1.65.10', + 'deviceMake': 'Oculus', + 'deviceModel': 'Quest 3', + 'androidSdkVersion': 32, + 'userAgent': 'com.google.android.apps.youtube.vr.oculus/1.65.10 (Linux; U; Android 12L; eureka-user Build/SQ3A.220605.009.A1) gzip', + 'osName': 'Android', + 'osVersion': '12L', + }, + }, + 'INNERTUBE_CONTEXT_CLIENT_NAME': 28, + 'REQUIRE_JS_PLAYER': False, + }, +} + +THEME_NAMES = { + 0: 'light_theme', + 1: 'gray_theme', + 2: 'dark_theme', +} + +FONT_CHOICES = { + 0: 'initial', + 1: '"liberation serif", "times new roman", calibri, carlito, serif', + 2: 'arial, "liberation sans", sans-serif', + 3: 'verdana, sans-serif', + 4: 'tahoma, sans-serif', +} + +URL_ORIGIN = "/https://www.youtube.com" + +MAX_RETRIES = 5 +BASE_DELAY = 1.0 + +TOR_DEFAULT_PORT = 9050 +TOR_CONTROL_DEFAULT_PORT = 9151 + +DEFAULT_PORT = 9010 + +# Backward compatibility aliases (matching existing code names) +desktop_user_agent = 'Mozilla/5.0 (Windows NT 6.1; rv:52.0) Gecko/20100101 Firefox/52.0' +desktop_ua = (('User-Agent', desktop_user_agent),) +mobile_ua = (('User-Agent', MOBILE_USER_AGENT),) +json_header = (('Content-Type', 'application/json'),) + +# Re-export for convenience +url_origin = URL_ORIGIN -- cgit v1.2.3