bep40 commited on
Commit
a445af4
·
verified ·
1 Parent(s): 53bd90d

Upload vtv_api.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. vtv_api.py +60 -12
vtv_api.py CHANGED
@@ -69,7 +69,7 @@ FPTPLAY_URLS = {
69
  "vtv3": "https://live.fptplay53.net/fnxch2/vtv3hd_abr.smil/chunklist.m3u8",
70
  "vtv4": "https://live.fptplay53.net/fnxch2/vtv4hd_abr.smil/chunklist.m3u8",
71
  "vtv5": "https://live-a.fptplay53.net/live/media/VTV5HD/live_hls_avc/index.m3u8",
72
- "vtv6": "https://live.fptplay53.net/fnxhd1/vtv6hd_vhls.smil/chunklist.m3u8",
73
  "vtv7": "https://live.fptplay53.net/fnxhd1/vtv7hd_vhls.smil/chunklist_b5000000.m3u8",
74
  "vtv8": "https://live.fptplay53.net/epzhd1/vtv8hd_vhls.smil/chunklist.m3u8",
75
  "vtv9": "https://live.fptplay53.net/fnxhd1/vtv9hd_vhls.smil/chunklist.m3u8",
@@ -132,6 +132,46 @@ def fetch_fptplay_stream(channel_id):
132
  pass
133
  return None
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  def fetch_vtv_stream(channel_id):
136
  """Fetch VTV stream with multi-source fallback chain:
137
  1. VTVGo CDN (primary, works for most channels)
@@ -161,18 +201,26 @@ def fetch_vtv_stream(channel_id):
161
  _set_cache(channel_id, None)
162
  return None
163
 
164
- # Source 1: VTVGo CDN (primary for channels that have it)
165
- vtvgourl = VTVGO_FAILOVER.get(channel_id)
166
- if vtvgourl:
167
- _set_cache(channel_id, vtvgourl)
168
- return vtvgourl
 
169
 
170
- # Source 2: fptplay CDN (primary for VTV10, fallback for others)
171
  fpt_url = fetch_fptplay_stream(channel_id)
172
  if fpt_url:
173
  _set_cache(channel_id, fpt_url)
174
  return fpt_url
175
 
 
 
 
 
 
 
 
176
  # Source 3: xemtv.net PHP scraper (last resort, often unreachable)
177
  xemtv_url = fetch_xemtv_stream(channel_id)
178
  if xemtv_url:
@@ -186,15 +234,15 @@ def fetch_vtv_stream(channel_id):
186
  def api_vtv_streams():
187
  result = {}
188
  for ch_id in CHANNEL_NAMES:
189
- stream_url = fetch_vtv_stream(ch_id)
190
- result[ch_id] = {"name": CHANNEL_NAMES[ch_id], "stream_url": stream_url, "status": "ok" if stream_url else "offline"}
191
  return JSONResponse(result)
192
 
193
  @router.get("/api/vtv/stream/{channel_id}")
194
  def api_vtv_stream(channel_id: str):
195
- stream_url = fetch_vtv_stream(channel_id)
196
- if stream_url:
197
- return JSONResponse({"stream_url": stream_url, "status": "ok"})
198
  return JSONResponse({"error": "stream not found", "status": "offline"}, status_code=404)
199
 
200
  @router.get("/api/proxy/page")
 
69
  "vtv3": "https://live.fptplay53.net/fnxch2/vtv3hd_abr.smil/chunklist.m3u8",
70
  "vtv4": "https://live.fptplay53.net/fnxch2/vtv4hd_abr.smil/chunklist.m3u8",
71
  "vtv5": "https://live-a.fptplay53.net/live/media/VTV5HD/live_hls_avc/index.m3u8",
72
+ "vtv6": "https://live.fptplay53.net/fnxch2/vtv6hd_abr.smil/chunklist.m3u8",
73
  "vtv7": "https://live.fptplay53.net/fnxhd1/vtv7hd_vhls.smil/chunklist_b5000000.m3u8",
74
  "vtv8": "https://live.fptplay53.net/epzhd1/vtv8hd_vhls.smil/chunklist.m3u8",
75
  "vtv9": "https://live.fptplay53.net/fnxhd1/vtv9hd_vhls.smil/chunklist.m3u8",
 
132
  pass
133
  return None
134
 
135
+ def fetch_vtv_streams(channel_id):
136
+ """Fetch all available stream URLs for a channel (ordered by priority)."""
137
+ urls = []
138
+ channel_id = channel_id.lower().strip()
139
+ name_map = {
140
+ 'vtvct': 'vtv10', 'vtv-can-tho': 'vtv10', 'vtv can tho': 'vtv10',
141
+ 'vtv_can_tho': 'vtv10', 'cantho': 'vtv10',
142
+ 'vietnam_vtv1': 'vtv1', 'vietnam_vtv2': 'vtv2', 'vietnam_vtv3': 'vtv3',
143
+ 'vietnam_vtv4': 'vtv4', 'vietnam_vtv5': 'vtv5', 'vietnam_vtv6': 'vtv6',
144
+ 'vietnam_vtv7': 'vtv7', 'vietnam_vtv8': 'vtv8', 'vietnam_vtv9': 'vtv9',
145
+ }
146
+ channel_id = name_map.get(channel_id, channel_id)
147
+
148
+ # Collect all available sources
149
+ sources = [
150
+ ('vtvgo', lambda: VTVGO_FAILOVER.get(channel_id)),
151
+ ('fptplay', lambda: fetch_fptplay_stream(channel_id)),
152
+ ('xemtv', lambda: fetch_xemtv_stream(channel_id)),
153
+ ]
154
+
155
+ # For VTV6: skip VTVGo CDN first (may be misrouted), prefer fptplay, then VTVGo as last resort
156
+ if channel_id == 'vtv6':
157
+ sources = [
158
+ ('fptplay', lambda: fetch_fptplay_stream(channel_id)),
159
+ ('xemtv', lambda: fetch_xemtv_stream(channel_id)),
160
+ ('vtvgo', lambda: VTVGO_FAILOVER.get(channel_id)),
161
+ ]
162
+
163
+ seen = set()
164
+ for name, fetch_fn in sources:
165
+ try:
166
+ url = fetch_fn()
167
+ if url and url not in seen:
168
+ seen.add(url)
169
+ urls.append(url)
170
+ except:
171
+ pass
172
+
173
+ return urls
174
+
175
  def fetch_vtv_stream(channel_id):
176
  """Fetch VTV stream with multi-source fallback chain:
177
  1. VTVGo CDN (primary, works for most channels)
 
201
  _set_cache(channel_id, None)
202
  return None
203
 
204
+ # Source 1: VTVGo CDN (primary for most channels)
205
+ if channel_id != 'vtv6': # VTV6 skip VTVGo CDN due to CDN misrouting
206
+ vtvgourl = VTVGO_FAILOVER.get(channel_id)
207
+ if vtvgourl:
208
+ _set_cache(channel_id, vtvgourl)
209
+ return vtvgourl
210
 
211
+ # Source 2: fptplay CDN (primary for VTV6/VTV10, fallback for others)
212
  fpt_url = fetch_fptplay_stream(channel_id)
213
  if fpt_url:
214
  _set_cache(channel_id, fpt_url)
215
  return fpt_url
216
 
217
+ # Source 3: VTVGo CDN for VTV6 as last resort
218
+ if channel_id == 'vtv6':
219
+ vtvgourl = VTVGO_FAILOVER.get(channel_id)
220
+ if vtvgourl:
221
+ _set_cache(channel_id, vtvgourl)
222
+ return vtvgourl
223
+
224
  # Source 3: xemtv.net PHP scraper (last resort, often unreachable)
225
  xemtv_url = fetch_xemtv_stream(channel_id)
226
  if xemtv_url:
 
234
  def api_vtv_streams():
235
  result = {}
236
  for ch_id in CHANNEL_NAMES:
237
+ stream_urls = fetch_vtv_streams(ch_id)
238
+ result[ch_id] = {"name": CHANNEL_NAMES[ch_id], "stream_urls": stream_urls, "stream_url": stream_urls[0] if stream_urls else None, "status": "ok" if stream_urls else "offline"}
239
  return JSONResponse(result)
240
 
241
  @router.get("/api/vtv/stream/{channel_id}")
242
  def api_vtv_stream(channel_id: str):
243
+ stream_urls = fetch_vtv_streams(channel_id)
244
+ if stream_urls:
245
+ return JSONResponse({"stream_urls": stream_urls, "stream_url": stream_urls[0], "status": "ok"})
246
  return JSONResponse({"error": "stream not found", "status": "offline"}, status_code=404)
247
 
248
  @router.get("/api/proxy/page")