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():
54 r
= requests
.get(f
"https://{host}/videoplayback{path}",
55 request
.args
.to_dict(),
60 k
:v
for k
,v
in r
.headers
.items()
61 if k
.lower() in RESPONSE_HEADERS_WHITELIST
64 silence_errors(r
.iter_content(chunk_size
=8192)),
65 status
=r
.status_code
, headers
=resp_headers
)
66 response
.call_on_close(lambda: r
.close())
67 response
.headers
['Access-Control-Allow-Origin'] = cors_origin()
70 @frontend.route("/api/manifest/hls_playlist/<path:path>")
71 @frontend.route("/api/manifest/hls_variant/<path:path>")
72 def hls_manifest(path
):
73 path_fixed
= request
.path
.replace(';','%3B').replace('=','%3D')
74 with requests_cache
.disabled():
75 r
= requests
.get(f
"https://manifest.googlevideo.com{path_fixed}")
77 return "", r
.status_code
79 rv
= re
.sub(r
"^https://[a-z0-9-]+\.googlevideo\.com", "", r
.text
, flags
=re
.M
)
81 'Content-Type': 'application/x-mpegURL',
82 'Access-Control-Allow-Origin': cors_origin()
86 return f
"{request.environ.get('wsgi.url_scheme')}://{request.host}"
88 @frontend.route("/x-hls/")
89 @frontend.route("/x-hls/<vid>")
90 def xxx(vid
="5qap5aO4i9A"):
91 from ..common
.common
import get_video_info
92 _
, map, _
, _
, _
= get_video_info(vid
, -1)
93 url
= map['hlsManifestUrl'].replace("https://manifest.googlevideo.com", "")
96 <meta charset="utf-8"/>
97 <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
99 video {{ width: 640px; height: 360px; }}
101 <video autoplay preload="none" controls="true">
102 <source src="{url}" type="application/x-mpegURL"/>
105 let vid = document.querySelector('video');
106 if (!vid.canPlayType('application/vnd.apple.mpegurl') && Hls.isSupported()) {{
108 hls.loadSource(document.querySelector("source").src);
109 hls.attachMedia(vid);
115 if __name__
== '__main__':
116 app().run(debug
=True)