Featured image of post Video Streaming with Node.js

Video Streaming with Node.js

Tutorial on Building a Simple Video Streaming App with Node.js\

Ever fancied turning your Node.js skills into a mini Netflix?

The Grand Plan

Imagine this: every time you pop open a new browser tab, our server tosses a random video your way.

It’s like a surprise party, but with videos.

And guess what?

The video loops endlessly, perfect for those who enjoy the hypnotic charm of looping cat videos.

Setting Up the Playground

First things first, let’s set up our project.

Fire up your terminal and create a new directory:

1
2
mkdir node-video-streamer
cd node-video-streamer

Initialize a new Node.js project:

1
npm init -y

We’ll need a few trusty packages:

  • express: Our web framework buddy.

  • nodemon: Auto-restarts our server when code changes.

Because who has time to restart manually?

Install them with:

1
2
npm install express
npm install --save-dev nodemon

In your package.json, add a start script:

1
2
3
"scripts": {
  "start": "nodemon index.js"
}

Show Me the Code!

Time to get our hands dirty.

Create an index.js file and sprinkle in the following magic:

 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
const express = require('express');
const fs = require('fs');
const path = require('path');

const app = express();
const port = 3000;

// Directory where your videos live
const videoDir = path.join(__dirname, 'videos');

// Get a list of video files
const videos = fs.readdirSync(videoDir);

// Serve a random video
app.get('/video', (req, res) => {
  const randomVideo = videos[Math.floor(Math.random() * videos.length)];
  const videoPath = path.join(videoDir, randomVideo);
  const stat = fs.statSync(videoPath);
  const fileSize = stat.size;
  const range = req.headers.range;

  if (range) {
    const parts = range.replace(/bytes=/, "").split("-");
    const start = parseInt(parts[0], 10);
    const end = parts[1] ?

parseInt(parts[1], 10) : fileSize - 1;
    const chunkSize = (end - start) + 1;
    const file = fs.createReadStream(videoPath, { start, end });
    const head = {
      'Content-Range': `bytes ${start}-${end}/${fileSize}`,
      'Accept-Ranges': 'bytes',
      'Content-Length': chunkSize,
      'Content-Type': 'video/mp4',
    };
    res.writeHead(206, head);
    file.pipe(res);
  } else {
    const head = {
      'Content-Length': fileSize,
      'Content-Type': 'video/mp4',
    };
    res.writeHead(200, head);
    fs.createReadStream(videoPath).pipe(res);
  }
});

// Serve the HTML page
app.get('/', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Random Video Streamer</title>
      </head>
      <body>
        <video id="videoPlayer" width="640" height="480" controls autoplay loop>
          <source src="/video" type="video/mp4">
          Your browser does not support the video tag.

</video>
      </body>
    </html>
  `);
});

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`);
});

Here’s the lowdown:

  • Video Directory: We point to a videos folder where your MP4 files chill out
  • Random Selection: Each visit to /video serves up a random video from the collection.
  • Range Requests: Handles those nifty HTTP range requests for smooth streaming
  • HTML Page: Serves a basic page with a video element that auto-plays and loops.

Time to Test Drive

  1. Stock Up on Videos: Drop some MP4 files into a videos folder inside your project directory.

  2. Fire Up the Server: In your terminal, run:

    1
    
    npm start
    
  3. Enjoy the Show: Open http://localhost:3000 in your browser.

Each new tab serves a fresh, random video.

What This Little Demo Shows

This playful project showcases:

  • Node.js Streaming: Serving video content in chunks, keeping memory usage lean and mean.

  • Randomized Content Delivery: Spice up user experience with varied content on each visit.

  • Looping Media: Perfect for those who can’t get enough of that one epic scene.

The Tricky Bits

While our demo is a hoot, it’s a bit of a stretch to simulate multiple users bombarding the server by opening a gazillion tabs yourself.

In the real world, you’d want to test with proper load testing tools to see how your server holds up under pressure.

Node.js and Video Streaming: The Good, the Bad, and the Buffering

The Good:

  • Simplicity: Node.js makes it a breeze to set up a basic streaming server.

LogRocket’s tutorial is a great example.

  • Non-Blocking I/O: Handles multiple requests without breaking a sweat.

The Not-So-Good:

  • Performance Limits: For heavy-duty streaming, Node.js might need some backup.

It’s not the Hulk of streaming servers.

  • Error Handling: Streams can be finicky.

Proper error handling is a must to avoid unexpected crashes.

Clariontech offers insights into managing errors and downtime in real-time data streaming with Node.js.

This Is Just a Toy

Remember, this app is like a toy car—fun to play with but not meant for the freeway.

It’s a great way to dip your toes into streaming, but building a full-fledged streaming platform?

That’s a whole different ball game.