bep40 commited on
Commit
ae30435
·
verified ·
1 Parent(s): ca43247

Upload vtv_api.py

Browse files
Files changed (1) hide show
  1. vtv_api.py +7 -39
vtv_api.py CHANGED
@@ -1,4 +1,4 @@
1
- # VTV Stream — SV2 iframe cho tất cả kênh + M3U fallback + EPG
2
  import re, time, threading, json, requests
3
  from fastapi import APIRouter, Query
4
  from fastapi.responses import JSONResponse, Response, StreamingResponse
@@ -18,8 +18,8 @@ HARDCODED_URLS = {"vtv6": "https://live.fptplay53.net/live/media/v6abr/live247-h
18
  CHANNEL_URLS = {k: (HARDCODED_URLS[k] if k in HARDCODED_URLS else None) for k in ["vtv1","vtv2","vtv3","vtv4","vtv5","vtv6","vtv7","vtv8","vtv9","vtv10"]}
19
  CHANNEL_NAMES = {"vtv1":"VTV1","vtv2":"VTV2","vtv3":"VTV3","vtv4":"VTV4","vtv5":"VTV5","vtv6":"VTV6","vtv7":"VTV7","vtv8":"VTV8","vtv9":"VTV9","vtv10":"VTV10","vtvprime":"VTVPrime"}
20
 
21
- # SV2 iframe URLs — player thật, hỗ trợ mobile
22
- SV2_URLS = {
23
  "vtv1": "https://sv2.xemtivitop.com/live/hot/vtv1.php",
24
  "vtv2": "https://sv2.xemtivitop.com/live/hot/vtv2.php",
25
  "vtv3": "https://sv2.xemtivitop.com/live/hot/vtv3.php",
@@ -88,38 +88,6 @@ def get_channel_url(channel_id):
88
  _fetch_m3u()
89
  with _channel_urls_lock: return CHANNEL_URLS.get(channel_id)
90
 
91
- # ===== SV2 PROXY (IFRAME-FRIENDLY) =====
92
- @router.get("/api/proxy/sv2/iframe")
93
- def proxy_sv2_iframe(url: str = Query(...)):
94
- """Proxy SV2 iframe — rewrite relative URLs, cho phép iframe"""
95
- try:
96
- s = requests.Session()
97
- try: s.get("https://sv2.xemtivitop.com/", headers=UA, timeout=5, verify=False)
98
- except: pass
99
- r = s.get(url, headers={**UA, "Referer": "https://sv2.xemtivitop.com/"}, timeout=15, verify=False)
100
- if r.status_code != 200:
101
- return Response(content=f"<html><body><p>sv2 error: {r.status_code}</p></body></html>",
102
- media_type="text/html", headers={"Access-Control-Allow-Origin": "*"})
103
- html = r.text
104
- # Rewrite relative URLs
105
- html = html.replace('src="/', 'src="https://sv2.xemtivitop.com/')
106
- html = html.replace("src='/", "src='https://sv2.xemtivitop.com/")
107
- html = html.replace('href="/', 'href="https://sv2.xemtivitop.com/')
108
- html = html.replace("href='/", "href='https://sv2.xemtivitop.com/")
109
- # Force fullscreen, hide margins
110
- html = html.replace('</head>', '''
111
- <style>
112
- *{margin:0;padding:0}
113
- body{background:#000;overflow:hidden;margin:0;padding:0}
114
- iframe,video,.video-js,#player,.player{width:100%!important;height:100%!important;max-width:100%!important}
115
- </style>
116
- </head>''')
117
- return Response(content=html.encode('utf-8'), media_type="text/html",
118
- headers={"Access-Control-Allow-Origin": "*", "X-Frame-Options": "ALLOWALL", "Content-Security-Policy": "frame-ancestors *"})
119
- except Exception as e:
120
- return Response(content=f"<html><body><p>sv2 proxy error: {str(e)[:100]}</p></body></html>",
121
- media_type="text/html", headers={"Access-Control-Allow-Origin": "*"})
122
-
123
  # ===================== API ENDPOINTS =====================
124
 
125
  @router.get("/api/vtv/streams")
@@ -128,7 +96,7 @@ def api_vtv_streams():
128
  result = {}
129
  for ch_id in CHANNEL_NAMES:
130
  stream_url = urls.get(ch_id)
131
- sv2_url = SV2_URLS.get(ch_id)
132
  is_flv = stream_url and ".flv" in stream_url
133
  result[ch_id] = {
134
  "name": CHANNEL_NAMES[ch_id],
@@ -136,7 +104,7 @@ def api_vtv_streams():
136
  "proxy_url": f"/api/proxy/flv?url={quote(stream_url, safe='')}" if stream_url and is_flv else "",
137
  "proxy_url_hls": f"/api/proxy/stream?url={quote(stream_url, safe='')}" if stream_url and not is_flv else "",
138
  "is_flv": is_flv,
139
- "proxy_iframe_url": f"/api/proxy/sv2/iframe?url={quote(sv2_url, safe='')}" if sv2_url else "",
140
  "status": "ok"
141
  }
142
  return JSONResponse(result)
@@ -146,7 +114,7 @@ def api_vtv_stream(channel_id: str):
146
  channel_id = channel_id.lower().strip()
147
  if channel_id not in CHANNEL_NAMES: return JSONResponse({"error":"not found"}, status_code=404)
148
  stream_url = get_channel_url(channel_id)
149
- sv2_url = SV2_URLS.get(channel_id)
150
  is_flv = stream_url and ".flv" in stream_url
151
  return JSONResponse({
152
  "name": CHANNEL_NAMES[channel_id],
@@ -154,7 +122,7 @@ def api_vtv_stream(channel_id: str):
154
  "proxy_url": f"/api/proxy/flv?url={quote(stream_url, safe='')}" if stream_url and is_flv else "",
155
  "proxy_url_hls": f"/api/proxy/stream?url={quote(stream_url, safe='')}" if stream_url and not is_flv else "",
156
  "is_flv": is_flv,
157
- "proxy_iframe_url": f"/api/proxy/sv2/iframe?url={quote(sv2_url, safe='')}" if sv2_url else "",
158
  "status": "ok"
159
  })
160
 
 
1
+ # VTV Stream — Direct SV2 iframe URLs + M3U fallback + EPG
2
  import re, time, threading, json, requests
3
  from fastapi import APIRouter, Query
4
  from fastapi.responses import JSONResponse, Response, StreamingResponse
 
18
  CHANNEL_URLS = {k: (HARDCODED_URLS[k] if k in HARDCODED_URLS else None) for k in ["vtv1","vtv2","vtv3","vtv4","vtv5","vtv6","vtv7","vtv8","vtv9","vtv10"]}
19
  CHANNEL_NAMES = {"vtv1":"VTV1","vtv2":"VTV2","vtv3":"VTV3","vtv4":"VTV4","vtv5":"VTV5","vtv6":"VTV6","vtv7":"VTV7","vtv8":"VTV8","vtv9":"VTV9","vtv10":"VTV10","vtvprime":"VTVPrime"}
20
 
21
+ # SV2 direct iframe URLs — player thật, hỗ trợ mobile
22
+ SV2_IFRAME_URLS = {
23
  "vtv1": "https://sv2.xemtivitop.com/live/hot/vtv1.php",
24
  "vtv2": "https://sv2.xemtivitop.com/live/hot/vtv2.php",
25
  "vtv3": "https://sv2.xemtivitop.com/live/hot/vtv3.php",
 
88
  _fetch_m3u()
89
  with _channel_urls_lock: return CHANNEL_URLS.get(channel_id)
90
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  # ===================== API ENDPOINTS =====================
92
 
93
  @router.get("/api/vtv/streams")
 
96
  result = {}
97
  for ch_id in CHANNEL_NAMES:
98
  stream_url = urls.get(ch_id)
99
+ sv2_url = SV2_IFRAME_URLS.get(ch_id)
100
  is_flv = stream_url and ".flv" in stream_url
101
  result[ch_id] = {
102
  "name": CHANNEL_NAMES[ch_id],
 
104
  "proxy_url": f"/api/proxy/flv?url={quote(stream_url, safe='')}" if stream_url and is_flv else "",
105
  "proxy_url_hls": f"/api/proxy/stream?url={quote(stream_url, safe='')}" if stream_url and not is_flv else "",
106
  "is_flv": is_flv,
107
+ "iframe_url": sv2_url,
108
  "status": "ok"
109
  }
110
  return JSONResponse(result)
 
114
  channel_id = channel_id.lower().strip()
115
  if channel_id not in CHANNEL_NAMES: return JSONResponse({"error":"not found"}, status_code=404)
116
  stream_url = get_channel_url(channel_id)
117
+ sv2_url = SV2_IFRAME_URLS.get(channel_id)
118
  is_flv = stream_url and ".flv" in stream_url
119
  return JSONResponse({
120
  "name": CHANNEL_NAMES[channel_id],
 
122
  "proxy_url": f"/api/proxy/flv?url={quote(stream_url, safe='')}" if stream_url and is_flv else "",
123
  "proxy_url_hls": f"/api/proxy/stream?url={quote(stream_url, safe='')}" if stream_url and not is_flv else "",
124
  "is_flv": is_flv,
125
+ "iframe_url": sv2_url,
126
  "status": "ok"
127
  })
128