bep40 commited on
Commit
eec71a2
·
verified ·
1 Parent(s): 6d7c17a

Fix VTV proxy SSL: verify=False for vtvdigital self-signed cert + rewrite nested m3u8

Browse files
Files changed (1) hide show
  1. vtv_api.py +25 -2
vtv_api.py CHANGED
@@ -5,6 +5,8 @@ EPG data scraped from https://vtv.vn/lich-phat-song.htm
5
  """
6
  import re, time, threading
7
  import requests
 
 
8
  from fastapi import APIRouter, Query
9
  from fastapi.responses import JSONResponse, Response
10
  from bs4 import BeautifulSoup
@@ -219,7 +221,9 @@ def proxy_vtv_m3u8(url: str = Query(...)):
219
  headers["Origin"] = "https://fptplay.vn"
220
  elif "xemtv" in url:
221
  headers["Referer"] = "https://hd.xemtv.net/"
222
- r = requests.get(url, headers=headers, timeout=15, allow_redirects=True)
 
 
223
  if r.status_code != 200:
224
  return Response(status_code=502, content="upstream error")
225
  content = r.text
@@ -246,10 +250,29 @@ def proxy_vtv_segment(url: str = Query(...)):
246
  if "fptplay" in url:
247
  headers["Referer"] = "https://fptplay.vn/"
248
  headers["Origin"] = "https://fptplay.vn"
249
- r = requests.get(url, headers=headers, timeout=30, allow_redirects=True)
 
 
250
  if r.status_code != 200:
251
  return Response(status_code=502, content="upstream error")
252
  data = r.content
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  if len(data) > 188 and data[0:4] == b'\x89PNG' and data[188] == 0x47:
254
  data = data[188:]
255
  return Response(content=data, media_type="video/mp2t", headers={"Access-Control-Allow-Origin": "*", "Cache-Control": "public, max-age=3600"})
 
5
  """
6
  import re, time, threading
7
  import requests
8
+ import urllib3
9
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
10
  from fastapi import APIRouter, Query
11
  from fastapi.responses import JSONResponse, Response
12
  from bs4 import BeautifulSoup
 
221
  headers["Origin"] = "https://fptplay.vn"
222
  elif "xemtv" in url:
223
  headers["Referer"] = "https://hd.xemtv.net/"
224
+ # vtvdigital uses self-signed cert — skip SSL verification
225
+ verify_ssl = "vtvdigital" not in url
226
+ r = requests.get(url, headers=headers, timeout=15, allow_redirects=True, verify=verify_ssl)
227
  if r.status_code != 200:
228
  return Response(status_code=502, content="upstream error")
229
  content = r.text
 
250
  if "fptplay" in url:
251
  headers["Referer"] = "https://fptplay.vn/"
252
  headers["Origin"] = "https://fptplay.vn"
253
+ # vtvdigital uses self-signed cert — skip SSL verification
254
+ verify_ssl = "vtvdigital" not in url
255
+ r = requests.get(url, headers=headers, timeout=30, allow_redirects=True, verify=verify_ssl)
256
  if r.status_code != 200:
257
  return Response(status_code=502, content="upstream error")
258
  data = r.content
259
+ # If response is an m3u8 sub-playlist, rewrite segment URLs to proxy
260
+ content_type = r.headers.get("Content-Type", "")
261
+ if b"#EXTM3U" in data[:500] or ".m3u8" in url:
262
+ lines = data.decode("utf-8", errors="replace").split('\n')
263
+ rewritten = []
264
+ base_url = url.rsplit('/', 1)[0] + '/'
265
+ for line in lines:
266
+ line = line.strip()
267
+ if not line or line.startswith('#'):
268
+ rewritten.append(line)
269
+ else:
270
+ seg_url = line
271
+ if not seg_url.startswith('http'):
272
+ seg_url = base_url + seg_url
273
+ rewritten.append("/api/proxy/seg/vtv?url=" + requests.utils.quote(seg_url, safe=""))
274
+ return Response(content='\n'.join(rewritten).encode("utf-8"), media_type="application/vnd.apple.mpegurl", headers={"Access-Control-Allow-Origin": "*", "Cache-Control": "no-cache"})
275
+ # PNG fix
276
  if len(data) > 188 and data[0:4] == b'\x89PNG' and data[188] == 0x47:
277
  data = data[188:]
278
  return Response(content=data, media_type="video/mp2t", headers={"Access-Control-Allow-Origin": "*", "Cache-Control": "public, max-age=3600"})