Transmitir grandes archivos de video desde el servidor al cliente, lo que podría ser una aplicación web o aplicaciones móviles de manera ineficiente.
No podemos enviar el video completo una vez a un cliente. porque hay condiciones como el ancho de banda y las restricciones de datos del usuario.
Ejemplo:
Digamos youtube, el usuario puede ver una parte del video y se fue por alguna razón, si abrió ese video nuevamente, no debería cargar el video completo desde el principio.
Aquí está la parte en la que necesitamos algún mecanismo para manejar esta situación.
La API de flujo de Nodejs entra en escena, es más eficiente que leer un archivo de manera convencional y esperar a que se resuelvan las devoluciones de llamada.
Creó un servidor básico de transmisión de video para explicarlo un poco mejor.
El flujo del sistema:
- El usuario visita el sitio (index.html)
- El componente de video html5 en index.html apunta a la URL del video que está transmitiendo el servidor
- La solicitud de video es manejada por el servidor al procesar el encabezado del rango y envía parte del video como contenido parcial.
Configuración del proyecto:
- terminal abierta
- mkdir <nombre del proyecto>
- cd <nombre del proyecto>
- npm inicializar -y
- Abre tu editor de texto favorito
- Cree index.html en esa carpeta (consulte el código html a continuación, utilícelo allí)
- Cree un archivo server.js (verifique el código js que se proporciona a continuación)
- Ejecute el comando «Node server.js»
- Abra el navegador y navegue hasta “localhost:3000”
Código fuente completo:
https://github.com/varaprasadh/gfg-blogs/tree/master/streamvideo
¡Necesitaremos un archivo index.html que muestre el video que proviene del servidor!
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>video player</title> </head> <body> <video src="http://localhost:3000/video" controls> </video> </body> </html>
Javascript
const http=require('http'); const fs=require("fs"); const path=require("path"); /* http.createServer takes a handler function and returns a server instance;*/ const server=http.createServer((req, res)=>{ // return res.end(req.url+req.method); if(req.method==='GET' && req.url==="/"){ /*we will send a index.html page when user visits "/" endpoint*/ /*index.html will have video component that displays the video*/ fs.createReadStream(path.resolve( "index.html")).pipe(res); return; } //if video content is requesting if(req.method==='GET' && req.url==="/video"){ const filepath = path.resolve("video.mp4"); const stat = fs.statSync(filepath) const fileSize = stat.size const range = req.headers.range /*when we seek the video it will put range header to the request*/ /*if range header exists send some part of video*/ if (range) { //range format is "bytes=start-end", const parts = range.replace(/bytes=/, "").split("-"); const start = parseInt(parts[0], 10) /*in some cases end may not exists, if its not exists make it end of file*/ const end = parts[1] ?parseInt(parts[1], 10) :fileSize - 1 //chunk size is what the part of video we are sending. const chunksize = (end - start) + 1 /*we can provide offset values as options to the fs.createReadStream to read part of content*/ const file = fs.createReadStream(filepath, {start, end}) const head = { 'Content-Range': `bytes ${start}-${end}/${fileSize}`, 'Accept-Ranges': 'bytes', 'Content-Length': chunksize, 'Content-Type': 'video/mp4', } /*we should set status code as 206 which is for partial content*/ // because video is continuously fetched part by part res.writeHead(206, head); file.pipe(res); }else{ //if not send the video from start. /* anyway html5 video player play content when sufficient frames available*/ // It doesn't wait for the entire video to load. const head = { 'Content-Length': fileSize, 'Content-Type': 'video/mp4', } res.writeHead(200, head); fs.createReadStream(path).pipe(res); } } /*if anything other than handler routes then send 400 status code, is for bad request*/ else{ res.writeHead(400); res.end("bad request"); } }) /*check if system has environment variable for the port, otherwise defaults to 3000*/ const PORT = process.env.PORT || 3000; //start the server server.listen(PORT, () => { console.log(`server listening on port:${PORT}`); })
Finalmente podemos ver el resultado en el navegador.
Publicación traducida automáticamente
Artículo escrito por varaprasadh y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA