2 import requests
, requests_cache
3 from flask
import Flask
, Blueprint
, request
, Response
4 from flask_login
import current_user
6 frontend
= Blueprint('proxy', __name__
)
10 app
.register_blueprint(frontend
)
13 # https://github.com/psf/requests/issues/5612
14 def silence_errors(generator
):
17 except requests
.exceptions
.RequestException
:
20 @frontend.route("/videoplayback/<path:path>")
21 @frontend.route("/videoplayback")
22 def videoplayback(path
=None):
23 if path
is not None: # seg.ts URL
24 args
= path
.split("/")[0:-1]
25 host
= dict(zip(args
[::2], args
[1::2])).get('hls_chunk_host')
26 path
= "/" + path
.replace(';','%3B').replace('=','%3D')
28 fvip
= request
.args
.get("fvip", "3")
29 mn
= request
.args
.get("mn", "").split(",")[-1]
30 host
= f
"r{fvip}---{mn}.googlevideo.com"
33 REQUEST_HEADERS_WHITELIST
= {
39 RESPONSE_HEADERS_WHITELIST
= {
46 "x-content-type-options",
50 k
:v
for k
,v
in request
.headers
51 if k
.lower() in REQUEST_HEADERS_WHITELIST
53 with requests_cache
.disabled():
55 r
= requests
.get(f
"https://{host}/videoplayback{path}",
56 request
.args
.to_dict(),
59 except requests
.exceptions
.ConnectionError
:
60 return f
"unable to connect to {host}", 502
63 k
:v
for k
,v
in r
.headers
.items()
64 if k
.lower() in RESPONSE_HEADERS_WHITELIST
67 silence_errors(r
.iter_content(chunk_size
=8192)),
68 status
=r
.status_code
, headers
=resp_headers
)
69 response
.call_on_close(lambda: r
.close())
70 response
.headers
['Access-Control-Allow-Origin'] = cors_origin()
73 @frontend.route("/api/manifest/hls_playlist/<path:path>")
74 @frontend.route("/api/manifest/hls_variant/<path:path>")
75 def hls_manifest(path
):
76 path_fixed
= request
.path
.replace(';','%3B').replace('=','%3D')
77 with requests_cache
.disabled():
78 r
= requests
.get(f
"https://manifest.googlevideo.com{path_fixed}")
80 return "", r
.status_code
82 rv
= re
.sub(r
"^https://[a-z0-9-]+\.googlevideo\.com", "", r
.text
, flags
=re
.M
)
83 if "/api/manifest/hls_variant" in request
.path
:
84 rv
= rv
+ "\n#EXT-X-ENDLIST"
86 'Content-Type': 'application/x-mpegURL',
87 'Access-Control-Allow-Origin': cors_origin()
91 return f
"{request.environ.get('wsgi.url_scheme')}://{request.host}"
94 if __name__
== '__main__':