Node.js for Streaming Videos

I am currently working on streaming video using node.js and I recently came across this helpful article. The setup works perfectly when streaming from a local source, but now I need to stream the video from a web source.

However, my specific requirement is to conceal the original URL in the source code. Instead of displaying the original URL like

<source src="http://goo.gl/KgGx0s" type="video/mp4"/>
, I want to show a modified one such as
<source src="http://localhost:8888" type="video/mp4"/>
.

To implement this, I have included the following code snippets:

var indexPage, movie_webm, movie_mp4, movie_ogg;
fs.readFile(path.resolve(__dirname,"ANY_LOCAL_VIDEO.mp4"), function (err, data) {
    if (err) {
        throw err;
    }
    console.log(data.length);
    movie_mp4 = data;
});

http.createServer(function (req, res) {
    var reqResource = url.parse(req.url).pathname;
    var total;
    total = movie_mp4.length;
    var range = req.headers.range;  
    var positions = range.replace(/bytes=/, "").split("-");
    var start = parseInt(positions[0], 10); 
    var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
    var chunksize = (end-start)+1;
    res.writeHead(206, { "Content-Range": "bytes " + start + "-" + end + "/" + total, 
                         "Accept-Ranges": "bytes",
                         "Content-Length": chunksize,
                         "Content-Type":"video/mp4"});
    res.end(movie_mp4.slice(start, end+1), "binary");

}).listen(8888); 

Although this solution works well for local videos, I encountered an issue when trying to use

