FetchStream is architected with a strict separation of concerns. Unlike conventional video downloaders that lock you into proprietary servers or commercial subscriptions, FetchStream separates the client browser extension from the execution backend.
Inspects network media streams (HLS/M3U8), embedded web PDFs, disk images, and direct media files. Downloads directly to disk with parallel workers, or offloads to a private runner.
An independent HTTP server that accepts stream download jobs, assembles them with FFmpeg, and can upload to configured storage. The browser still communicates with the runner.
Every detected media item gives you complete control over how to process it:
| Action Button | Where It Executes | Bandwidth Used | Setup Required |
|---|---|---|---|
| Download | Your computer's browser engine (OPFS) | Local download only | No Setup |
| Local Upload | Browser downloads file & streams directly to cloud host API | Local download + Local upload | No Setup |
| Server Upload | Remote cloud runner (VPS / Docker / CI/CD Runner) | 0MB Local Data | Configure Server URL in Settings |
To build or host a compatible backend, your server must implement two straightforward REST endpoints:
POST /api/server-relay and GET /api/server-status.
The code blocks, JSON schemas, and architectural blueprints provided in this documentation and in our repositories are mere examples meant to demonstrate intended functionality. They are provided as-is and may be prone to error depending on your production environment, dependencies, or configuration. Please review, test, and adapt them thoroughly before deploying to production.
/api/server-relay
(or /api/tasks)
Dispatches a stream or media file download and upload job to the server.
Content-Type: application/json
Authorization: Bearer <YOUR_API_KEY>
X-API-Key: <YOUR_API_KEY>
{
"jobId": "job_1725900000000_abc12",
"mediaUrl": "https://cdn.site.com/hls.m3u8",
"fileName": "lecture_video.mp4",
"type": "hls",
"format": "mp4",
"service": "gofile.io",
"threads": 8,
"headers": {
"User-Agent": "Mozilla/5.0 ...",
"Referer": "https://streaming-site.com/"
},
"credentials": {
"caption": "My Optional Description",
"gofile": {
"token": "YOUR_GOFILE_API_TOKEN",
"folderId": "OPTIONAL_FOLDER_ID"
},
"telegram": {
"chatId": "-100123456789",
"botToken": "1234:ABCDEF",
"caption": "My Optional Description"
},
"s3_compatible": {
"endpoint": "https://s3.us-east-1.amazonaws.com",
"bucket": "my-bucket",
"region": "us-east-1",
"accessKeyId": "YOUR_KEY",
"secretAccessKey": "YOUR_SECRET",
"prefix": "optional/folder/path/"
},
"pixeldrain.com": {
"apiKey": "YOUR_PIXELDRAIN_API_KEY"
}
},
"useFallbackProxy": true
}
{
"jobId": "job_1725900000000_abc12",
"status": "QUEUED",
"message": "Job received and queued successfully."
}
/api/server-status?jobId={jobId}
(or /api/tasks/{jobId})
Returns real-time download and upload progress for the specified job.
The status field must be one of: "QUEUED", "RUNNING", "COMPLETED", or "FAILED".
{
"jobId": "job_1725900000000_abc12",
"status": "RUNNING",
"stage": "DOWNLOADING",
"progress": 55.4,
"speed": "12.8 MB/s",
"completedSegments": 554,
"totalSegments": 1000,
"fileName": "lecture_video.mp4",
"fileSize": 157286400
}
{
"jobId": "job_1725900000000_abc12",
"status": "COMPLETED",
"stage": "COMPLETED",
"progress": 100,
"speed": "Complete",
"fileName": "lecture_video.mp4",
"fileSize": 284190120,
"url": "https://gofile.io/d/abc123",
"links": [
{
"service": "gofile.io",
"name": "GoFile",
"url": "https://gofile.io/d/abc123",
"directUrl": "https://srv.gofile.io/download/web/abc123/video.mp4"
}
]
}
/api/server-callback
Runner Webhook
Internal webhook called by runner scripts (server_uploader.py) to stream fine-grained download progress, conversion status, and resulting upload links to the edge/server store.
{
"jobId": "job_1725900000000_abc12",
"status": "RUNNING",
"stage": "UPLOADING",
"progress": 82.5,
"speed": "Telegram • 45.2/60.0MB (75%)",
"fileName": "lecture_video.mp4"
}
/api/server-cancel
(or /api/tasks/{jobId}/cancel)
{
"jobId": "job_1725900000000_abc12"
}
{
"ok": true,
"jobId": "job_1725900000000_abc12",
"status": "CANCELLED"
}
/api/server-pause
and
/api/server-resume
Optional endpoints. If your custom backend supports pausing and resuming active streams, implementing these endpoints will allow the Extension UI's Pause/Resume buttons to control the server jobs. If unimplemented, the extension will gracefully notify the user that the server lacks pause capabilities.
{
"jobId": "job_1725900000000_abc12"
}
/health
Liveness Check
Returns real-time worker load, version, and auth status of the runner.
{
"status": "healthy",
"service": "FetchStream Remote Runner",
"version": "1.0.0",
"active_jobs": 0,
"total_jobs": 12,
"auth_enabled": true
}
/api/stream-proxy?url={target_segment_url}
Edge Proxy
Streams media playlists and segments through Edge API workers. When an origin CDN blocks datacenter IP ranges (returning HTTP 403 Forbidden to CI/CD or VPS runners), the runner automatically retries chunk downloads via this edge proxy using residential/edge IP routing.
To prevent unauthorized users from abusing your server bandwidth, you can set an API_KEY environment variable on your backend.
In the FetchStream extension, open Settings -> Server Upload and paste your secret key into Server API Key / Token (Optional). The extension automatically transmits your key in the Authorization: Bearer <key> header.
The Docker and Serverless backend blueprints below are reference implementations. Review, test, and secure them for your deployment. Operators are responsible for runner security, configuration, maintenance, and lawful use.
Suitable for a Linux VPS, Raspberry Pi, home server, or local PC. The example includes FFmpeg and Python 3.11 for server-side stream processing.
📁 Reference Source Code & Dockerfile: server-examples/docker/
git clone https://github.com/Abhishek-banal/fetchstream.git
cd fetchstream/server-examples/docker
docker compose up -d --build
curl http://localhost:8000/health
http://localhost:8000 (or your VPS domain, e.g. https://downloader.yourdomain.com).Do not own a server? You can run the cloud downloader using an Edge Worker or CI/CD pipeline with temporary runner VMs.
📁 Reference Blueprints & Workflows: server-examples/serverless/
functions/api scripts to an Edge provider. For example, using Edge CDN Workers connected to your private runner repo:
publicCI_TOKEN: Your copied CI/CD tokenCI_REPO: your-username/your-runner-repo-namehttps://my-fetchstream-runner.pages.dev) and paste it into the FetchStream extension settings under Remote Server URL.
Because FetchStream communicates via a standard JSON contract, you can implement a custom backend in any programming language using minimal code.
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uuid
app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"])
jobs = {}
@app.post("/api/server-relay")
async def dispatch_task(data: dict):
job_id = data.get("jobId") or str(uuid.uuid4())
jobs[job_id] = {"status": "RUNNING", "progress": 0, "url": data.get("mediaUrl")}
return {"jobId": job_id, "status": "QUEUED"}
@app.get("/api/server-status")
async def task_status(jobId: str):
return jobs.get(jobId, {"status": "FAILED", "error": "Job not found"})
FetchStream includes upload adapters for several third-party storage hosts and generic object storage endpoints:
| Target Provider | Local Upload Cap | Server Upload Cap | Auth / Credentials | Features & Retention |
|---|---|---|---|---|
| GoFile.io | Provider-defined | Provider-defined | None (Optional API Token) | High-speed streaming & direct download links |
| Buzzheavier.com | 50 GB | 50 GB | None | Ultra-fast temporary cloud transfer |
| Pixeldrain.com | 10 GB | 10 GB | None (Optional API Key) | Direct file streaming with fast delivery |
| FFast | 5 GB | 5 GB | None | Parallel chunked streaming pipeline |
| Storage.to | 5 GB | 5 GB | None | Instant direct download hosting |
| Catbox / Litterbox | 200MB | 200MB | None (Optional Userhash) | Retention depends on the selected service |
| Telegram | 50MB (Bot API) | Telegram and runner limits | Bot Token + Chat ID | Native streaming video cards in your private channel |
| Generic S3 / R2 | 5 TB (Multi-part) | 5 TB | Access Key + Secret Key + Bucket | Private cloud bucket (Cloud Provider, Edge Object Storage, MinIO, B2) |
| S3 + Telegram Relay | Composite | Composite | Bucket Keys + Telegram Credentials | Stores asset in S3 and relays playable preview to Telegram |
FetchStream supports direct client-side uploads to any S3-compliant object storage bucket (such as Edge Object Storage, S3-compatible Object Storage, Backblaze B2, or MinIO) using authentic Cloud Provider Signature Version 4 (SigV4) generated directly in your browser.
Because transfers execute directly from the browser runtime to your storage bucket endpoint via HTTP PUT requests, your storage provider must permit cross-origin requests. Without a valid CORS policy, browsers will abort uploads with a Cross-Origin Request Blocked (CORS) error.
Copy and paste this standard CORS JSON policy into your bucket's CORS configuration:
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET", "PUT", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"]
}
]
| Provider | Endpoint URL Format | Region | Credentials & Where to Configure CORS |
|---|---|---|---|
| Edge Object Storage Recommended (10GB Free) |
https://<ACCOUNT_ID>.r2.Edge Providerstorage.com |
auto |
Create an R2 API Token with Object Read & Write permissions. Configure CORS in Bucket Settings ➔ CORS Policy. |
| Major Cloud Providers (S3-compatible Storage) | https://s3.<region>.amazonaws.com(e.g. https://s3.us-east-1.amazonaws.com) |
Target Region (e.g. us-east-1) |
IAM User Access Key & Secret Key with s3:PutObject and s3:GetObject permissions. Configure CORS in Bucket ➔ Permissions ➔ CORS. |
| Backblaze B2 | https://s3.<region>.backblazeb2.com |
Target Region (e.g. us-west-004) |
Application Key ID and Application Key with Read and Write access. Configure CORS via B2 CLI or B2 web console. |
| Self-Hosted MinIO | https://minio.yourdomain.com (or http://IP:9000) |
us-east-1 (default) |
MinIO Access Key & Secret Key. Set CORS via MinIO Console or mc anonymous set. |
You can organize uploads into a subfolder by entering a prefix (e.g. recordings/ or archives/) in Settings. FetchStream will automatically place all uploads under that bucket key prefix.
Upon upload completion, FetchStream automatically generates a SigV4 signed download URL valid for 7 days so you can immediately retrieve and share the file without making your bucket publicly accessible.
FetchStream can upload downloaded streams, videos, and files directly to a private Telegram Channel, Group, or Chat using Telegram's official Bot API. Follow this step-by-step guide to create your bot and find your numeric Channel ID.
1. In Telegram, search for the official @BotFather and click Start.
2. Send the command: /newbot
3. Choose a friendly name for your bot (e.g. My Storage Bot).
4. Choose a unique username ending in bot (e.g. my_media_vault_bot).
5. BotFather will provide your HTTP API Token (e.g. 7123456789:AAFn73hK...). Copy this token.
1. In Telegram, create a new Channel (e.g. My Cloud Archive) and set it to Private.
2. Open Channel Info ➔ Administrators ➔ Add Administrator.
3. Search for your bot username and select it.
4. Ensure the permission "Post Messages" is enabled so the bot can upload media. Click Done.
Telegram channel IDs are negative numbers prefixed with -100 (e.g. -1001234567890). To easily find yours:
1. Post any sample message (e.g. "test") in your newly created channel.
2. Forward that message to @JsonDumpBot or @userinfobot.
3. The helper bot will return the raw Telegram update JSON. Locate the forward_from_chat section:
"forward_from_chat": {
"id": -1001234567890,
"title": "My Cloud Archive",
"type": "channel"
}
4. Copy the entire id number, including the -100 prefix: -1001234567890.
1. Open the FetchStream extension and click Settings (⚙️).
2. Under Telegram Bot Settings, paste your Bot Token and Chat ID.
3. Click outside to save. Whenever you upload to Telegram, your bot will post the files directly into your private channel.
Telegram Bot API limits and upload methods depend on Telegram's current rules and the configured backend. Server Upload can pass a job to a runner that implements additional Telegram upload methods.
Some runner deployments may include a Telegram client that supports methods beyond the Bot API. Refer to that runner's documentation for supported credentials, limits, and transfer methods.
If running the official Telegram Bot API server locally on port 8081, FetchStream auto-detects http://127.0.0.1:8081 and utilizes Telegram's local filesystem upload method (bypassing HTTP payload limits).
FetchStream is an open-source, client-side utility and offloading bridge. Please review the following terms regarding third-party cloud hosting providers:
FetchStream is developed strictly as a developer utility, media stream analyzer, and personal archival tool. Please review the following principles: