El Atributo ONSEEKED

El atributo onseeked se dispara cuando un usuario finaliza un cambio de posición en un elemento audio o video.

El atributo onseeked se dispara cuando un usuario finaliza un cambio de posición en un elemento <audio> o <video>. Es clave para sincronizar interfaces y manejar acciones posteriores a la navegación manual en la línea de tiempo.


???? Sintaxis básica

html
Copy
<video 
    id="miVideo" 
    src="video.mp4" 
    onseeked="manejarSeeked(event)"
></video>
javascript
Copy
// Método alternativo con JavaScript
document.getElementById("miVideo").addEventListener("seeked", (event) => {
    // Lógica aquí
});

???? Características clave

  • Se activa después de que la operación de búsqueda (seek) se completa.

  • Ideal para actualizar UI o cargar recursos relacionados con el nuevo tiempo.

  • Funciona junto con onseeking (que detecta el inicio de la búsqueda).


???? Ejemplos prácticos

1. Actualizar tiempo actual en la interfaz

html
Copy
<video id="reproductor" src="video.mp4" controls onseeked="actualizarTiempo()"></video>
<p>Tiempo actual: <span id="tiempoActual">0:00</span></p>

<script>
function actualizarTiempo() {
    const video = document.getElementById("reproductor");
    const minutos = Math.floor(video.currentTime / 60);
    const segundos = Math.floor(video.currentTime % 60);
    document.getElementById("tiempoActual").textContent = 
        `${minutos}:${segundos.toString().padStart(2, '0')}`;
}
</script>

2. Cargar subtítulos dinámicos

html
Copy
<video id="videoTutorial" src="clase.mp4" controls onseeked="cargarSubtitulos()"></video>
<div id="subtitulos"></div>

<script>
const subtitulos = {
    10: "Introducción al tema",
    30: "Conceptos clave",
    60: "Ejemplo práctico"
};

function cargarSubtitulos() {
    const video = document.getElementById("videoTutorial");
    const tiempoActual = Math.floor(video.currentTime);
    document.getElementById("subtitulos").textContent = 
        subtitulos[tiempoActual] || "";
}
</script>

3. Sistema de análisis de navegación

javascript
Copy
let tiempoInicioSeek = 0;

video.addEventListener("seeking", () => {
    tiempoInicioSeek = Date.now();
});

video.addEventListener("seeked", () => {
    const duracionSeek = Date.now() - tiempoInicioSeek;
    console.log(`Búsqueda completada en ${duracionSeek}ms`);
    analytics.track("video_seek", {
        tiempoAnterior: video.previousTime,
        tiempoNuevo: video.currentTime
    });
});

???? Casos de uso avanzados

1. Precarga de fragmentos

javascript
Copy
video.addEventListener("seeked", async () => {
    const tiempoActual = video.currentTime;
    const siguienteSegmento = tiempoActual + 30; // Precargar próximos 30 segundos
    
    // Precargar fragmento desde API
    const respuesta = await fetch(`/api/video-fragment?start=${tiempoActual}&end=${siguienteSegmento}`);
    const buffer = await respuesta.arrayBuffer();
    
    // Almacenar en caché para reproducción fluida
    video.buffered.append(new Uint8Array(buffer));
});

2. Marcadores interactivos

html
Copy
<video id="videoCurso" src="curso.mp4" onseeked="resaltarMarcador()"></video>
<div class="marcadores">
    <div data-tiempo="15" onclick="saltarATiempo(15)">Introducción</div>
    <div data-tiempo="90" onclick="saltarATiempo(90)">Ejercicio</div>
</div>

<script>
function saltarATiempo(segundos) {
    const video = document.getElementById("videoCurso");
    video.currentTime = segundos;
}

function resaltarMarcador() {
    const tiempoActual = document.getElementById("videoCurso").currentTime;
    document.querySelectorAll(".marcadores div").forEach(marcador => {
        const tiempoMarcador = parseFloat(marcador.dataset.tiempo);
        marcador.style.background = tiempoActual >= tiempoMarcador ? "#2ecc71" : "#eee";
    });
}
</script>

⚠️ Consideraciones importantes

1. Diferencias entre eventos

Evento Descripción
onseeking Cuando comienza el cambio de posición
onseeked Cuando finaliza el cambio de posición
ontimeupdate Durante la reproducción normal

2. Compatibilidad

Navegador Soporte
Chrome ✅ 15+
Firefox ✅ 12+
Safari ✅ 6+
Edge ✅ 12+

3. Buenas prácticas

  • Debounce para múltiples eventos: Evitar procesamiento excesivo en búsquedas rápidas

  • Manejar errores: Algunos navegadores no disparan el evento si el salto es instantáneo

  • Optimizar rendimiento: Usar requestAnimationFrame para actualizaciones visuales


???? Solución de problemas comunes

Problema: El evento no se dispara en saltos pequeños

javascript
Copy
// Forzar actualización manual si es necesario
video.addEventListener("timeupdate", () => {
    if (video.seeking) {
        console.log("Búsqueda en progreso...");
    }
});

Problema: Demora en la actualización de la UI

javascript
Copy
video.addEventListener("seeked", () => {
    requestAnimationFrame(() => {
        actualizarUI();
    });
});

???? Conclusión

El atributo onseeked es esencial para:

  • Crear reproductores multimedia profesionales

  • Sincronizar contenido secundario (subtítulos, gráficos)

  • Implementar analítica avanzada de uso

  • Optimizar la experiencia de navegación

Ejemplo final avanzado (Reproductor educativo):

html
Copy
<video id="leccion" src="leccion.mp4" controls></video>
<div id="notas-tiempo"></div>

<script>
const notas = {
    25: "Recuerda este concepto clave",
    45: "Importante para el examen",
    60: "Resumen de la lección"
};

document.getElementById("leccion").addEventListener("seeked", () => {
    const tiempo = Math.floor(video.currentTime);
    const nota = notas[tiempo];
    
    if (nota) {
        const divNotas = document.getElementById("notas-tiempo");
        divNotas.innerHTML = `<div class="nota">${nota}</div>`;
        divNotas.style.display = "block";
        
        setTimeout(() => {
            divNotas.style.opacity = "0";
        }, 5000);
    }
});
</script>

<style>
#notas-tiempo {
    position: fixed;
    bottom: 20px;
    right: 20px;
    background: rgba(0,0,0,0.8);
    color: white;
    padding: 15px;
    border-radius: 8px;
    transition: opacity 1s;
}
</style>

Con estos conceptos, podrás crear experiencias multimedia interactivas y profesionales. ¡Experimenta con diferentes implementaciones! ????????