1

Problem statement :
I have placed a movie file in a node.js server.
I want to stream the movie in my browser and display


I have a node server which serves byte range request under http://localhost/video url. The browser sends the request. I get 206 successful byte-range request status code. But the fetched segment is not playing in html5 video element. I am using firefox.

Error : No video with supported format or mime type found


async function fetchRange(url, startByte, endByte) {
 try {
 const response = await fetch(url, {
 headers: {'Range': `bytes=${startByte}-${endByte}`}
 });
 
 const data = await response.blob(); 
 console.log(`Fetched ${data.size} bytes from ${startByte} to ${endByte}.`);
 return data;
 } catch (error) {
 console.error('Error fetching range:', error);
 }
}
// Example usage:
const fileUrl = 'http://localhost:8000/video'; // Replace with your file URL
const start = 0;
const end = 1023; // Requesting the first 1024 bytes (0-1023)
fetchRange(fileUrl, start, end)
.then(data => {
 if (data) {
 // Process the received data (e.g., display it, save it)
 console.log('Received data:', data);
 let f = new File([data],'haah',{ type: "video/mp4" })
 document.getElementById('vid2').src = URL.createObjectURL(f)
 }
});

html:

<video controls width="350" id="vid2" >
 <source src='' type="video/mp4" >
 Sorry, not supported by browser
 </source>
</video>

node server code :

if(req.url === '/video' && req.method === 'GET'){
 console.log('video get')
 //var filePath = 'audiofile2.flac';
 var filePath = "output_ah.mp4"
 var stat = fs.statSync(filePath);
 var total = stat.size;
 console.log(req.headers.range)
 var range = req.headers.range;
 var parts = range.replace(/bytes=/, "").split("-");
 var partialstart = parts[0];
 var partialend = parts[1];
 var start = parseInt(partialstart, 10);
 var end = partialend ? parseInt(partialend, 10) : total-1;
 //console.log(start,end)
 var chunksize = (end-start)+1;
 var file = fs.createReadStream(filePath, {start: start, end: end});
 res.writeHead(206, {
 'Content-Range': 'bytes ' + start + '-' + end + '/' + total,
 // 'Content-Length' : total,
 'Accept-Ranges': 'bytes', 
 'Content-Length': chunksize,
 'Content-Type': 'video/mp4'
 // 'ETag' : '"'+"abcd-efgh"+'"'
 });
 file.pipe(res)
 }
VC.One
16.2k4 gold badges27 silver badges66 bronze badges
asked Sep 19, 2025 at 22:22
8
  • You're loading a whopping 1 KB of a video file... what do you expect? Commented Sep 20, 2025 at 1:57
  • Agreed. The metadata alone can be bigger than 1KB. A video frame IS bigger than 1KB. A test amount of 1 or 2MB should show some frames. I suspect they want to stream a long video in constant 1KB chunks. Commented Sep 21, 2025 at 9:51
  • Questions about a "not working" video need to provide testable video data. Put this short example MP4 file (from W3Schools) into your NodeJS server. Try running your code with it. Commented Sep 21, 2025 at 10:07
  • If you just want to play a video, you don't need to do anything special. No MediaSource needed. Just plug in the URL of the video, and then on your Node.js side you can simly use Express which will handle the range requests for you. Commented Sep 22, 2025 at 0:17
  • 1
    "I have a node server which serves byte range request under http://localhost/video url." - okay, then stop there. Leave it up to the client, whether it wants to make byte range requests, or not. If it does, then it will know what kind of range sizes to request. Your own client-side attempt to request chunks of arbitrary sizes defined by you, is not very promising. You'd probably have to look into the specifics of video encoding & container formats in a lot more detail, if you wanted to implement that part of the equation yourself as well. Commented Sep 22, 2025 at 13:19

1 Answer 1

1

MP4 files are a container for video and audio data, meta data, embedded subtitles and who knows what else. Video data is compressed with keyframes separating frames that only define changes since the previous frame (roughly speaking).

Taking a slice of a (MP4) file between specified byte offsets could return almost anything, with high likelihood a corruption of a segment of valid content in the file - with no meta data describing what it is.

More usefully the file needs to be split based on its timeline, between specified start and end times, with the server responsible for extracting a playable segment using a package like FFMPEG or a tool to pre-split the video file into a sequential set of videos. Splitting should occur on keyframes to avoid artifacts at the beginning and end of segments.

The MediaStream API may provide alternative solutions.

This question has probably been asked in a different format before - and there are a range of solutions. Hopefully this answer can clarify the underlying issue.

See also:

  1. FFMPEG Splitting MP4 with Same Quality on SuperUser
  2. How to split a mp4 file into multiple .m4s chunks with one init.mp4 file
  3. Seekable player with WebRTC

and web searches with terms for splitting MP4 files, seekable streams etc.

answered Sep 20, 2025 at 1:45
Sign up to request clarification or add additional context in comments.

5 Comments

how can MediaStream API help when I need to stream video from server?
An AI overview of searching Google 10 minutes ago for "what protocols are used to stream live cams on the internet" mentions protocols RTSP, RTMP, HLS and MPEG-DASH, and WebRTC , about which I know little, although some were mentioned in "see also" answers above. In hindsight the question lacks details about the exact problem to be solved and what needs to be achieved to do so. Please update the question with more focus on and clarity about the issue to be solved. An answer could involve the Media Stream API without saying it will.
"issue to be solved" is obvious: I have placed a movie file in a node.js server. I want to stream the movie in my borwser and display it using html5 video player. For learning purposes!
Got it. I have written code to write unlimited sized video files to the response stream in chunks using buffering to handle reading them asynchronously, chunk by chunk, on the server. At the same time allowing response stream events to trigger when to write the next chunk, again asynchronously. I'll update the answer when I get a chance, hopefully tomorrow.
My apologies, the code I wrote was to handle unlimited uploads (POSTs) of binary data and switched modes on the request stream to read it in chunks and append it to a file on the server machine. For downloading videos from the server I I simply used the Node/Express static middleware to handle GET requets issued internally by HTML5 video elements .

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.