Deeve Technologies
Client workWeb Application

Deeve YT Downloader

A simple YouTube downloader supporting MP3 and MP4 output, quality selection and batch processing.

ClientDeeve Technologies
RoleFull-stack developer
Year2026
TypeWeb Application
Updated23 Sep 2026
Portfolio yt downloader 2
Overview

Deeve YT Downloader is a self-hosted media conversion tool. Paste a URL, pick MP3 or MP4 and a quality, and get the file.

It handles whole playlists, runs downloads through a queue with live progress, and carries no advertising because it runs on my own server rather than someone else's ad network.

Built with
PythonFlaskyt-dlpGunicornDocker
The problem

What was in the way

Search for a YouTube downloader and every result is the same page: a text box surrounded by advertising, three fake download buttons, a redirect to a survey, and a file that may or may not be what you asked for. The tool works, technically, and the experience is hostile by design because the advertising is the product.

The actual job is small. Resolve a URL, pick a format, convert, serve the file, clean up afterwards. Everything else on those sites exists to monetise the visit.

What I built

Five parts, each with a reason

One box, two choices

A URL field, MP3 or MP4, and a quality selector. That is the whole interface. No account, no upsell, no interstitial.

It cleans up after itself

Completed tasks are capped, and older entries are evicted as new ones arrive. Files are served through a token per task rather than by path, and are removed on a schedule. A downloader that never deletes anything becomes a disk space problem within a week, and a downloader that serves files by guessable path becomes everyone else's file server.

Playlists handled properly

Pasting a link to a video that happens to sit inside a playlist is ambiguous, and most tools guess wrong. The URL parser detects when a link carries both a video id and a list id, and resolves to the playlist so the whole thing can be extracted rather than silently grabbing one track. A playlist is expanded to its items first, and the items are then queued individually.

A real queue with live progress

Downloads run on background threads behind a queue rather than blocking the request. Each task gets an id, and the browser polls for progress, so a long playlist reports where it actually is instead of showing a spinner. Tasks can be cancelled mid-download, and a cancelled task stops the worker rather than just hiding the row.

Conversion through ffmpeg

Audio extraction and format conversion run through ffmpeg, with a fallback check at startup so the app knows whether ffmpeg is present before it accepts a job rather than failing at the end of one.

How it was built

The engineering underneath

FlaskPython served by Gunicorn and containerised with Docker, with yt-dlp extracting and ffmpeg converting
In memoryBounded task dictionaries rather than a database, because nothing here needs to survive a restart
Granular routesSeparate endpoints for extraction, start, progress, cancel, file info, retrieval and clearing

A single Flask application with a clear split: routing and JSON endpoints at the front, a queue and worker threads behind, and yt-dlp doing the actual extraction. State lives in memory with bounded task dictionaries rather than in a database, because nothing here needs to survive a restart. A download that was interrupted should be re-requested, not resumed from a persisted half-state.

The endpoints are deliberately granular: separate routes for playlist extraction, starting a download, polling progress, cancelling, fetching file information, retrieving the finished file, and clearing a task. That makes the front end straightforward and the whole thing scriptable, which matters more for a utility than a polished single page application would.

It ships as a container. The Dockerfile and a Gunicorn entry point mean deployment is the same operation on any host, and the tkinter import is wrapped in a try so the same file runs on a desktop for local use and on a Linux server with no display.

Python with Flask, served by Gunicorn, containerised with Docker. yt-dlp handles extraction, ffmpeg handles conversion. Threading for the worker pool, plain templates for the interface.

This is the only project here that is not PHP, and that is the point of including it. yt-dlp is the tool for this job and it is a Python library, so the application is Python. Choosing a stack because it is the one you already know, when a better fit exists and the project is small enough to learn on, is how you end up maintaining the wrong thing for years.

It is a personal tool rather than client work, and it is listed because the decisions in it are the ones I would defend in a code review: pick the right library, keep the state bounded, clean up your own disk, and do not serve files by path.

PythonFlaskyt-dlpGunicornDocker
More work

Projects like this

All projects
Why it matters for your project

I build software, and I measure whether it works.

The same questions I research are the ones I ask on client builds: is it reliable, is it fast, is it easy to use, and is it secure. Those four drove satisfaction in my ICT portal study, and they shape how I scope and test every project.