ztoolx commited on
Commit
da1e1ae
·
verified ·
1 Parent(s): c456421
Files changed (1) hide show
  1. main.py +36 -21
main.py CHANGED
@@ -33,29 +33,34 @@ async def get_transcript(req: TranscriptRequest):
33
  if not video_id:
34
  raise HTTPException(status_code=400, detail="Invalid YouTube URL")
35
 
36
- # We will try multiple Invidious instances in case one is down
37
  instances = [
38
- "https://inv.nadeko.net",
39
- "https://invidious.fdn.fr",
40
- "https://invidious.protokolla.fi",
41
- "https://iv.datura.network"
42
  ]
43
 
44
  for host in instances:
45
  try:
46
- print(f"Trying {host} for video {video_id}...")
47
- # 1. Fetch available captions from Invidious
48
- res = requests.get(f"{host}/api/v1/captions/{video_id}?label=English", timeout=5)
 
49
 
50
  if res.status_code != 200:
51
- continue # Try next instance
 
52
 
53
  data = res.json()
54
- if not data.get("captions"):
55
- continue # Try next instance
56
 
57
- # 2. Find the English caption URL (or first available)
58
- caption = next((c for c in data["captions"] if "English" in c.get("label", "")), data["captions"][0])
 
 
 
 
59
  caption_url = caption.get("url")
60
 
61
  if not caption_url:
@@ -64,27 +69,37 @@ async def get_transcript(req: TranscriptRequest):
64
  if caption_url.startswith("/"):
65
  caption_url = f"{host}{caption_url}"
66
 
67
- # 3. Fetch the actual caption XML
68
- cap_res = requests.get(caption_url, timeout=5)
 
 
69
  if cap_res.status_code != 200:
70
  continue
71
 
72
- # 4. Parse XML to plain text
73
- texts = re.findall(r'<text[^>]*>([^<]*)</text>', cap_res.text)
 
 
 
 
 
 
 
 
74
  if not texts:
75
  continue
76
 
77
  full_text = " ".join(texts)
78
- full_text = full_text.replace("&amp;#39;", "'").replace("&amp;quot;", '"').replace("&amp;amp;", "&").replace("&#39;", "'").replace("\n", " ")
79
 
80
  print(f"Successfully fetched transcript from {host}. Length: {len(full_text)} chars")
81
  return {"text": full_text}
82
 
83
  except Exception as e:
84
  print(f"Failed on {host}: {e}")
85
- continue # Try next instance
86
-
87
- raise HTTPException(status_code=500, detail="Failed to fetch transcript. All sources timed out or are blocked.")
88
 
89
  # ========================================================
90
  # TRANSLATE API
 
33
  if not video_id:
34
  raise HTTPException(status_code=400, detail="Invalid YouTube URL")
35
 
36
+ # Using Piped API - much more reliable on cloud servers than Invidious
37
  instances = [
38
+ "https://pipedapi.kavin.rocks",
39
+ "https://pipedapi.adminforge.de",
40
+ "https://piped-api.privacy.com.de",
41
+ "https://api.piped.projectsegfau.lt"
42
  ]
43
 
44
  for host in instances:
45
  try:
46
+ print(f"Trying Piped instance {host} for video {video_id}...")
47
+
48
+ # 1. Fetch video stream data (contains caption list)
49
+ res = requests.get(f"{host}/streams/{video_id}", timeout=8)
50
 
51
  if res.status_code != 200:
52
+ print(f"Failed on {host}: Status {res.status_code}")
53
+ continue
54
 
55
  data = res.json()
56
+ captions = data.get("captions", [])
 
57
 
58
+ if not captions:
59
+ print(f"No captions on {host}")
60
+ continue
61
+
62
+ # 2. Find English caption (or first available)
63
+ caption = next((c for c in captions if c.get("code") == "en" or "English" in c.get("name", "")), captions[0])
64
  caption_url = caption.get("url")
65
 
66
  if not caption_url:
 
69
  if caption_url.startswith("/"):
70
  caption_url = f"{host}{caption_url}"
71
 
72
+ print(f"Fetching caption data from {caption_url}...")
73
+
74
+ # 3. Fetch the JSON caption data
75
+ cap_res = requests.get(caption_url, timeout=8)
76
  if cap_res.status_code != 200:
77
  continue
78
 
79
+ cap_data = cap_res.json()
80
+
81
+ # 4. Parse Piped JSON captions into plain text
82
+ texts = []
83
+ for event in cap_data.get("events", []):
84
+ for seg in event.get("segs", []):
85
+ text = seg.get("utf8", "").strip()
86
+ if text and text != "\n":
87
+ texts.append(text)
88
+
89
  if not texts:
90
  continue
91
 
92
  full_text = " ".join(texts)
93
+ full_text = full_text.replace("&amp;#39;", "'").replace("&amp;quot;", '"').replace("&amp;amp;", "&").replace("&#39;", "'")
94
 
95
  print(f"Successfully fetched transcript from {host}. Length: {len(full_text)} chars")
96
  return {"text": full_text}
97
 
98
  except Exception as e:
99
  print(f"Failed on {host}: {e}")
100
+ continue
101
+
102
+ raise HTTPException(status_code=500, detail="Failed to fetch transcript. All sources timed out or video has no captions.")
103
 
104
  # ========================================================
105
  # TRANSLATE API