Aprende a montar un servidor HTTP en Node.js que sirve un MP4 por la ruta /video, leyendo desde disco con fs y resolviendo rutas con path, mientras envía el contenido en chunks mediante streams y buffers. Con encabezados correctos y registro de bytes, comprenderás el flujo completo desde el archivo hasta el navegador.
¿Cómo servir video con Node.js usando streams y buffers?
Para entregar un video de forma eficiente, se crea un servidor con http que escucha la ruta exacta /video, obtiene metadatos del archivo con fs.statSync, envía headers adecuados y transmite el contenido en fragmentos. Así se aprovecha la naturaleza no bloqueante de Node.js y la memoria se usa de forma óptima.
¿Qué hace la ruta /video y qué headers envía?
Resuelve la ubicación del archivo con path.join y __dirname hacia "video.mp4".
Obtiene el tamaño con fs.statSync(videoPath) para calcular Content-Length.
Envía Content-Type: video/mp4 y Content-Length: stat.size con res.writeHead(200, { ... }).
Responde únicamente cuando la URL es exactamente "/video".
¿Cómo se leen y envían chunks con fs.createReadStream?
Crea un flujo de lectura con fs.createReadStream(videoPath).
Registra un contador: chunkCounter para monitorear envíos parciales.
En cada evento data, incrementa el contador y muestra chunk.length en bytes leídos y enviados.
Conecta lectura y respuesta con readStream.pipe(res) para transmitir sin cargar todo en memoria.
¿Cómo manejar errores y rutas inexistentes?
Para rutas que no sean "/video", responde con status code 404, Content-Type: text/plain y mensaje "Not found".
Un "invalid status code" suele indicar que faltó el código en res.writeHead; se corrige enviando 404 explícitamente.
// server-video.jsconst http =require('http');const fs =require('fs');const path =require('path');const server = http.createServer((req, res)=>{if(req.url==='/video'){const videoPath = path.join(__dirname,'video.mp4');const stat = fs.statSync(videoPath); res.writeHead(200,{'Content-Type':'video/mp4','Content-Length': stat.size,});const readStream = fs.createReadStream(videoPath);let chunkCounter =0; readStream.on('data',(chunk)=>{ chunkCounter++;console.log(`chunk ${chunkCounter}: ${chunk.length} bytes leídos y enviados`);}); readStream.pipe(res);}else{ res.writeHead(404,{'Content-Type':'text/plain'}); res.end('Not found');}});server.listen(3005,()=>{console.log('server is running on http://localhost:3005');});
¿Qué módulos y rutas se configuran en el servidor?
Se combinan varios módulos nativos y una ruta clara para entregar el recurso. Esto consolida habilidades clave: manejo de archivos, resolución de rutas y transmisión eficiente.
http: crea el servidor y maneja request y response.
fs: lee el archivo en flujo con fs.createReadStream y consulta metadatos con fs.statSync.
path: garantiza rutas portables con path.join(__dirname, 'video.mp4').
Ruta exacta "/video": única responsable de enviar el MP4.
Archivo requerido: coloca "video.mp4" en la raíz del proyecto. Si falta, la lectura falla y la solicitud no se completa.
¿Cómo probar, depurar y simular la red?
Probar con distintas condiciones ayuda a observar el comportamiento real de los streams y los buffers. Además, registrar bytes por chunk facilita comprender la transferencia.
Ejecuta con node --watch server-video.js para reiniciar ante cambios.
readStream.on('data',(chunk)=>{console.count('chunks');console.log(`Chunk size: ${chunk.byteLength} bytes`);});```Y ya no hay necesidad de hacer un let counterChunks
Dos comentarios: 1-Hay un problema con el examen?, cuando quiero ingresar me devuelve al home de Platzi. 2- Creo que faltó aclarar que como este curso es introductorio casi todas las funciones que usamos (sobre todo en fs) son sincronicas pero que no es la forma que se usa en un servidor de producción.
Les comento un error que tenía en node.js y era por usar sintaxis de ES modules, pues __dirname no era reconocido por node.js y simplemente basta con hacer esto:
Dejo la solución a un error que se me estaba presentado. El error era el siguiente:
El mensaje del error es "(node:31556) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 data listeners added to [ReadStream]."
La solución es mover la instrucción "readStream.pipe(res)" fuera del bloque "readStream.on" esto evita estar crear listerners por cada chunk procesado.
En el código, stat es un objeto que contiene información sobre el archivo de video, obtenido usando fs.statSync(videoPath). Este método síncrono lee los metadatos del archivo, como su tamaño, y permite al servidor enviar correctamente el encabezado 'content-length' en la respuesta HTTP. Esto es crucial para que el cliente sepa cuánto data esperar al reproducir el video. Así, stat.size proporciona el tamaño del archivo, que se usa para optimizar la transferencia del video.
estamos presentando error en el acceso al examen, redirije al home, y ahora dice que se pide subscripción, pero se supone que están habilitados hasta hoy?