Add get_video_thumbnails function and update transcript handling to include thumbnail URLs
This commit is contained in:
parent
f8924a2965
commit
344fd5809a
166
main.py
166
main.py
@ -161,8 +161,8 @@ def format_segments_text(segments: List[Dict]) -> List[str]:
|
|||||||
return ''
|
return ''
|
||||||
s = str(t).strip()
|
s = str(t).strip()
|
||||||
s = re.sub(r'^\s*Kind\s*:\s*.*$', '', s, flags=re.IGNORECASE).strip()
|
s = re.sub(r'^\s*Kind\s*:\s*.*$', '', s, flags=re.IGNORECASE).strip()
|
||||||
# eliminar contenido entre corchetes, patrón seguro para corchetes
|
# eliminar contenido entre corchetes (no-greedy)
|
||||||
s = re.sub(r'\[[^\]]*\]', '', s)
|
s = re.sub(r'\[.*?\]', '', s)
|
||||||
s = re.sub(r'\(.*?\)', '', s)
|
s = re.sub(r'\(.*?\)', '', s)
|
||||||
s = re.sub(r'<[^>]+>', '', s)
|
s = re.sub(r'<[^>]+>', '', s)
|
||||||
s = re.sub(r'[♪★■◆►▶◀•–—]', '', s)
|
s = re.sub(r'[♪★■◆►▶◀•–—]', '', s)
|
||||||
@ -180,10 +180,83 @@ def format_segments_text(segments: List[Dict]) -> List[str]:
|
|||||||
return output
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
# Nuevo helper: obtener thumbnails para un video (intenta yt-dlp --dump-json, fallback a URLs estándar)
|
||||||
|
def get_video_thumbnails(video_id: str) -> List[str]:
|
||||||
|
"""Devuelve una lista de URLs de thumbnail para el video.
|
||||||
|
Primero intenta obtener metadata con yt-dlp y extraer 'thumbnails' o 'thumbnail'.
|
||||||
|
Si falla, construye una lista de URLs por defecto (maxresdefault, sddefault, hqdefault, mqdefault, default).
|
||||||
|
"""
|
||||||
|
thumbs: List[str] = []
|
||||||
|
url = f"https://www.youtube.com/watch?v={video_id}"
|
||||||
|
|
||||||
|
cookie_mgr = CookieManager()
|
||||||
|
cookiefile_path = cookie_mgr.get_cookiefile_path()
|
||||||
|
cookies_path = cookiefile_path or os.getenv('API_COOKIES_PATH', DEFAULT_COOKIES_PATH)
|
||||||
|
proxy = os.getenv('API_PROXY', DEFAULT_PROXY) or None
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
"yt-dlp",
|
||||||
|
"--skip-download",
|
||||||
|
"--dump-json",
|
||||||
|
"--no-warnings",
|
||||||
|
url
|
||||||
|
]
|
||||||
|
if os.path.exists(cookies_path):
|
||||||
|
cmd.extend(["--cookies", cookies_path])
|
||||||
|
if proxy:
|
||||||
|
cmd.extend(['--proxy', proxy])
|
||||||
|
|
||||||
|
try:
|
||||||
|
proc = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
||||||
|
if proc.returncode == 0 and proc.stdout:
|
||||||
|
try:
|
||||||
|
meta = json.loads(proc.stdout)
|
||||||
|
# thumbnails puede ser lista de dicts con 'url'
|
||||||
|
t = meta.get('thumbnails') or meta.get('thumbnail')
|
||||||
|
if isinstance(t, list):
|
||||||
|
for item in t:
|
||||||
|
if isinstance(item, dict) and item.get('url'):
|
||||||
|
thumbs.append(item.get('url'))
|
||||||
|
elif isinstance(item, str):
|
||||||
|
thumbs.append(item)
|
||||||
|
elif isinstance(t, dict) and t.get('url'):
|
||||||
|
thumbs.append(t.get('url'))
|
||||||
|
elif isinstance(t, str):
|
||||||
|
thumbs.append(t)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
try:
|
||||||
|
cookie_mgr.cleanup()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Si no obtuvimos thumbnails desde metadata, construir URLs estándar
|
||||||
|
if not thumbs:
|
||||||
|
thumbs = [
|
||||||
|
f"https://i.ytimg.com/vi/{video_id}/maxresdefault.jpg",
|
||||||
|
f"https://i.ytimg.com/vi/{video_id}/sddefault.jpg",
|
||||||
|
f"https://i.ytimg.com/vi/{video_id}/hqdefault.jpg",
|
||||||
|
f"https://i.ytimg.com/vi/{video_id}/mqdefault.jpg",
|
||||||
|
f"https://i.ytimg.com/vi/{video_id}/default.jpg",
|
||||||
|
]
|
||||||
|
|
||||||
|
# deduplicate while preserving order
|
||||||
|
seen = set()
|
||||||
|
unique_thumbs = []
|
||||||
|
for t in thumbs:
|
||||||
|
if t and t not in seen:
|
||||||
|
seen.add(t)
|
||||||
|
unique_thumbs.append(t)
|
||||||
|
|
||||||
|
return unique_thumbs
|
||||||
|
|
||||||
def get_transcript_data(video_id: str, lang: str = "es"):
|
def get_transcript_data(video_id: str, lang: str = "es"):
|
||||||
video_id = extract_video_id(video_id)
|
video_id = extract_video_id(video_id)
|
||||||
if not video_id:
|
if not video_id:
|
||||||
return None, "video_id inválido o vacío"
|
return None, [], "video_id inválido o vacío"
|
||||||
|
|
||||||
url = f"https://www.youtube.com/watch?v={video_id}"
|
url = f"https://www.youtube.com/watch?v={video_id}"
|
||||||
|
|
||||||
@ -262,9 +335,9 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
# Si yt-dlp falló por rate limiting, devolver mensaje claro
|
# Si yt-dlp falló por rate limiting, devolver mensaje claro
|
||||||
stderr = (result.stderr or "").lower()
|
stderr = (result.stderr or "").lower()
|
||||||
if result.returncode != 0 and ('http error 429' in stderr or 'too many requests' in stderr):
|
if result.returncode != 0 and ('http error 429' in stderr or 'too many requests' in stderr):
|
||||||
return None, "YouTube está limitando las peticiones al descargar subtítulos (HTTP 429). Agrega un cookies.txt válido exportado desde tu navegador y monta en el contenedor, o espera unos minutos."
|
return None, get_video_thumbnails(video_id), "YouTube está limitando las peticiones al descargar subtítulos (HTTP 429). Agrega un cookies.txt válido exportado desde tu navegador y monta en el contenedor, o espera unos minutos."
|
||||||
if result.returncode != 0 and ('http error 403' in stderr or 'forbidden' in stderr):
|
if result.returncode != 0 and ('http error 403' in stderr or 'forbidden' in stderr):
|
||||||
return None, "Acceso denegado al descargar subtítulos (HTTP 403). El video puede tener restricciones. Usa cookies.txt con una cuenta autorizada."
|
return None, get_video_thumbnails(video_id), "Acceso denegado al descargar subtítulos (HTTP 403). El video puede tener restricciones. Usa cookies.txt con una cuenta autorizada."
|
||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -282,7 +355,7 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
vtt_combined = "\n".join(combined)
|
vtt_combined = "\n".join(combined)
|
||||||
parsed = parse_subtitle_format(vtt_combined, 'vtt')
|
parsed = parse_subtitle_format(vtt_combined, 'vtt')
|
||||||
if parsed:
|
if parsed:
|
||||||
return parsed, None
|
return parsed, get_video_thumbnails(video_id), None
|
||||||
finally:
|
finally:
|
||||||
# cleanup any temp cookiefile created for this request
|
# cleanup any temp cookiefile created for this request
|
||||||
try:
|
try:
|
||||||
@ -325,7 +398,7 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
except subprocess.TimeoutExpired:
|
except subprocess.TimeoutExpired:
|
||||||
video_metadata = None
|
video_metadata = None
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return None, "yt-dlp no está instalado en el contenedor/entorno. Instala yt-dlp y vuelve a intentar."
|
return None, get_video_thumbnails(video_id), "yt-dlp no está instalado en el contenedor/entorno. Instala yt-dlp y vuelve a intentar."
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
video_metadata = None
|
video_metadata = None
|
||||||
|
|
||||||
@ -380,19 +453,19 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
# salir del loop y usar fallback con yt-dlp más abajo
|
# salir del loop y usar fallback con yt-dlp más abajo
|
||||||
break
|
break
|
||||||
elif response.status_code == 403:
|
elif response.status_code == 403:
|
||||||
return None, "Acceso denegado (HTTP 403). El video puede tener restricciones de edad o región. Intenta con cookies.txt."
|
return None, get_video_thumbnails(video_id), "Acceso denegado (HTTP 403). El video puede tener restricciones de edad o región. Intenta con cookies.txt."
|
||||||
elif response.status_code == 404:
|
elif response.status_code == 404:
|
||||||
# No encontramos la URL esperada; intentar fallback
|
# No encontramos la URL esperada; intentar fallback
|
||||||
response = None
|
response = None
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
return None, f"Error al descargar subtítulos desde YouTube (HTTP {response.status_code})."
|
return None, get_video_thumbnails(video_id), f"Error al descargar subtítulos desde YouTube (HTTP {response.status_code})."
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
if attempt < max_retries - 1:
|
if attempt < max_retries - 1:
|
||||||
continue
|
continue
|
||||||
return None, "Timeout al descargar subtítulos. Intenta nuevamente."
|
return None, get_video_thumbnails(video_id), "Timeout al descargar subtítulos. Intenta nuevamente."
|
||||||
except requests.exceptions.RequestException as e:
|
except requests.exceptions.RequestException as e:
|
||||||
return None, f"Error de conexión al descargar subtítulos: {str(e)[:100]}"
|
return None, get_video_thumbnails(video_id), f"Error de conexión al descargar subtítulos: {str(e)[:100]}"
|
||||||
|
|
||||||
# Si obtuvimos un 200, procesarlo; si hubo rate limiting, intentar fallback con yt-dlp
|
# Si obtuvimos un 200, procesarlo; si hubo rate limiting, intentar fallback con yt-dlp
|
||||||
if response and response.status_code == 200:
|
if response and response.status_code == 200:
|
||||||
@ -443,9 +516,9 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
stderr2 = (res2.stderr or "").lower()
|
stderr2 = (res2.stderr or "").lower()
|
||||||
if res2.returncode != 0 and ('http error 429' in stderr2 or 'too many requests' in stderr2):
|
if res2.returncode != 0 and ('http error 429' in stderr2 or 'too many requests' in stderr2):
|
||||||
# rate limit cuando intentamos descargar timedtext
|
# rate limit cuando intentamos descargar timedtext
|
||||||
return None, "YouTube está limitando las peticiones al descargar subtítulos (HTTP 429). Agrega cookies.txt válido o intenta más tarde."
|
return None, get_video_thumbnails(video_id), "YouTube está limitando las peticiones al descargar subtítulos (HTTP 429). Agrega cookies.txt válido o intenta más tarde."
|
||||||
if res2.returncode != 0 and ('http error 403' in stderr2 or 'forbidden' in stderr2):
|
if res2.returncode != 0 and ('http error 403' in stderr2 or 'forbidden' in stderr2):
|
||||||
return None, "Acceso denegado al descargar subtítulos (HTTP 403). Intenta con cookies.txt o una cuenta con permisos."
|
return None, get_video_thumbnails(video_id), "Acceso denegado al descargar subtítulos (HTTP 403). Intenta con cookies.txt o una cuenta con permisos."
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -465,7 +538,7 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
vtt_combined = "\n".join(combined)
|
vtt_combined = "\n".join(combined)
|
||||||
formatted_transcript = parse_subtitle_format(vtt_combined, 'vtt')
|
formatted_transcript = parse_subtitle_format(vtt_combined, 'vtt')
|
||||||
if formatted_transcript:
|
if formatted_transcript:
|
||||||
return formatted_transcript, None
|
return formatted_transcript, get_video_thumbnails(video_id), None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
subtitle_data = response.json()
|
subtitle_data = response.json()
|
||||||
@ -473,12 +546,12 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
formatted_transcript = parse_subtitle_format(response.text, subtitle_format)
|
formatted_transcript = parse_subtitle_format(response.text, subtitle_format)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return None, f"Error al procesar los subtítulos: {str(e)[:200]}"
|
return None, get_video_thumbnails(video_id), f"Error al procesar los subtítulos: {str(e)[:200]}"
|
||||||
|
|
||||||
if not formatted_transcript:
|
if not formatted_transcript:
|
||||||
return None, "Los subtítulos están vacíos o no se pudieron procesar."
|
return None, get_video_thumbnails(video_id), "Los subtítulos están vacíos o no se pudieron procesar."
|
||||||
|
|
||||||
return formatted_transcript, None
|
return formatted_transcript, get_video_thumbnails(video_id), None
|
||||||
# Si hubo rate limiting, intentar fallback con yt-dlp para descargar la URL de subtítulos
|
# Si hubo rate limiting, intentar fallback con yt-dlp para descargar la URL de subtítulos
|
||||||
if rate_limited and (not response or response.status_code != 200):
|
if rate_limited and (not response or response.status_code != 200):
|
||||||
# Intentar descargar la URL de subtítulos directamente con yt-dlp (usa cookies si existen)
|
# Intentar descargar la URL de subtítulos directamente con yt-dlp (usa cookies si existen)
|
||||||
@ -499,7 +572,7 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
res = subprocess.run(ytdlp_cmd, capture_output=True, text=True, timeout=90)
|
res = subprocess.run(ytdlp_cmd, capture_output=True, text=True, timeout=90)
|
||||||
stderr = (res.stderr or "").lower()
|
stderr = (res.stderr or "").lower()
|
||||||
if res.returncode != 0 and ('http error 429' in stderr or 'too many requests' in stderr):
|
if res.returncode != 0 and ('http error 429' in stderr or 'too many requests' in stderr):
|
||||||
return None, "YouTube está limitando las peticiones al descargar subtítulos (HTTP 429). Agrega cookies.txt válido o intenta más tarde."
|
return None, get_video_thumbnails(video_id), "YouTube está limitando las peticiones al descargar subtítulos (HTTP 429). Agrega cookies.txt válido o intenta más tarde."
|
||||||
# Leer archivos generados
|
# Leer archivos generados
|
||||||
combined = []
|
combined = []
|
||||||
for fpath in glob.glob(os.path.join(tdir, "*.*")):
|
for fpath in glob.glob(os.path.join(tdir, "*.*")):
|
||||||
@ -514,9 +587,9 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
vtt_combined = "\n".join(combined)
|
vtt_combined = "\n".join(combined)
|
||||||
formatted_transcript = parse_subtitle_format(vtt_combined, 'vtt')
|
formatted_transcript = parse_subtitle_format(vtt_combined, 'vtt')
|
||||||
if formatted_transcript:
|
if formatted_transcript:
|
||||||
return formatted_transcript, None
|
return formatted_transcript, get_video_thumbnails(video_id), None
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return None, "yt-dlp no está instalado en el contenedor/entorno. Instala yt-dlp y vuelve a intentar."
|
return None, get_video_thumbnails(video_id), "yt-dlp no está instalado en el contenedor/entorno. Instala yt-dlp y vuelve a intentar."
|
||||||
except Exception:
|
except Exception:
|
||||||
# seguir con otros fallbacks
|
# seguir con otros fallbacks
|
||||||
pass
|
pass
|
||||||
@ -567,22 +640,22 @@ def get_transcript_data(video_id: str, lang: str = "es"):
|
|||||||
with open(downloaded, 'r', encoding='utf-8') as fh:
|
with open(downloaded, 'r', encoding='utf-8') as fh:
|
||||||
content = fh.read()
|
content = fh.read()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return None, f"Error leyendo archivo de subtítulos descargado: {str(e)[:200]}"
|
return None, get_video_thumbnails(video_id), f"Error leyendo archivo de subtítulos descargado: {str(e)[:200]}"
|
||||||
|
|
||||||
# Intentar parsear según extensión conocida
|
# Intentar parsear según extensión conocida
|
||||||
fmt = 'json3' if ext in ('json', 'json3') else ('vtt' if ext == 'vtt' else 'srv3')
|
fmt = 'json3' if ext in ('json', 'json3') else ('vtt' if ext == 'vtt' else 'srv3')
|
||||||
formatted_transcript = parse_subtitle_format(content, fmt)
|
formatted_transcript = parse_subtitle_format(content, fmt)
|
||||||
if formatted_transcript:
|
if formatted_transcript:
|
||||||
return formatted_transcript, None
|
return formatted_transcript, get_video_thumbnails(video_id), None
|
||||||
else:
|
else:
|
||||||
return None, "Se descargaron subtítulos pero no se pudieron procesar."
|
return None, get_video_thumbnails(video_id), "Se descargaron subtítulos pero no se pudieron procesar."
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return None, "yt-dlp no está instalado. Instala yt-dlp en el contenedor/entorno y vuelve a intentar."
|
return None, get_video_thumbnails(video_id), "yt-dlp no está instalado. Instala yt-dlp en el contenedor/entorno y vuelve a intentar."
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# No hacer crash, retornar mensaje general
|
# No hacer crash, retornar mensaje general
|
||||||
return None, f"Error al intentar descargar subtítulos con yt-dlp: {str(e)[:200]}"
|
return None, get_video_thumbnails(video_id), f"Error al intentar descargar subtítulos con yt-dlp: {str(e)[:200]}"
|
||||||
|
|
||||||
return None, "No se encontraron subtítulos para este video (o el video no tiene subtítulos disponibles). Intenta con otro video en vivo o agrega cookies.txt si hay restricciones."
|
return None, get_video_thumbnails(video_id), "No se encontraron subtítulos para este video (o el video no tiene subtítulos disponibles). Intenta con otro video en vivo o agrega cookies.txt si hay restricciones."
|
||||||
|
|
||||||
def get_stream_url(video_id: str):
|
def get_stream_url(video_id: str):
|
||||||
"""
|
"""
|
||||||
@ -664,7 +737,7 @@ def get_stream_url(video_id: str):
|
|||||||
|
|
||||||
@app.get("/transcript/{video_id}")
|
@app.get("/transcript/{video_id}")
|
||||||
def transcript_endpoint(video_id: str, lang: str = "es"):
|
def transcript_endpoint(video_id: str, lang: str = "es"):
|
||||||
data, error = get_transcript_data(video_id, lang)
|
data, thumbnails, error = get_transcript_data(video_id, lang)
|
||||||
|
|
||||||
if error:
|
if error:
|
||||||
raise HTTPException(status_code=400, detail=error)
|
raise HTTPException(status_code=400, detail=error)
|
||||||
@ -688,7 +761,34 @@ def transcript_endpoint(video_id: str, lang: str = "es"):
|
|||||||
"count": len(data),
|
"count": len(data),
|
||||||
"segments": data,
|
"segments": data,
|
||||||
"text": combined_text,
|
"text": combined_text,
|
||||||
"format_text": format_text
|
"format_text": format_text,
|
||||||
|
"thumbnails": thumbnails
|
||||||
|
}
|
||||||
|
|
||||||
|
@app.get('/transcript_vtt/{video_id}')
|
||||||
|
def transcript_vtt(video_id: str, lang: str = 'es'):
|
||||||
|
"""Descarga (con yt-dlp) y devuelve subtítulos en VTT, además de segmentos parseados y texto concatenado."""
|
||||||
|
vtt_text, error = fetch_vtt_subtitles(video_id, lang)
|
||||||
|
if error:
|
||||||
|
raise HTTPException(status_code=400, detail=error)
|
||||||
|
|
||||||
|
# parsear VTT a segmentos usando parse_subtitle_format
|
||||||
|
segments = parse_subtitle_format(vtt_text, 'vtt') if vtt_text else []
|
||||||
|
|
||||||
|
combined_text = '\n'.join([s.get('text','') for s in segments])
|
||||||
|
# format_text con texto limpio listo para procesamiento por agentes
|
||||||
|
format_text = format_segments_text(segments)
|
||||||
|
|
||||||
|
thumbnails = get_video_thumbnails(video_id)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'video_id': video_id,
|
||||||
|
'vtt': vtt_text,
|
||||||
|
'count': len(segments),
|
||||||
|
'segments': segments,
|
||||||
|
'text': combined_text,
|
||||||
|
'format_text': format_text,
|
||||||
|
'thumbnails': thumbnails
|
||||||
}
|
}
|
||||||
|
|
||||||
@app.get("/stream/{video_id}")
|
@app.get("/stream/{video_id}")
|
||||||
@ -708,6 +808,8 @@ def stream_endpoint(video_id: str):
|
|||||||
if error:
|
if error:
|
||||||
raise HTTPException(status_code=400, detail=error)
|
raise HTTPException(status_code=400, detail=error)
|
||||||
|
|
||||||
|
thumbnails = get_video_thumbnails(video_id)
|
||||||
|
|
||||||
# Determinar el tipo de URL obtenida
|
# Determinar el tipo de URL obtenida
|
||||||
url_type = "unknown"
|
url_type = "unknown"
|
||||||
if "m3u8" in stream_url.lower():
|
if "m3u8" in stream_url.lower():
|
||||||
@ -721,6 +823,7 @@ def stream_endpoint(video_id: str):
|
|||||||
"url_type": url_type,
|
"url_type": url_type,
|
||||||
"youtube_url": f"https://www.youtube.com/watch?v={video_id}",
|
"youtube_url": f"https://www.youtube.com/watch?v={video_id}",
|
||||||
"ffmpeg_example": f'ffmpeg -re -i "{stream_url}" -c copy -f flv rtmp://destino/stream_key',
|
"ffmpeg_example": f'ffmpeg -re -i "{stream_url}" -c copy -f flv rtmp://destino/stream_key',
|
||||||
|
"thumbnails": thumbnails,
|
||||||
"usage": {
|
"usage": {
|
||||||
"description": "Usa stream_url con FFmpeg para retransmitir",
|
"description": "Usa stream_url con FFmpeg para retransmitir",
|
||||||
"command_template": "ffmpeg -re -i \"{stream_url}\" -c copy -f flv {rtmp_url}/{stream_key}",
|
"command_template": "ffmpeg -re -i \"{stream_url}\" -c copy -f flv {rtmp_url}/{stream_key}",
|
||||||
@ -1034,13 +1137,16 @@ def transcript_vtt(video_id: str, lang: str = 'es'):
|
|||||||
# format_text con texto limpio listo para procesamiento por agentes
|
# format_text con texto limpio listo para procesamiento por agentes
|
||||||
format_text = format_segments_text(segments)
|
format_text = format_segments_text(segments)
|
||||||
|
|
||||||
|
thumbnails = get_video_thumbnails(video_id)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'video_id': video_id,
|
'video_id': video_id,
|
||||||
'vtt': vtt_text,
|
'vtt': vtt_text,
|
||||||
'count': len(segments),
|
'count': len(segments),
|
||||||
'segments': segments,
|
'segments': segments,
|
||||||
'text': combined_text,
|
'text': combined_text,
|
||||||
'format_text': format_text
|
'format_text': format_text,
|
||||||
|
'thumbnails': thumbnails
|
||||||
}
|
}
|
||||||
|
|
||||||
@app.post('/upload_vtt/{video_id}')
|
@app.post('/upload_vtt/{video_id}')
|
||||||
@ -1119,6 +1225,8 @@ def transcript_alt(video_id: str, lang: str = 'es'):
|
|||||||
combined_text = '\n'.join([s['text'] for s in segments if s.get('text')])
|
combined_text = '\n'.join([s['text'] for s in segments if s.get('text')])
|
||||||
format_text = format_segments_text(segments)
|
format_text = format_segments_text(segments)
|
||||||
|
|
||||||
|
thumbnails = get_video_thumbnails(vid)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'video_id': vid,
|
'video_id': vid,
|
||||||
'count': len(segments),
|
'count': len(segments),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user