"""UI logic for the "Analitzar video-transcripcions" page.""" from __future__ import annotations from pathlib import Path from typing import Dict import streamlit as st from utils import save_bytes def render_analyze_transcriptions_page(api, permissions: Dict[str, bool]) -> None: st.header("Analitzar video-transcripcions") base_dir = Path("/tmp/data/videos") if not base_dir.exists(): st.info("No s'ha trobat la carpeta **videos**. Crea-la i afegeix-hi subcarpetes amb els teus vídeos.") st.stop() carpetes = [p.name for p in sorted(base_dir.iterdir()) if p.is_dir() and p.name != "completed"] if not carpetes: st.info("No s'ha trobat la carpeta **videos**. Crea-la i afegeix-hi subcarpetes amb els teus vídeos.") st.stop() if "current_video" not in st.session_state: st.session_state.current_video = None seleccio = st.selectbox("Selecciona un vídeo (carpeta):", carpetes, index=None, placeholder="Tria una carpeta…") if seleccio != st.session_state.current_video: st.session_state.current_video = seleccio if "version_selector" in st.session_state: del st.session_state["version_selector"] st.session_state.add_ad_checkbox = False st.rerun() if not seleccio: st.stop() vid_dir = base_dir / seleccio mp4s = sorted(vid_dir.glob("*.mp4")) col_video, col_txt = st.columns([2, 1], gap="large") with col_video: subcarpetas_ad = [p.name for p in sorted(vid_dir.iterdir()) if p.is_dir()] default_index_sub = subcarpetas_ad.index("Salamandra") if "Salamandra" in subcarpetas_ad else 0 subcarpeta_seleccio = st.selectbox( "Selecciona una versió d'audiodescripció:", subcarpetas_ad, index=default_index_sub if subcarpetas_ad else None, placeholder="Tria una versió…" if subcarpetas_ad else "No hi ha versions", key="version_selector", ) video_ad_path = vid_dir / subcarpeta_seleccio / "une_ad.mp4" if subcarpeta_seleccio else None is_ad_video_available = video_ad_path is not None and video_ad_path.exists() add_ad_video = st.checkbox( "Afegir audiodescripció", disabled=not is_ad_video_available, key="add_ad_checkbox", ) video_to_show = None if add_ad_video and is_ad_video_available: video_to_show = video_ad_path elif mp4s: video_to_show = mp4s[0] if video_to_show: st.video(str(video_to_show)) else: st.warning("No s'ha trobat cap fitxer **.mp4** a la carpeta seleccionada.") st.markdown("---") st.markdown("#### Accions") c1, c2 = st.columns(2) with c1: if st.button("Reconstruir àudio amb narració lliure", use_container_width=True, key="rebuild_free_ad"): if subcarpeta_seleccio: free_ad_path = vid_dir / subcarpeta_seleccio / "free_ad.txt" if free_ad_path.exists(): with st.spinner("Generant àudio de la narració lliure..."): text_content = free_ad_path.read_text(encoding="utf-8") voice = "central/grau" response = api.tts_matxa(text=text_content, voice=voice) if "mp3_bytes" in response: output_path = vid_dir / subcarpeta_seleccio / "free_ad.mp3" save_bytes(output_path, response["mp3_bytes"]) st.success(f"Àudio generat i desat a: {output_path}") else: st.error(f"Error en la generació de l'àudio: {response.get('error', 'Desconegut')}") else: st.warning("No s'ha trobat el fitxer 'free_ad.txt' en aquesta versió.") with c2: if st.button("Reconstruir vídeo amb audiodescripció", use_container_width=True, key="rebuild_video_ad"): if subcarpeta_seleccio and mp4s: une_srt_path = vid_dir / subcarpeta_seleccio / "une_ad.srt" video_original_path = mp4s[0] if une_srt_path.exists(): with st.spinner( "Reconstruint el vídeo amb l'audiodescripció... Aquesta operació pot trigar una estona." ): response = api.rebuild_video_with_ad( video_path=str(video_original_path), srt_path=str(une_srt_path), ) if "video_bytes" in response: output_path = vid_dir / subcarpeta_seleccio / "video_ad_rebuilt.mp4" save_bytes(output_path, response["video_bytes"]) st.success(f"Vídeo reconstruït i desat a: {output_path}") st.info( "Pots visualitzar-lo activant la casella 'Afegir audiodescripció' i seleccionant el nou fitxer si cal." ) else: st.error(f"Error en la reconstrucció del vídeo: {response.get('error', 'Desconegut')}") else: st.warning("No s'ha trobat el fitxer 'une_ad.srt' en aquesta versió.") with col_txt: tipus_ad_options = ["narració lliure", "UNE-153010"] tipus_ad_seleccio = st.selectbox("Fitxer d'audiodescripció a editar:", tipus_ad_options) ad_filename = "free_ad.txt" if tipus_ad_seleccio == "narració lliure" else "une_ad.srt" text_content = "" ad_path = None if subcarpeta_seleccio: ad_path = vid_dir / subcarpeta_seleccio / ad_filename if ad_path.exists(): try: text_content = ad_path.read_text(encoding="utf-8") except Exception: text_content = ad_path.read_text(errors="ignore") else: st.info(f"No s'ha trobat el fitxer **{ad_filename}**.") else: st.warning("Selecciona una versió per veure els fitxers.") new_text = st.text_area( f"Contingut de {tipus_ad_seleccio}", value=text_content, height=500, key=f"editor_{seleccio}_{subcarpeta_seleccio}_{ad_filename}", ) if st.button( "▶️ Reproduir narració", use_container_width=True, disabled=not new_text.strip(), key="play_button_editor", ): with st.spinner("Generant àudio..."): pass if st.button("Desar canvis", use_container_width=True, type="primary"): if ad_path: try: ad_path.write_text(new_text, encoding="utf-8") st.success(f"Fitxer **{ad_filename}** desat correctament.") st.rerun() except Exception as e: st.error(f"No s'ha pogut desar el fitxer: {e}") else: st.error("No s'ha seleccionat una ruta de fitxer vàlida per desar.") st.markdown("---") st.subheader("Avaluació de la qualitat de l'audiodescripció") can_rate = permissions.get("valorar", False) controls_disabled = not can_rate c1, c2, c3 = st.columns(3) with c1: transcripcio = st.slider("Transcripció", 1, 10, 7, disabled=controls_disabled) identificacio = st.slider("Identificació de personatges", 1, 10, 7, disabled=controls_disabled) with c2: localitzacions = st.slider("Localitzacions", 1, 10, 7, disabled=controls_disabled) activitats = st.slider("Activitats", 1, 10, 7, disabled=controls_disabled) with c3: narracions = st.slider("Narracions", 1, 10, 7, disabled=controls_disabled) expressivitat = st.slider("Expressivitat", 1, 10, 7, disabled=controls_disabled) comments = st.text_area( "Comentaris (opcional)", placeholder="Escriu els teus comentaris lliures…", height=120, disabled=controls_disabled, ) if not can_rate: st.info("El teu rol no permet enviar valoracions.") else: if st.button("Enviar valoració", type="primary", use_container_width=True): try: from database import add_feedback_ad add_feedback_ad( video_name=seleccio, user_id=st.session_state.user["id"], transcripcio=transcripcio, identificacio=identificacio, localitzacions=localitzacions, activitats=activitats, narracions=narracions, expressivitat=expressivitat, comments=comments or None, ) st.success("Gràcies! La teva valoració s'ha desat correctament.") except Exception as e: st.error(f"S'ha produït un error en desar la valoració: {e}")