1. Client-Side Browser Streaming with Fetch & Blob
In browser environments, downloading a large video file into memory via await response.blob() can freeze the UI or exhaust mobile memory. Using response.body.getReader() provides progressive download feedback:
async function downloadVideoWithProgress(videoUrl, filename = "video.mp4") {
const response = await fetch(videoUrl);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const contentLength = response.headers.get("content-length");
const totalBytes = contentLength ? parseInt(contentLength, 10) : 0;
const reader = response.body.getReader();
const chunks = [];
let receivedBytes = 0;
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
receivedBytes += value.length;
if (totalBytes > 0) {
const percent = Math.round((receivedBytes / totalBytes) * 100);
console.log(`Progress: ${percent}%`);
}
}
// Create Blob URL and trigger browser save
const blob = new Blob(chunks, { type: "video/mp4" });
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
setTimeout(() => URL.revokeObjectURL(downloadUrl), 5000);
}
2. Node.js Stream Piping with pipeline()
On the backend with Node.js, never buffer video files in memory. Use stream/promises pipeline to stream directly from the HTTP socket to the filesystem:
import fs from 'node:fs';
import { pipeline } from 'node:stream/promises';
import { Readable } from 'node:stream';
async function streamVideoToFile(videoUrl, outputPath) {
const response = await fetch(videoUrl, {
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36'
}
});
if (!response.ok) throw new Error(`Fetch failed with status ${response.status}`);
// Convert Web ReadableStream to Node.js Readable stream
const nodeStream = Readable.fromWeb(response.body);
const fileWriter = fs.createWriteStream(outputPath);
await pipeline(nodeStream, fileWriter);
console.log(`✅ Saved video to ${outputPath}`);
}
// Example usage:
streamVideoToFile('https://example.com/stream.mp4', './output.mp4');
3. Overcoming CORS in Static Frontends
Browser frontends hosted on static servers (like GitHub Pages) cannot make direct requests to Instagram or Facebook video endpoints because those servers do not emit Access-Control-Allow-Origin: *.
Solutions for production:
- Direct CORS APIs: APIs like TikWM (TikTok) and Piped (YouTube) provide CORS-friendly streaming endpoints.
- Serverless Edge Proxies: Deploy a Cloudflare Worker or Vercel Edge Function with custom CORS headers to stream video headers directly.