php

Grabar vídeo con JavaScript y enviarlo a servidor con PHP

Esta es la continuación del post en donde vimos cómo grabar un vídeo (con audio incluido) usando JavaScript accediendo a la cámara web y al micrófono.

En ese mismo post tenemos enlaces a tutoriales para:

Grabar vídeo de cámara con JavaScript y subirlo a PHP usando MediaRecorder, fetch, getUserMedia y FormData

Así que es momento de grabar un vídeo con JavaScript pero enviar el resultado a un servidor con PHP.

Código fuente

El código fuente está en mi GitHub. Recomiendo encarecidamente que mires el post anterior, pues esta será una modificación que enviará el vídeo grabado a PHP en lugar de descargarlo.

Si no tienes PHP mira en este post cómo se instala.

Subir vídeo a PHP

La parte que se modifica es en donde se descarga el vídeo. En lugar de descargarlo, se envía el BLOB con fetch y formdata.

En el evento stop del objeto de MediaRecorder se ejecuta el siguiente código:

// Cuando se detenga (haciendo click en el botón) se ejecuta esto
mediaRecorder.addEventListener("stop", () => {
    // Pausar vídeo
    $video.pause();
    // Detener el stream
    stream.getTracks().forEach(track => track.stop());
    // Detener la cuenta regresiva
    detenerConteo();
    // Convertir los fragmentos a un objeto binario
    const blobVideo = new Blob(fragmentosDeAudio);

    const formData = new FormData();

    // Enviar el BinaryLargeObject con FormData
    formData.append("video", blobVideo);
    const RUTA_SERVIDOR = "guardar.php";
    $duracion.textContent = "Enviando vídeo...";
    fetch(RUTA_SERVIDOR, {
            method: "POST",
            body: formData,
        })
        .then(respuestaRaw => respuestaRaw.text()) // Decodificar como texto
        .then(respuestaComoTexto => {
            // Aquí haz algo con la respuesta ;)
            console.log("La respuesta: ", respuestaComoTexto);
            // Abrir el archivo, es opcional y solo lo pongo como demostración
            $duracion.innerHTML = `<strong>Vídeo subido correctamente.</strong>&nbsp; <a target="_blank" href="${respuestaComoTexto}">Abrir</a>`
        })
});

Creamos un objeto de FormData y usamos fetch para su envío utilizando el método POST de HTTP.

La respuesta (que veremos con el código de PHP) es el nombre del vídeo que ha sido guardado en el disco duro; con el nombre del vídeo creamos un enlace para que el usuario pueda abrir el vídeo que acaba de grabar.

Recibir y guardar vídeo con PHP

En el lado del servidor recibimos el archivo en el arreglo superglobal de $_FILES, como vimos en un post pasado.

Calculamos un nombre único (es para ejemplificar, pero podríamos guardarlo en otro lugar, en otra ruta, mandarlo a otro servidor, etcétera) y lo escribimos en el disco.

Al final, imprimimos el nombre del vídeo grabado, que será la respuesta de la petición de JavaScript:

<?php
/**
    * Grabar vídeo y audio obtenido del micrófono y cámara web
    * con JavaScript, seleccionando el dispositivo de grabación de audio
    * y el dispositivo de vídeo (cámara web) de una lista; 
    * usando MediaRecorder y getUserMedia
    * 
    * Extra: enviar el vídeo a un servidor con PHP y guardarlo en el disco duro
    * 
    * @author parzibyte
    * @see https://parzibyte.me/blog
 */# Si no hay archivos, salir inmediatamente
if (count($_FILES) <= 0 || empty($_FILES["video"])) {
    exit("No hay archivos");
}
# De dónde viene el vídeo y en dónde lo ponemos
$rutaVideoSubido = $_FILES["video"]["tmp_name"];
$nuevoNombre = uniqid() . ".webm";
$rutaDeGuardado = __DIR__ . "/" . $nuevoNombre;
// Mover el archivo subido a la ruta de guardado
move_uploaded_file($_FILES["video"]["tmp_name"], $rutaDeGuardado);
// Imprimir el nombre para que la petición lo lea
echo $nuevoNombre;

Si miramos los archivos, en el disco duro estarán los vídeos grabados con JavaScript:

Lista de vídeos grabados con JavaScript subidos a PHP

Además, si hacemos click en el enlace que se crea del lado del cliente, se abrirá el vídeo:

Reproducir vídeo guardado con PHP

Poniendo todo junto

Para pedir permisos, llenar las listas de micrófonos y cámaras se utiliza el código que vimos en el post anterior; lo único que cambiamos es el funcionamiento del evento stop del objeto de tipo MediaRecorder.

Del lado del servidor recibimos un archivo y lo guardamos.

Recuerda que el código completo y actualizado se encuentra en GitHub.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.