fs.readFile("http://goo.gl/KgGx0s", function (err, data) {
instead of the aforementioned code. I attempted changing fs.readFile to fs.filepath, but the problem persisted with the following error message:

c:\git\personal\streaming-video-html5\server.js:13
        throw err;
              ^
Error: ENOENT, open 'c:\git\personal\streaming-video-html5\http:\goo.gl\KgGx0s'

This error likely occurs due to the changing path. What steps should I take to address this issue? Is there a viable solution available?

Answer №1

If you're searching for a solution, consider using the request module to fetch a remote video and pipe it directly to your response.

To ensure the remote video supports byte ranges and obtain its content length, start by making a HEAD request.

Once you have this information, set the response headers with an HTTP status code of 206 to indicate a partial response.

After setting the headers, create a request to the remote video, including the byte range in the original request, and pipe the data directly to your response (res).

Suggested file URL: 'https://ia800300.us.archive.org/1/items/night_of_the_living_dead/night_of_the_living_dead_512kb.mp4';

var range = req.headers.range;
var positions, start, end, total, chunksize;

// Perform HEAD request for file metadata
request({
  url: fileUrl,
  method: 'HEAD'
}, function(error, response, body){
  setResponseHeaders(response.headers);
  pipeToResponse();
});

function setResponseHeaders(headers){
  positions = range.replace(/bytes=/, "").split("-");
  start = parseInt(positions[0], 10); 
  total = headers['content-length'];
  end = positions[1] ? parseInt(positions[1], 10) : total - 1;
  chunksize = (end-start)+1;

  res.writeHead(206, { 
    "Content-Range": "bytes " + start + "-" + end + "/" + total, 
    "Accept-Ranges": "bytes",
    "Content-Length": chunksize,
    "Content-Type":"video/mp4"
  });
}

function pipeToResponse() {
  var options = {
    url: fileUrl,
    headers: {
      range: "bytes=" + start + "-" + end,
      connection: 'keep-alive'
    }
  };

  request(options).pipe(res);
}

To optimize performance, consider caching the response from the initial HEAD request to avoid repeating it for each byte-range request.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Developing JSON with the use of jQuery

My latest project involves creating an application that converts HTML tables to JSON format. The code is functioning properly, but I've encountered an issue when the td or th elements contain inner components like span or other child elements. While I ...

The HTML video controls in Safari take precedence over the window.name attribute

When using Safari 8.0.5, the controls attribute for the video element will change the value of window.name to "webkitendfullscreen". This is significant because I rely on using window.name to store client-side data in Safari's private mode, where loca ...

Why did my compilation process fail to include the style files despite compiling all other files successfully?

As English is not my first language, I kindly ask for your understanding with any typing mistakes. I have created a workspace with the image depicted here; Afterwards, I executed "tsc -p ." to compile my files; You can view the generated files here Unf ...

Utilize state objects and child components by accessing sub-values within the object

I have a Dropzone component where multiple uploads can happen simultaneously and I want to display the progress of each upload. Within my Dropzone component, there is a state array called uploads: const [uploads, setUploads] = useState([]) Each element i ...

Nodejs - Utilizing Express and Mongoose to Implement URL Routing by Name

My Express 4 server has CRUD routes specifically for authors: router.get('/authors', AuthorsController.index); router.post('/authors', AuthorsController.store); router.get('/authors/:name', AuthorsController.show) ...

Tips for inserting an array as separate documents in MongoDB

I'm currently facing an issue with a post function in my nodeJs application. The body I am trying to post is as follows: { "_id": "fffff-ggg-jjjjj", "type": "", "gamers": [ "Ra ...

Assign a CSS class to a DIV depending on the vertical position of the cursor

The website I am currently developing is located at Within the site, there is a collection of project titles. When hovering over a project title, the featured image is displayed directly below it. I would like to change the positioning of these images to ...

Using jQuery to follow a div while scrolling that halts at a designated top or bottom boundary

I've been working on this jsfiddle: https://jsfiddle.net/3ncyxnzt/ Currently, the red box stops at a specified margin from the top of the page but I want it to also stop before reaching the bottom, so that it doesn't go under or over the footer. ...

Exploring face detection with Three.js

When I utilize an octree, I am able to generate an array of faces that are in close proximity to an object. However, I am unsure how to perform a ray cast to these faces. All the resources I have found only explain how to ray cast to a mesh, line or poin ...

Storing values in an array when checkboxes are selected within an ng-repeat loop in AngularJS

I am facing a situation where I need to populate an array with values when a checkbox is checked within an ng-repeat iteration. <li ng-repeat="player in team.players"> <div class="row"> <div class="col-md-3 m-t-xs"> <inp ...

How can we add a class to a radio button using jQuery when it is checked, and remove the class when it

I'm looking for help with using jQuery to toggle between two radio buttons and display different divs based on the selection. jQuery(document).ready(function($) { if ($('#user_personal').is(':checked')) { $('.user_co ...

What is the best way to transfer a multidimensional array from PHP to JavaScript?

Attempting to extract array value from a JSON string, I utilize the json_decode function in PHP. <?php $jsonContent=file_get_contents('http://megarkarsa.com/gpsjson.php'); $jsonDecoded=json_decode($jsonContent,true); foreach($jsonEncoded[&apo ...

When attempting to reference from a variable, you may encounter an error stating that setAttribute

In my VueJS project, I am facing an issue with dynamically adding the width attribute to an inline SVG code stored in a variable called icon. Despite having the correct SVG icon code in the variable, the setAttribute method is not working as expected and t ...

Activate fancybox when clicked, triggering numerous ajax requests

Although I achieved my desired output, the method in which it was done is not ideal because AJAX duplicates with every click. Check out my code: <a href="/messages/schedule" class="greenbtn fancybox">Schedule</a> $('a.fancybox').cl ...

What is the best way to automatically connect npm packages during installation?

I am currently involved in a large project that is divided into multiple npm packages. These packages have dependencies on each other, and the entire code base is stored in a main directory structure like this: main/ pkg1/ pkg2/ ... For example, if ...

Swapping React components within a list: How to easily change classes

For my latest project, I am building a straightforward ecommerce website. One of the key features on the product page is the ability for users to select different attributes such as sizes and colors. These options are represented by clickable divs that pul ...

How can I make the row color of a jQuery datatable change when the row is selected?

One of my challenges involves implementing a jquery dataTable (view here) where each row contains a checkbox. I want the row's color to change when the checkbox is checked. This is the approach I attempted: <table id="tabellaOrdinaFarmaci" class=" ...

Transforming SOAP into GraphQL

Is it possible for GraphQL to directly interact with a SOAP service as a data source, or is it necessary to create a SOAP-to-REST conversion layer? If such a conversion layer is needed, what technology (language, framework, OS, etc.) would be recommended f ...

Error occurs in Javascript when attempting to execute javascript code using PHP's echo and an unexpected identifier token is encountered

Currently, I am trying to insert a div into the page when a specific condition is met in PHP: if ($var == 0) { echo '<script>console.log("Test."); var res = document.getElementById("response"); res.innerHTML = "<div class='h ...

Obtain a listing of values that appear multiple times within an array

I need a solution to find values that appear more than once in an array. The current code I have is quite complex. var arr = [1, 2, 3, 4, 2, 3]; var flag = {} var exist2arr = []; for(var i = 0; i < arr.length; i++){ for(var j = 0 ; j < arr.leng ...