import urllib.request
-USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0"
+MOZILLA_RELEASE_URL = "https://www.mozilla.org/en-US/firefox/releases/"
+USER_AGENT_TEMPLATE = "Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/%s"
MIMETYPES = {
"video/mp4": "mp4",
cookiejar = http.cookiejar.CookieJar()
urlopener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookiejar))
referrer = ""
+user_agent = None
def urlopen(url, offset=None):
+ global user_agent
+ if not user_agent:
+ page = MozillaReleasesPageParser()
+ with urllib.request.urlopen(MOZILLA_RELEASE_URL) as f:
+ page.feed(f.read().decode("utf-8"))
+ page.close()
+ user_agent = USER_AGENT_TEMPLATE % page.latest_release
+
if url.startswith("//"):
url = "https:" + url
if not url.startswith("http://") and not url.startswith("https://"):
else:
req.add_header("Referer", referrer)
- req.add_header("User-Agent", USER_AGENT)
+ req.add_header("User-Agent", user_agent)
if offset:
req.add_header("Range", "bytes=%d-" % offset)
else:
raise NotYouTube()
-def parse_url(url, parser):
+def load_parse_url(url, parser):
f = urlopen(url)
parser.feed(f.read().decode("utf-8"))
parser.close()
fakeGlobal.matchMedia = () => ({matches: () => {}, media: ''});
fakeGlobal.result_url = null;
fakeGlobal.g = function(){}; // this is _yt_player
+ fakeGlobal.TimeRanges = function(){};
const code_string = %(code)s + ';';
const exec_string = 'result_url = %(url_func_name)s(%(cipher_func_name)s(...%(args)s));';
if data:
self.scripts.append(data)
+class MozillaReleasesPageParser(html.parser.HTMLParser):
+ def __init__(self):
+ super().__init__()
+ self.latest_release = "1.0"
+
+ def handle_starttag(self, tag, attrs):
+ attrs = dict(attrs)
+ if attrs.get("data-latest-firefox", None):
+ self.latest_release = attrs.get("data-latest-firefox", None)
+
def write_video(filename, video_data):
quoted_filename = urllib.parse.quote(filename.encode("utf-8"))
sys.stdout.buffer.write(
try:
page = YouTubeVideoPageParser()
validate_url(url)
- parse_url(url, page)
+ with urlopen(url) as f:
+ page.feed(f.read().decode("utf-8"))
+ page.close()
video_url, filename = get_video_url(page)
video_data = urlopen(video_url)
except VideoUnavailable as e:
sys.exit(1)
page = YouTubeVideoPageParser()
- parse_url(url, page)
+ with urlopen(url) as f:
+ page.feed(f.read().decode("utf-8"))
+ page.close()
video_url, filename = get_video_url(page)
print("Downloading", filename)