File size: 9,325 Bytes
d345661 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
"""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}")
|