import urllib.request
-USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"
+USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0"
MIMETYPES = {
"video/mp4": "mp4",
def validate_url(url):
parsed_url = urllib.parse.urlparse(url)
scheme_ok = parsed_url.scheme == "https"
- host_ok = parsed_url.netloc.lstrip("www.") in ["youtube.com", "youtu.be"]
+ host = parsed_url.netloc.lstrip("www.").lstrip("m.")
+ host_ok = host in ["youtube.com", "youtu.be"]
if scheme_ok and host_ok:
return
return url
def get_player_config(scripts):
- player_config = None
+ config_strings = [
+ ("ytplayer.config = {", 1, "};", 1),
+ ("ytcfg.set({\"", 2, "});", 1),
+ ]
+ player_config = {}
for script in scripts:
for line in script.split("\n"):
- s = "ytplayer.config = {"
- if s in line:
- p1 = line.find(s) + len(s) - 1
- p2 = line.find("};", p1) + 1
- if p1 >= 0 and p2 > 0:
- return json.loads(line[p1:p2])
+ for s1, off1, s2, off2 in config_strings:
+ if s1 in line:
+ p1 = line.find(s1) + len(s1) - off1
+ p2 = line.find(s2, p1) + off2
+ if p1 >= 0 and p2 > 0:
+ player_config.update(json.loads(line[p1:p2]))
+ return player_config
def extract_js(script):
PREFIX = "var _yt_player={};(function(g){var window=this;"
return result_url
def get_best_video(player_config):
- js_url = player_config["assets"]["js"]
-
player_args = player_config["args"]
player_response = json.loads(player_args["player_response"])
formats = player_response["streamingData"]["formats"]
continue
if "signatureCipher" in format_data:
+ js_url = player_config["PLAYER_JS_URL"]
video_url = decode_cipher_url(js_url, format_data["signatureCipher"])
else:
video_url = format_data["url"]